From barton at grass.itc.it Sun Jul 1 00:43:06 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Jul 1 00:43:08 2007 Subject: [grass-addons] r889 - trunk/grassaddons/gui Message-ID: <200706302243.l5UMh6ts025784@grass.itc.it> Author: barton Date: 2007-07-01 00:42:56 +0200 (Sun, 01 Jul 2007) New Revision: 889 Modified: trunk/grassaddons/gui/location_wizard.py Log: Further improvements to summary page. Create variables to use in PROJ.4 string for g.proj Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-06-30 16:24:40 UTC (rev 888) +++ trunk/grassaddons/gui/location_wizard.py 2007-06-30 22:42:56 UTC (rev 889) @@ -18,7 +18,6 @@ global georeffile global datum global transform -global projection global north global south global east @@ -30,7 +29,6 @@ georeffile = '' datum = '' transform = '' -projection = '' north = '' south = '' east = '' @@ -54,7 +52,7 @@ self.SetSizer(tmpsizer) self.SetAutoLayout(True) - def MakeLabel(self, text=""): + def MakeRLabel(self, text=""): try: if text[-1] != " ": text += " " @@ -62,6 +60,14 @@ pass return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT) + def MakeLLabel(self, text=""): + try: + if text[-1] != " ": + text += " " + except: + pass + return wx.StaticText(self, -1, text, style=wx.ALIGN_LEFT) + def MakeTextCtrl(self,text='', size=(100,-1)): return wx.TextCtrl(self,-1, text, size=size) @@ -76,6 +82,14 @@ TitledPage.__init__(self, wizard, "Specify geodetic datum") self.parent = parent + self.datum = '' + self.datumname = '' + self.ellipsoid = '' + self.datumparams = '' + self.transform = '' + self.transcountry = '' + self.transdesc = '' + self.transparams = '' # text input self.tdatum = self.MakeTextCtrl("", size=(200,-1)) @@ -89,15 +103,11 @@ self.bupdate = self.MakeButton("Update trans. parms.", size=(-1,-1)) - # table - self.tablewidth=675 - # create list control for datum/elipsoid list self.datumlist = wx.ListCtrl(self, id=wx.ID_ANY, - size=(675,150), - style=wx.LC_REPORT | - wx.LC_VRULES | - wx.LC_HRULES | + size=(650,150), + style=wx.LC_REPORT| + wx.LC_HRULES| wx.EXPAND) self.datumlist.InsertColumn(0, 'Short Name') self.datumlist.InsertColumn(1, 'Full EPSG-style name') @@ -110,9 +120,8 @@ # create list control for datum transformation parameters list self.transformlist = wx.ListCtrl(self, id=wx.ID_ANY, - size=(675,125), + size=(650,125), style=wx.LC_REPORT | - wx.LC_VRULES | wx.LC_HRULES | wx.EXPAND) self.transformlist.InsertColumn(0, 'ID') @@ -125,7 +134,7 @@ self.transformlist.SetColumnWidth(3, 250) # layout - self.sizer.Add(self.MakeLabel("Geodetic datum:"), 0, + self.sizer.Add(self.MakeRLabel("Geodetic datum:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, col=1, row=1) @@ -137,7 +146,7 @@ wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=1, col=3) - self.sizer.Add(self.MakeLabel("Search in description:"), 0, + self.sizer.Add(self.MakeRLabel("Search in description:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, col=1, row=2) @@ -149,9 +158,9 @@ self.sizer.Add(self.datumlist, 0 , wx.EXPAND | wx.ALIGN_LEFT | - wx.ALL, 5, row=3, col=1, colspan=5) + wx.ALL, 5, row=3, col=1, colspan=4) - self.sizer.Add(self.MakeLabel("Transformation parameters:"), 0, + self.sizer.Add(self.MakeRLabel("Transformation parameters:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, col=1, row=5) @@ -163,12 +172,10 @@ self.sizer.Add(self.transformlist, 0 , wx.EXPAND | wx.ALIGN_LEFT | - wx.ALL, 5, row=6, col=1, colspan=5) + wx.ALL, 5, row=6, col=1, colspan=4) # events - #wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) - #wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.datumlist) + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnDatumSelected, self.datumlist) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams) @@ -176,17 +183,19 @@ self.tdatum.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) self._onBrowseDatums(None,None) + self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) self.datumlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + self.transformlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + def onPageChange(self,event): self.GetNext().SetPrev(self) - global datum - datum = self.tdatum.GetValue() - global transform - transform = self.ttrans.GetValue() def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -202,18 +211,33 @@ self._onBrowseDatums(None,str) def OnTransformSelected(self,event): + index = event.m_itemIndex item = event.GetItem() - self.ttrans.SetValue(str(item.GetText())) - def OnItemSelected(self,event): + self.transform = item.GetText() + self.transcountry = self.transformlist.GetItem(index, 1).GetText() + self.transdesc = self.transformlist.GetItem(index, 2).GetText() + self.transparams = self.transformlist.GetItem(index, 3).GetText() + + self.ttrans.SetValue(str(self.transform)) + + + def OnDatumSelected(self,event): + index = event.m_itemIndex item = event.GetItem() - self.tdatum.SetValue(str(item.GetText())) + + self.datum = item.GetText() + self.datumname = self.datumlist.GetItem(index, 1).GetText() + self.ellipsoid = self.datumlist.GetItem(index, 2).GetText() + self.datumparams = self.datumlist.GetItem(index, 3).GetText() + + self.tdatum.SetValue(self.datum) self._onBrowseParams() def _onBrowseParams(self, event=None): params = [["","Use whole region",""]] file = os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table") - search = self.tdatum.GetValue() + search = self.datum try: f = open(file,"r") @@ -301,44 +325,44 @@ self.parent = parent - self.sizer.Add(self.MakeLabel("GRASS database:"), 1, flag=wx.ALIGN_RIGHT, row=1, col=0) - self.sizer.Add(self.MakeLabel("Location name:"), 1, flag=wx.ALIGN_RIGHT, row=2, col=0) + self.sizer.Add(self.MakeRLabel("GRASS database:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=1, col=0) + self.sizer.Add(self.MakeRLabel("Location name:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=2, col=0) self.sizer.Add(wx.StaticLine(self, -1), 0, wx.ALIGN_RIGHT|wx.EXPAND|wx.ALL, 0, row=3, col=0, colspan=2) - self.sizer.Add((10,10), 1, flag=wx.ALIGN_CENTER_HORIZONTAL, row=4, col=0) - self.sizer.Add(self.MakeLabel("Projection:"), 1, flag=wx.ALIGN_RIGHT, row=5, col=0) - self.sizer.Add(self.MakeLabel("North:"), 1, flag=wx.ALIGN_RIGHT, row=6, col=0) - self.sizer.Add(self.MakeLabel("South:"), 1, flag=wx.ALIGN_RIGHT, row=7, col=0) - self.sizer.Add(self.MakeLabel("East:"), 1, flag=wx.ALIGN_RIGHT, row=8, col=0) - self.sizer.Add(self.MakeLabel("West:"), 1, flag=wx.ALIGN_RIGHT, row=9, col=0) - self.sizer.Add(self.MakeLabel("Resolution:"), 1, flag=wx.ALIGN_RIGHT, row=10, col=0) - self.sizer.Add(self.MakeLabel("Rows:"), 1, flag=wx.ALIGN_RIGHT, row=12, col=0) - self.sizer.Add(self.MakeLabel("Columns:"), 1, flag=wx.ALIGN_RIGHT, row=13, col=0) - self.sizer.Add(self.MakeLabel("Cells:"), 1, flag=wx.ALIGN_RIGHT, row=14, col=0) + self.sizer.Add((10,10), 1, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, border=5, row=4, col=0) + self.sizer.Add(self.MakeRLabel("Projection:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=5, col=0) + self.sizer.Add(self.MakeRLabel("North:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=6, col=0) + self.sizer.Add(self.MakeRLabel("South:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=7, col=0) + self.sizer.Add(self.MakeRLabel("East:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=8, col=0) + self.sizer.Add(self.MakeRLabel("West:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=9, col=0) + self.sizer.Add(self.MakeRLabel("Resolution:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=10, col=0) + self.sizer.Add(self.MakeRLabel("Rows:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=12, col=0) + self.sizer.Add(self.MakeRLabel("Columns:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=13, col=0) + self.sizer.Add(self.MakeRLabel("Cells:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=14, col=0) # labels - self.ldatabase = self.MakeLabel("") - self.llocation = self.MakeLabel("") - self.lprojection = self.MakeLabel("") - self.lnorth = self.MakeLabel("") - self.lsouth = self.MakeLabel("") - self.least = self.MakeLabel("") - self.lwest = self.MakeLabel("") - self.lres = self.MakeLabel("") - self.lrows = self.MakeLabel("") - self.lcols = self.MakeLabel("") - self.lcells = self.MakeLabel("") + self.ldatabase = self.MakeLLabel("") + self.llocation = self.MakeLLabel("") + self.lprojection = self.MakeLLabel("") + self.lnorth = self.MakeLLabel("") + self.lsouth = self.MakeLLabel("") + self.least = self.MakeLLabel("") + self.lwest = self.MakeLLabel("") + self.lres = self.MakeLLabel("") + self.lrows = self.MakeLLabel("") + self.lcols = self.MakeLLabel("") + self.lcells = self.MakeLLabel("") - self.sizer.Add(self.ldatabase, 1, flag=wx.ALIGN_LEFT, row=1, col=1) - self.sizer.Add(self.llocation, 1, flag=wx.ALIGN_LEFT, row=2, col=1) - self.sizer.Add(self.lprojection, 1, flag=wx.ALIGN_LEFT, row=5, col=1) - self.sizer.Add(self.lnorth, 1, flag=wx.ALIGN_LEFT, row=6, col=1) - self.sizer.Add(self.lsouth, 1, flag=wx.ALIGN_LEFT, row=7, col=1) - self.sizer.Add(self.least, 1, flag=wx.ALIGN_LEFT, row=8, col=1) - self.sizer.Add(self.lwest, 1, flag=wx.ALIGN_LEFT, row=9, col=1) - self.sizer.Add(self.lres, 1, flag=wx.ALIGN_LEFT, row=10, col=1) - self.sizer.Add(self.lrows, 1, flag=wx.ALIGN_LEFT, row=12, col=1) - self.sizer.Add(self.lcols, 1, flag=wx.ALIGN_LEFT, row=13, col=1) - self.sizer.Add(self.lcells, 1, flag=wx.ALIGN_LEFT, row=14, col=1) + self.sizer.Add(self.ldatabase, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=1, col=1) + self.sizer.Add(self.llocation, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=2, col=1) + self.sizer.Add(self.lprojection, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=5, col=1) + self.sizer.Add(self.lnorth, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=6, col=1) + self.sizer.Add(self.lsouth, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=7, col=1) + self.sizer.Add(self.least, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=8, col=1) + self.sizer.Add(self.lwest, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=9, col=1) + self.sizer.Add(self.lres, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=10, col=1) + self.sizer.Add(self.lrows, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=12, col=1) + self.sizer.Add(self.lcols, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=13, col=1) + self.sizer.Add(self.lcells, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=14, col=1) def FillVars(self,event=None): database = self.parent.startpage.grassdatabase @@ -363,22 +387,47 @@ if not resolution: resolution = 1 - #if projection != "latlong": rows = int(round((float(north)-float(south))/float(resolution))) cols = int(round((float(east)-float(west))/float(resolution))) cells = int(rows*cols) + projection = self.parent.projpage.projname + projdesc = self.parent.projpage.projdesc + utmzone = self.parent.utmpage.utmzone + utmhemisphere = self.parent.utmpage.utmhemisphere + datum = self.parent.datumpage.datum + datumname = self.parent.datumpage.datumname + ellipsoid = self.parent.datumpage.ellipsoid + datumparams = self.parent.datumpage.datumparams + transform = self.parent.datumpage.transform + transcountry = self.parent.datumpage.transcountry + transdesc = self.parent.datumpage.transdesc + transparams = self.parent.datumpage.transparams + self.ldatabase.SetLabel(str(database)) self.llocation.SetLabel(str(location)) + if coordsys == 'epsg': label = 'EPSG code %s: %s' % (self.parent.epsgpage.epsgcode,self.parent.epsgpage.epsgdesc) self.lprojection.SetLabel(label) elif coordsys == 'file': label = 'Matches file: %s' % self.parent.filepage.georeffile self.lprojection.SetLabel(label) - else: - self.lprojection.SetLabel(str(coordsys)) + elif coordsys == 'utm': + label = ('UTM zone: %s%s, datum: %s %s' % (utmzone,utmhemisphere, datumname, ellipsoid)) + self.lprojection.SetLabel(label) + elif coordsys == 'latlon': + label = ('Geographic (latlon), datum: %s %s' % (datumname, ellipsoid)) + self.lprojection.SetLabel(label) + elif coordsys == 'custom': + label = ('%s %s, datum: %s %s' % (projection, projdesc, datumname, ellipsoid)) + self.lprojection.SetLabel(label) + elif coordsys == 'xy': + label = ('XY coordinate system. Not projected') + self.lprojection.SetLabel(label) + self.lprojection.Wrap(500) + self.lnorth.SetLabel(str(north)) self.lsouth.SetLabel(str(south)) self.least.SetLabel(str(east)) @@ -447,7 +496,7 @@ style=wx.CB_DROPDOWN) # layout - self.sizer.Add(self.MakeLabel("North"), 0, + self.sizer.Add(self.MakeRLabel("North"), 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 0, row=1,col=2) @@ -456,7 +505,7 @@ wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=2,col=2) - self.sizer.Add(self.MakeLabel("West"), 0, + self.sizer.Add(self.MakeRLabel("West"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 0, row=3,col=0) @@ -469,7 +518,7 @@ wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=3,col=3) - self.sizer.Add(self.MakeLabel("East"), 0, + self.sizer.Add(self.MakeRLabel("East"), 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 0, row=3,col=4) @@ -478,12 +527,12 @@ wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=4,col=2) - self.sizer.Add(self.MakeLabel("South"), 0, + self.sizer.Add(self.MakeRLabel("South"), 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 0, row=5,col=2) - self.sizer.Add(self.MakeLabel("Initial resolution"), 0, + self.sizer.Add(self.MakeRLabel("Initial resolution"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=6,col=1) @@ -498,12 +547,12 @@ self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, row=7, col=0, colspan=6) - self.sizer.Add(self.MakeLabel("Match extents of georeferenced raster map or image"), 3, + self.sizer.Add(self.MakeRLabel("Match extents of georeferenced raster map or image"), 3, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=8,col=0, colspan=3) - self.sizer.Add(self.MakeLabel("File:"), 0, + self.sizer.Add(self.MakeRLabel("File:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=9,col=0, colspan=1) @@ -520,12 +569,12 @@ wx.EXPAND|wx.ALL, 0, row=10, col=0, colspan=6) - self.sizer.Add(self.MakeLabel("Match extents of georeferenced vector map"), 0, + self.sizer.Add(self.MakeRLabel("Match extents of georeferenced vector map"), 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=11,col=0, colspan=3 ) - self.sizer.Add(self.MakeLabel("Data source/directory:"), 0, + self.sizer.Add(self.MakeRLabel("Data source/directory:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=12,col=0, colspan=1) @@ -538,7 +587,7 @@ wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=12, col=3) - self.sizer.Add(self.MakeLabel("Layer/file:"), 0, + self.sizer.Add(self.MakeRLabel("Layer/file:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=13,col=0, colspan=1) @@ -556,7 +605,7 @@ wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=14, col=0, colspan=6) - self.sizer.Add(self.MakeLabel("Match extents of selected country"), 0, + self.sizer.Add(self.MakeRLabel("Match extents of selected country"), 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=15,col=0, colspan=3) @@ -775,20 +824,19 @@ style=wx.TE_PROCESS_ENTER) # table - self.tablewidth=675 +# self.tablewidth=675 self.list = wx.ListCtrl(self, id=wx.ID_ANY, - size=(675,275), + size=(650,275), style=wx.LC_REPORT | - wx.LC_VRULES | wx.LC_HRULES | wx.EXPAND) self.list.InsertColumn(0, 'Name') self.list.InsertColumn(1, 'Description') self.list.SetColumnWidth(0, 100) - self.list.SetColumnWidth(1, 575) + self.list.SetColumnWidth(1, 500) # layout - self.sizer.Add(self.MakeLabel("Projection name:"), 0, + self.sizer.Add(self.MakeRLabel("Projection name:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=1, col=2) @@ -797,7 +845,7 @@ wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=1, col=3) - self.sizer.Add(self.MakeLabel("Search in projection description"), 0, + self.sizer.Add(self.MakeRLabel("Search in projection description"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=2, col=2) @@ -836,9 +884,12 @@ def OnItemSelected(self,event): + index = event.m_itemIndex item = event.GetItem() - self.tproj.SetValue(str(item.GetText())) + self.projname = item.GetText() + self.projdesc = self.list.GetItem(index, 1).GetText() + self.tproj.SetValue(str(self.projname)) def _onBrowseDatums(self,event,search=None): try: @@ -872,8 +923,9 @@ dlg.Destroy() def onPageChange(self,event): - global projection - projection = self.tproj.GetValue() + pass +# global projection +# projection = self.tproj.GetValue() class GeoreferencedFilePage(TitledPage): def __init__(self, wizard, parent): @@ -931,6 +983,7 @@ epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg') self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1)) self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1)) + self.epsgdesc = '' self.epsgcode = '' @@ -942,7 +995,7 @@ self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) # table - self.tablewidth=675 +# self.tablewidth=675 self.epsgs = wx.ListCtrl(self, id=wx.ID_ANY, size=(650,275), style=wx.LC_REPORT| @@ -1142,19 +1195,30 @@ def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose zone for UTM coordinate system") + self.utmzone = '' + self.utmhemisphere = '' + self.parent = parent - self.text_utm = self.MakeTextCtrl(size=(300,-1)) - self.label_utm = self.MakeLabel("Set UTM zone: ") + self.text_utm = self.MakeTextCtrl(size=(100,-1)) + self.label_utm = self.MakeRLabel("Set UTM zone: ") + hemischoices = ["north","south"] + self.hemisphere = wx.Choice(self, -1, (100, 50), choices = hemischoices) + self.label_hemisphere = self.MakeRLabel("Set hemisphere: ") - self.sizer.Add(self.label_utm, 0, wx.ALIGN_LEFT, 5, row=1,col=1) - self.sizer.Add(self.text_utm, 0, wx.ALIGN_LEFT, 5, row=1,col=2) + self.sizer.Add(self.label_utm, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=1,col=1) + self.sizer.Add(self.text_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=1,col=2) + self.sizer.Add(self.label_hemisphere, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=2,col=1) + self.sizer.Add(self.hemisphere, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=2,col=2) + self.Bind(wx.EVT_CHOICE, self.OnHemisphere, self.hemisphere) + self.Bind(wx.EVT_TEXT, self.GetUTM, self.text_utm) - def GetUtm(self): - return int(self.text_utm.GetValue()) + def GetUTM(self, event): + self.utmzone = int(event.GetString()) + def OnHemisphere(self, event): + self.utmhemisphere = event.GetString() - class DatabasePage(TitledPage): def __init__(self, wizard, parent, grassdatabase): TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") @@ -1170,7 +1234,7 @@ self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1)) # layout - self.sizer.Add(self.MakeLabel("GIS Data Directory:"), 0, + self.sizer.Add(self.MakeRLabel("GIS Data Directory:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, @@ -1186,7 +1250,7 @@ wx.ALL, 5, row=1, col=4) # - self.sizer.Add(self.MakeLabel("Project Location"), 0, + self.sizer.Add(self.MakeRLabel("Project Location"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, @@ -1196,7 +1260,7 @@ wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=2, col=3) - self.sizer.Add(self.MakeLabel("(projection/coordinate system)"), 0, + self.sizer.Add(self.MakeRLabel("(projection/coordinate system)"), 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, @@ -1343,35 +1407,54 @@ """ Create a new Lat/Long location """ - projection = self.projpage.tproj.GetValue() - datum = self.datumpage.tdatum.GetValue() - transform = self.datumpage.ttrans.GetValue() + datum = self.datumpage.datum + datumname = self.datumpage.datumname + ellipsoid = self.datumpage.ellipsoid + datumparams = self.datumpage.datumparams + transform = self.datumpage.transform + transcountry = self.datumpage.transcountry + transdesc = self.datumpage.transdesc + transparams = self.datumpage.transparams - wx.MessageBox('Not implemented: Create input for g.proj from \n%s \n%s \n%s' % - (projection, datum, transform)) + wx.MessageBox('Not implemented: Create input for g.proj from \nlatitude/longitude \n%s: %s %s \n%s: %s' % + (datum, datumname, ellipsoid, transform, transdesc)) def UTMCreate(self): """ Create a new UTM location """ - projection = self.projpage.tproj.GetValue() - datum = self.datumpage.tdatum.GetValue() - transform = self.datumpage.ttrans.GetValue() + utm = self.utmpage.utm + zone = self.utmpage.zone + utmhemisphere = self.utmpage.utmhemisphere + datum = self.datumpage.datum + datumname = self.datumpage.datumname + ellipsoid = self.datumpage.ellipsoid + datumparams = self.datumpage.datumparams + transform = self.datumpage.transform + transcountry = self.datumpage.transcountry + transdesc = self.datumpage.transdesc + transparams = self.datumpage.transparams + wx.MessageBox('Not implemented: Create input for g.proj from \n%s: %s%s \n%s: %s %s \n%s: %s' % + (utm, zone, utmhemisphere, datum, datumname, ellipsoid, transform, transdesc)) - wx.MessageBox('Not implemented: Create input for g.proj from \n%s \n%s \n%s' % - (projection, datum, transform)) - def CustomCreate(self): """ Create a new custom-defined location """ - projection = self.projpage.tproj.GetValue() - datum = self.datumpage.tdatum.GetValue() - transform = self.datumpage.ttrans.GetValue() + projection = self.projpage.projname + projdesc = self.projpage.projdesc + datum = self.datumpage.datum + datumname = self.datumpage.datumname + ellipsoid = self.datumpage.ellipsoid + datumparams = self.datumpage.datumparams + transform = self.datumpage.transform + transcountry = self.datumpage.transcountry + transdesc = self.datumpage.transdesc + transparams = self.datumpage.transparams - wx.MessageBox('Not implemented: Create input for g.proj from \n%s \n%s \n%s' % - (projection, datum, transform)) + wx.MessageBox('Not implemented: Create input for g.proj from \n%s: %s \n%s: %s %s \n%s: %s' % + (projection, projdesc, datum, datumname, ellipsoid, transform, transdesc)) def EPSGCreate(self): """ From chemin at grass.itc.it Sun Jul 1 12:06:40 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 12:06:41 2007 Subject: [grass-addons] r890 - in trunk/grassaddons/gipe: . script_generator Message-ID: <200707011006.l61A6eI6017083@grass.itc.it> Author: chemin Date: 2007-07-01 12:06:26 +0200 (Sun, 01 Jul 2007) New Revision: 890 Modified: trunk/grassaddons/gipe/gmmenu.tcl trunk/grassaddons/gipe/imagery_Makefile trunk/grassaddons/gipe/menudata.py trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: New module for Atmospheric Air Density calculations (input to sensible heat flux) Modified: trunk/grassaddons/gipe/gmmenu.tcl =================================================================== --- trunk/grassaddons/gipe/gmmenu.tcl 2007-06-30 22:42:56 UTC (rev 889) +++ trunk/grassaddons/gipe/gmmenu.tcl 2007-07-01 10:06:26 UTC (rev 890) @@ -575,6 +575,7 @@ {command {[G_msg "Net radiation"]} {} "i.eb.netrad" {} -command {execute i.eb.netrad }} {separator} {command {[G_msg "Displacement height"]} {} "i.eb.disp" {} -command {execute i.eb.disp }} + {separator} {command {[G_msg "Monin-Obukov Length"]} {} "i.eb.molength" {} -command {execute i.eb.molength }} {command {[G_msg "Psichrometric param. for heat"]} {} "i.eb.psi" {} -command {execute i.eb.psi }} {command {[G_msg "Blending height wind speed"]} {} "i.eb.ublend" {} -command {execute i.eb.ublend }} Modified: trunk/grassaddons/gipe/imagery_Makefile =================================================================== --- trunk/grassaddons/gipe/imagery_Makefile 2007-06-30 22:42:56 UTC (rev 889) +++ trunk/grassaddons/gipe/imagery_Makefile 2007-07-01 10:06:26 UTC (rev 890) @@ -23,6 +23,7 @@ i.eb.netrad \ i.eb.psi \ i.eb.rah \ + i.eb.rohair \ i.eb.ublend \ i.eb.ustar \ i.eb.z0m \ Modified: trunk/grassaddons/gipe/menudata.py =================================================================== --- trunk/grassaddons/gipe/menudata.py 2007-06-30 22:42:56 UTC (rev 889) +++ trunk/grassaddons/gipe/menudata.py 2007-07-01 10:06:26 UTC (rev 890) @@ -343,6 +343,7 @@ ("Net radiation", "net radiation", "self.RunMenuCmd", "i.eb.netrad"), ("","","", ""), ("Displacement height", "Displacement height", "self.RunMenuCmd", "i.eb.disp"), + ("","","", ""), ("Monin-Obukov Length", "Monin-Obukov Length", "self.RunMenuCmd", "i.eb.molength"), ("Psichrometric param. for heat", "psichrometric param. for heat", "self.RunMenuCmd", "i.eb.psi"), ("Blending height wind speed", "blending height wind speed", "self.RunMenuCmd", "i.eb.ublend"), Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-06-30 22:42:56 UTC (rev 889) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 10:06:26 UTC (rev 890) @@ -19,15 +19,16 @@ Thanks to Brad Douglas to fix the .tif filename issue */ -//This is auto-generating an image processing script for GRASS GIS. -//It is created by extracting useful information from the .met metadata -//file of Landsat 7 -//It runs several GRASS GIS modules to calculate (hopefully) -//automagically ET Potential -//It assumes you just downloaded *.gz Landsat images from public -//repositories such as www.landsat.org or other and run this code -//in that directory from the GRASS GIS shell - +/* This is auto-generating an image processing script for GRASS GIS. + * It is created by extracting useful information from the .met metadata + * file of Landsat 7 + * It runs several GRASS GIS modules to calculate (hopefully) + * automagically ET Potential and more ET types... + * It assumes you just downloaded *.gz Landsat images from public + * repositories such as www.landsat.org or other and run this code + * in that directory from the GRASS GIS shell + */ + #include #include #include @@ -53,9 +54,9 @@ char b1[80],b2[80],b3[80]; char b4[80],b5[80],b61[80]; - char b62[80],b7[80],b8[80]; //Load .tif file names - char path[80],row[80]; //load path and row of L7 - char basedate[80];//p127r05020001104 + char b62[80],b7[80],b8[80]; /*Load .tif file names*/ + char path[80],row[80]; /*load path and row of L7*/ + char basedate[80];/*p127r05020001104*/ double lmin[MAXFILES]={0.0}; double lmax[MAXFILES]={0.0}; @@ -73,11 +74,11 @@ char sys_lmax[80]; char sys_qcalmin[80]; char sys_qcalmax[80]; - char sys_basedate[80];//catenate of path and row (i.e.p127r050) + char sys_basedate[80];/*catenate of path and row (i.e.p127r050)*/ char sys_b1[80],sys_b2[80],sys_b3[80]; char sys_0[100],sys_00[100]; char sys_b4[80],sys_b5[80],sys_b61[80]; - char sys_b62[80],sys_b7[80],sys_b8[80]; //Load .tif file names + char sys_b62[80],sys_b7[80],sys_b8[80]; /*Load .tif file names*/ char sys_1[1000],sys_2[1000],sys_3[1000],sys_4[1000]; char sys_5[1000],sys_6[1000],sys_7[1000],sys_8[1000]; char sys_9[1000],sys_10[1000],sys_100[1000]; @@ -97,60 +98,54 @@ if (!f) return 1; -// printf("1\n"); while (fgets(s,1000,f)!=NULL) { - // printf("2%s\n",s); ptr = strstr(s, "ACQUISITION_DATE"); if (ptr != NULL) { - // printf("3\t"); p = strtok(ptr, " ="); p = strtok(NULL, " =-"); year = atoi(p); - // printf("4\t"); p = strtok(NULL, "-"); month = atoi(p); - // printf("5\t"); p = strtok(NULL, "-"); day = atoi(p); - // printf("6\n"); } ptr = strstr(s, "WRS_PATH"); if (ptr != NULL) { p = strtok(ptr, " ="); p = strtok(NULL, " =\n"); -// printf("path=%s\n",p); +/* printf("path=%s\n",p);*/ snprintf(path, 80, "%s", p); -// printf("path=%s\n",path); +/* printf("path=%s\n",path);*/ } ptr = strstr(s, "WRS_ROW"); if (ptr != NULL) { p = strtok(ptr, " ="); p = strtok(NULL, " =\n"); -// printf("row=%s\n",p); +/* printf("row=%s\n",p);*/ snprintf(row, 80, "%s", p); -// printf("row=%s\n",row); +/* printf("row=%s\n",row);*/ } ptr = strstr(s, "BAND1_FILE_NAME"); if (ptr != NULL) { p = strtok(ptr, " ="); p = strtok(NULL, " =\""); - // printf("b1=%s\n",p); + /* printf("b1=%s\n",p);*/ snprintf(b1, 80, "%s", p); - // printf("b1=%s\n",band1); + /* printf("b1=%s\n",band1);*/ } ptr = strstr(s, "BAND2_FILE_NAME"); if (ptr != NULL) { p = strtok(ptr, " ="); p = strtok(NULL, " =\""); - // printf("b2=%s\n",p); + /* printf("b2=%s\n",p);*/ snprintf(b2, 80, "%s", p); - // printf("b2=%s\n",band2); + /* printf("b2=%s\n",band2);*/ } ptr = strstr(s, "BAND3_FILE_NAME"); if (ptr != NULL) @@ -514,16 +509,16 @@ snprintf(sys_sun_elevation,80,"sun_elevation=%f",sun_elevation); system(sys_sun_elevation); -// for (i=0;i temp.txt"); system("echo \"\" >> temp.txt"); system("echo \"#This is an auto-generated script by l7inread_ingrass().\n#It is created by a C code that extract useful information from the .met metadata file of Landsat 7\n#It runs several GRASS GIS modules to calculate (hopefully) automagically ET Potential\n\n#Q: I am bonehead, my script does not run because i am not running it from inside GRASS GIS\n#A: How many times we have to tell you that it will NOT work from outside GRASS GIS! (Actually, there might be a way :P, have to ask the dev-ML...) \" >> temp.txt"); - //ungzip the L7 files + /*ungzip the L7 files*/ system("echo \"\" >> temp.txt"); system("echo \"#UNGZIP ALL LANDSAT BANDS\" >> temp.txt"); system("echo \"for file in *.gz; do gzip -d \\$file ; done\" >> temp.txt"); - //import the Landsat 7 files + /*import the Landsat 7 files*/ system("echo \"\" >> temp.txt"); system("echo \"#IMPORT IN GRASS GIS\" >> temp.txt"); sprintf(sys_0,"echo \"for file in *10.tif; do r.in.gdal input=\\$file output=\\$file title=Landsat7ETM\\$file location=landsat\\%s ; done\" >> temp.txt",basedate); @@ -554,36 +549,36 @@ sprintf(sys_00,"echo \"g.mapset location=landsat\\%s mapset=PERMANENT\" >> temp.txt", basedate); system(sys_00); system("echo \"for file in *.tif; do r.in.gdal input=\\$file output=\\$file title=Landsat7ETM\\$file ; done\" >> temp.txt"); - //Set region to Temperature map + /*Set region to Temperature map*/ system("echo \"\" >> temp.txt"); system("echo \"#SET REGION TO TEMPERATURE MAP\" >> temp.txt"); snprintf(sys_b61,80,"echo \"g.region rast=%s\" >> temp.txt",b61); system(sys_b61); - //export met file name to envt var -// snprintf(sys_metfName,80,"echo \"inpmetF=%s\" >> temp.txt",metfName); -// system(sys_metfName); - //Create a base variable -// snprintf(sys_basedate,80,"echo \"basedate=%s\" >> temp.txt",basedate); -// system(sys_basedate); - //calibrate DN to TOA Reflectance + /*export met file name to envt var*/ +/* snprintf(sys_metfName,80,"echo \"inpmetF=%s\" >> temp.txt",metfName); + system(sys_metfName);*/ + /*Create a base variable*/ +/* snprintf(sys_basedate,80,"echo \"basedate=%s\" >> temp.txt",basedate); + system(sys_basedate);*/ + /*calibrate DN to TOA Reflectance*/ system("echo \"\" >> temp.txt"); system("echo \"#DN2REF\" >> temp.txt"); snprintf(sys_1,1000,"echo \"i.dn2full.l7 metfile=%s output=%s --overwrite\" >> temp.txt",metfName,basedate); system(sys_1); - //Calculate Albedo + /*Calculate Albedo*/ system("echo \"\" >> temp.txt"); system("echo \"#ALBEDO\" >> temp.txt"); snprintf(sys_2,1000,"echo \"i.albedo -l input=%s.1,%s.2,%s.3,%s.4,%s.5,%s.7 output=%s.albedo --overwrite\" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate); system(sys_2); snprintf(sys_3,1000,"r.null map=%s.albedo setnull=0.0\" >> temp.txt",basedate); system(sys_3); - //Calculate Latitude + /*Calculate Latitude*/ system("echo \"\" >> temp.txt"); system("echo \"#LATITUDE, DOY, TSW\" >> temp.txt"); snprintf(sys_4,1000,"echo \"i.latitude input=%s.albedo latitude=%s.latitude --overwrite ; r.mapcalc %s.doy=%d ; r.mapcalc %s.tsw=0.7\" >> temp.txt", basedate, basedate, basedate, doy, basedate); - //Create a doy layer + /*Create a doy layer*/ system(sys_4); - //Calculate ETPOT (and Rnetd for future ETa calculations) + /*Calculate ETPOT (and Rnetd for future ETa calculations)*/ system("echo \"\" >> temp.txt"); system("echo \"#ETPOT\" >> temp.txt"); snprintf(sys_5,1000,"echo \"i.evapo.potrad -r albedo=%s.albedo tempk=%s.61 lat=%s.latitude doy=%s.doy tsw=%s.tsw etpot=%s.etpot rnetd=%s.rnetd --overwrite\" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate); @@ -592,13 +587,13 @@ system(sys_7); system("echo \"\" >> temp.txt"); system("echo \"#NDVI\" >> temp.txt"); - //Calculate NDVI + /*Calculate NDVI*/ snprintf(sys_8,1000,"echo \"i.vi viname=ndvi red=%s.3 nir=%s.4 vi=%s.ndvi --overwrite ; r.null map=%s.ndvi setnull=-1.0 ; r.colors map=%s.ndvi rules=ndvi\" >> temp.txt",basedate,basedate,basedate,basedate,basedate); system(sys_8); snprintf(sys_16,1000,"echo \"i.vi viname=savi red=%s.3 nir=%s.4 vi=%s.savi --overwrite ; r.null map=%s.savi setnull=-1.0 ; r.colors map=%s.savi rules=ndvi\" >> temp.txt",basedate,basedate,basedate,basedate,basedate); system(sys_16); - //Calculate ETa after Two-Source Algorithm (Chen et al., 2005) + /*Calculate ETa after Two-Source Algorithm (Chen et al., 2005)*/ system("echo \"\" >> temp.txt"); system("echo \"#TWO-SOURCE ALGORITHM\" >> temp.txt"); system("echo \"\" >> temp.txt"); @@ -626,7 +621,7 @@ sprintf(sys_10,"echo \"i.evapo.TSA RNET=%s.rnetd FV=%s.ndvi TEMPK=%s.61 TEMPKA=%s.tempka ALB=%s.albedo NDVI=%s.ndvi UZ=u2 Z=2.0 Z0=%s.z0h Z0S=z0s W=%s.w TIME=%s.sath SUNH=%s.sunh output=%s.ETA_TSA --overwrite\" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate); system(sys_10); system("echo \"\" >> temp.txt"); - //Calculate ET Potential after Prestley and Taylor + /*Calculate ET Potential after Prestley and Taylor*/ system("echo \"#PRESTLEY AND TAYLOR ET POTENTIAL\" >> temp.txt"); system("echo \"\" >> temp.txt"); sprintf(sys_19,"echo \"r.mapcalc %s.patm=1010.0\" >> temp.txt",basedate); @@ -643,13 +638,14 @@ sprintf(sys_23,"echo \"i.evapo.PT -z RNET=%s.rnetd G0=%s.g0 TEMPKA=%s.tempka PATM=%s.patm PT=1.26 output=%s.ETA_PT --overwrite\" >> temp.txt",basedate,basedate,basedate,basedate,basedate); system(sys_23); system("echo \"\" >> temp.txt"); - //Calculate the Actual ET after Pawan (2004) + /*Calculate the Actual ET after Pawan (2004)*/ system("echo \"#ACTUAL ET\" >> temp.txt"); system("echo \"\" >> temp.txt"); - - //clean maps -// system("chmod +x temp.txt; cat temp.txt; echo \"Start GRASS Processing\n\" ; ./temp.txt"); - + sprintf(sys_24,"echo \"i.eb.disp -s lai=%s.savi disp=%s.disp --overwrite\" >> temp.txt",basedate,basedate); + system(sys_24); + /*clean maps + system("chmod +x temp.txt; cat temp.txt; echo \"Start GRASS Processing\n\" ; ./temp.txt"); + */ (void)fclose(f); return; } From chemin at grass.itc.it Sun Jul 1 12:08:08 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 12:08:10 2007 Subject: [grass-addons] r891 - trunk/grassaddons/gipe/i.eb.disp Message-ID: <200707011008.l61A889i017166@grass.itc.it> Author: chemin Date: 2007-07-01 12:07:52 +0200 (Sun, 01 Jul 2007) New Revision: 891 Added: trunk/grassaddons/gipe/i.eb.disp/roh_air.c Modified: trunk/grassaddons/gipe/i.eb.disp/Makefile trunk/grassaddons/gipe/i.eb.disp/description.html trunk/grassaddons/gipe/i.eb.disp/main.c Log: added function Modified: trunk/grassaddons/gipe/i.eb.disp/Makefile =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/Makefile 2007-07-01 10:06:26 UTC (rev 890) +++ trunk/grassaddons/gipe/i.eb.disp/Makefile 2007-07-01 10:07:52 UTC (rev 891) @@ -1,6 +1,6 @@ MODULE_TOPDIR = ../.. -PGM = i.eb.disp +PGM = i.eb.rohair LIBES = $(GISLIB) DEPENDENCIES = $(GISDEP) Modified: trunk/grassaddons/gipe/i.eb.disp/description.html =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/description.html 2007-07-01 10:06:26 UTC (rev 890) +++ trunk/grassaddons/gipe/i.eb.disp/description.html 2007-07-01 10:07:52 UTC (rev 891) @@ -1,23 +1,22 @@

DESCRIPTION

-i.eb.disp calculates the displacement height above the earth skin. +i.eb.rohair calculates the Atmospheric Air Density.

NOTES

-This is found in Pawan (2004). +This is found in Bastiaanssen (1995).

TODO

SEE ALSO

-i.eb.psi
-i.eb.ublend
+i.eb.h_iter

AUTHORS

-Yann Chemin, Asian Institute of Technology, Thailand
+Yann Chemin

-Last changed: $Date: 2006/10/13 22:19:55 $ +Last changed: $Date: 2007/06/30 12:04:02 $ Modified: trunk/grassaddons/gipe/i.eb.disp/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/main.c 2007-07-01 10:06:26 UTC (rev 890) +++ trunk/grassaddons/gipe/i.eb.disp/main.c 2007-07-01 10:07:52 UTC (rev 891) @@ -1,12 +1,10 @@ /**************************************************************************** * - * MODULE: i.eb.disp + * MODULE: i.eb.rohair * AUTHOR(S): Yann Chemin - ychemin@gmail.com - * PURPOSE: Calculates the displacement height above skin surface - * as seen in Pawan (2004), a flag makes savi2lai instead of - * direct LAI input. + * PURPOSE: Calculates the standard air density as seen in Pawan (2004) * - * COPYRIGHT: (C) 2002-2006 by the GRASS Development Team + * COPYRIGHT: (C) 2002-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 @@ -21,8 +19,7 @@ #include -double dis_p(double lai); -double savi_lai(double savi); +double roh_air(double dem); int main(int argc, char *argv[]) { @@ -33,9 +30,9 @@ int verbose=1; struct GModule *module; - struct Option *input1, *output1; + struct Option *input1, *input2, *output1; - struct Flag *flag1, *flag2; + struct Flag *flag1; struct History history; //metadata /************************************/ @@ -43,70 +40,87 @@ char *name; // input raster name char *result1; //output raster name //File Descriptors - int infd_lai; + int infd_dem, infd_tempka; int outfd1; - char *disp; - char *lai; + char *rohair; + char *dem, *tempka; int i=0,j=0; - void *inrast_lai; + void *inrast_dem, *inrast_tempka; unsigned char *outrast1; RASTER_MAP_TYPE data_type_output=DCELL_TYPE; - RASTER_MAP_TYPE data_type_lai; + RASTER_MAP_TYPE data_type_dem; + RASTER_MAP_TYPE data_type_tempka; /************************************/ G_gisinit(argv[0]); module = G_define_module(); - module->keywords = _("disp, energy balance, SEBAL"); - module->description = _("Displacement height above skin surface, as seen in Pawan (2004). A flag (-s) permits direct SAVI input using the equation in the same document, be careful using it."); + module->keywords = _("rohair, energy balance, SEBAL"); + module->description = _("Standard height-based Air Density as seen in Pawan (2004)."); /* Define the different options */ input1 = G_define_option() ; - input1->key = _("lai"); + input1->key = _("dem"); input1->type = TYPE_STRING; input1->required = YES; input1->gisprompt =_("old,cell,raster") ; - input1->description=_("Name of the LAI map [-]"); - input1->answer =_("lai"); + input1->description=_("Name of the DEM map [-]"); + input1->answer =_("dem"); + input2 = G_define_option() ; + input2->key = _("dem"); + input2->type = TYPE_STRING; + input2->required = YES; + input2->gisprompt =_("old,cell,raster") ; + input2->description=_("Name of the Air Temperature map [K]"); + input2->answer =_("tempka"); + output1 = G_define_option() ; - output1->key =_("disp"); + output1->key =_("rohair"); output1->type = TYPE_STRING; output1->required = YES; output1->gisprompt =_("new,dcell,raster"); - output1->description=_("Name of the output disp layer"); - output1->answer =_("disp"); + output1->description=_("Name of the output rohair layer"); + output1->answer =_("rohair"); flag1 = G_define_flag(); flag1->key = 'q'; flag1->description = _("Quiet"); - flag2 = G_define_flag(); - flag2->key = 's'; - flag2->description = _("use savi2lai conversion (Pawan, 2004)"); - /********************/ if (G_parser(argc, argv)) exit (EXIT_FAILURE); - lai = input1->answer; + dem = input1->answer; result1 = output1->answer; verbose = (!flag1->answer); /***************************************************/ - mapset = G_find_cell2(lai, ""); + mapset = G_find_cell2(dem, ""); if (mapset == NULL) { - G_fatal_error(_("cell file [%s] not found"), lai); + G_fatal_error(_("cell file [%s] not found"), dem); } - data_type_lai = G_raster_map_type(lai,mapset); - if ( (infd_lai = G_open_cell_old (lai,mapset)) < 0) - G_fatal_error (_("Cannot open cell file [%s]"), lai); - if (G_get_cellhd (lai, mapset, &cellhd) < 0) - G_fatal_error (_("Cannot read file header of [%s])"), lai); - inrast_lai = G_allocate_raster_buf(data_type_lai); + data_type_dem = G_raster_map_type(dem,mapset); + if ( (infd_dem = G_open_cell_old (dem,mapset)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), dem); + if (G_get_cellhd (dem, mapset, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s])"), dem); + inrast_dem = G_allocate_raster_buf(data_type_dem); /***************************************************/ + /***************************************************/ + mapset = G_find_cell2(tempka, ""); + if (mapset == NULL) { + G_fatal_error(_("cell file [%s] not found"), tempka); + } + data_type_tempka = G_raster_map_type(tempka,mapset); + if ( (infd_tempka = G_open_cell_old (tempka,mapset)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), tempka); + if (G_get_cellhd (tempka, mapset, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s])"), tempka); + inrast_tempka = G_allocate_raster_buf(data_type_tempka); + /***************************************************/ G_debug(3, "number of rows %d",cellhd.rows); nrows = G_window_rows(); ncols = G_window_cols(); @@ -118,42 +132,55 @@ for (row = 0; row < nrows; row++) { DCELL d; - DCELL d_lai; + DCELL d_dem; + DCELL d_tempka; if(verbose) G_percent(row,nrows,2); -// printf("row = %i/%i\n",row,nrows); /* read soil input maps */ - if(G_get_raster_row(infd_lai,inrast_lai,row,data_type_lai)<0) - G_fatal_error(_("Could not read from <%s>"),lai); + if(G_get_raster_row(infd_dem,inrast_dem,row,data_type_dem)<0) + G_fatal_error(_("Could not read from <%s>"),dem); /*process the data */ for (col=0; col < ncols; col++) { - d_lai = ((DCELL *) inrast_lai)[col]; - if(G_is_d_null_value(&d_lai)){ + switch(data_type_dem){ + case CELL_TYPE: + d_dem = (double) ((CELL *) inrast_dem)[col]; + break; + case FCELL_TYPE: + d_dem = (double) ((FCELL *) inrast_dem)[col]; + break; + case DCELL_TYPE: + d_dem = ((DCELL *) inrast_dem)[col]; + break; + } + switch(data_type_tempka){ + case CELL_TYPE: + d_tempka = (double) ((CELL *) inrast_tempka)[col]; + break; + case FCELL_TYPE: + d_tempka = (double) ((FCELL *) inrast_tempka)[col]; + break; + case DCELL_TYPE: + d_tempka = ((DCELL *) inrast_tempka)[col]; + break; + } + if(G_is_d_null_value(&d_dem)||G_is_d_null_value(&d_tempka)){ ((DCELL *) outrast1)[col] = -999.99; } else { - if(flag2->answer){ - /********************/ - /* savi2lai() */ - d = savi_lai(d_lai); - /********************/ - /* calculate disp */ - d = dis_p(d); - ((DCELL *) outrast1)[col] = d; - } else { - /********************/ - /* calculate disp */ - d = dis_p(d_lai); - ((DCELL *) outrast1)[col] = d; - } + /********************/ + /* calculate rohair */ + d = roh_air(d_dem, tempka); + ((DCELL *) outrast1)[col] = d; } } if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) G_fatal_error(_("Cannot write to output raster file")); } - G_free (inrast_lai); - G_close_cell (infd_lai); + G_free (inrast_dem); + G_free (inrast_tempka); + G_close_cell (infd_dem); + G_close_cell (infd_tempka); G_free (outrast1); G_close_cell (outfd1); Added: trunk/grassaddons/gipe/i.eb.disp/roh_air.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/roh_air.c (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/roh_air.c 2007-07-01 10:07:52 UTC (rev 891) @@ -0,0 +1,18 @@ +#include +#include +#include + +/* Atmospheric Air Density + * Requires Air Temperature and DEM + */ + +double roh_air(double dem, double tempka) +{ + double b, result; + + b = (( tempka - 0.00627 * dem ) / tempka ); + + result = 349.467 * pow( b , 5.26 ) / tempka ; + + return result; +} From chemin at grass.itc.it Sun Jul 1 12:20:15 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 12:20:17 2007 Subject: [grass-addons] r892 - trunk/grassaddons/gipe/i.eb.disp Message-ID: <200707011020.l61AKFWM017360@grass.itc.it> Author: chemin Date: 2007-07-01 12:20:10 +0200 (Sun, 01 Jul 2007) New Revision: 892 Removed: trunk/grassaddons/gipe/i.eb.disp/Makefile trunk/grassaddons/gipe/i.eb.disp/description.html trunk/grassaddons/gipe/i.eb.disp/main.c trunk/grassaddons/gipe/i.eb.disp/roh_air.c Log: Still trying to clean up mess Deleted: trunk/grassaddons/gipe/i.eb.disp/Makefile =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/Makefile 2007-07-01 10:07:52 UTC (rev 891) +++ trunk/grassaddons/gipe/i.eb.disp/Makefile 2007-07-01 10:20:10 UTC (rev 892) @@ -1,14 +0,0 @@ -MODULE_TOPDIR = ../.. - -PGM = i.eb.rohair - -LIBES = $(GISLIB) -DEPENDENCIES = $(GISDEP) - -include $(MODULE_TOPDIR)/include/Make/Module.make - -ifneq ($(USE_LARGEFILES),) - EXTRA_CFLAGS = -D_FILE_OFFSET_BITS=64 -endif - -default: cmd Deleted: trunk/grassaddons/gipe/i.eb.disp/description.html =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/description.html 2007-07-01 10:07:52 UTC (rev 891) +++ trunk/grassaddons/gipe/i.eb.disp/description.html 2007-07-01 10:20:10 UTC (rev 892) @@ -1,22 +0,0 @@ -

DESCRIPTION

- -i.eb.rohair calculates the Atmospheric Air Density. -

NOTES

-This is found in Bastiaanssen (1995). -

TODO

- - -

SEE ALSO

- - -i.eb.h_iter
-
- - -

AUTHORS

- -Yann Chemin
- - -

-Last changed: $Date: 2007/06/30 12:04:02 $ Deleted: trunk/grassaddons/gipe/i.eb.disp/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/main.c 2007-07-01 10:07:52 UTC (rev 891) +++ trunk/grassaddons/gipe/i.eb.disp/main.c 2007-07-01 10:20:10 UTC (rev 892) @@ -1,194 +0,0 @@ -/**************************************************************************** - * - * MODULE: i.eb.rohair - * AUTHOR(S): Yann Chemin - ychemin@gmail.com - * PURPOSE: Calculates the standard air density as seen in Pawan (2004) - * - * COPYRIGHT: (C) 2002-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 -#include -#include -#include -#include - - -double roh_air(double dem); - -int main(int argc, char *argv[]) -{ - struct Cell_head cellhd; //region+header info - char *mapset; // mapset name - int nrows, ncols; - int row,col; - - int verbose=1; - struct GModule *module; - struct Option *input1, *input2, *output1; - - struct Flag *flag1; - struct History history; //metadata - - /************************************/ - /* FMEO Declarations*****************/ - char *name; // input raster name - char *result1; //output raster name - //File Descriptors - int infd_dem, infd_tempka; - int outfd1; - - char *rohair; - char *dem, *tempka; - int i=0,j=0; - - void *inrast_dem, *inrast_tempka; - unsigned char *outrast1; - RASTER_MAP_TYPE data_type_output=DCELL_TYPE; - RASTER_MAP_TYPE data_type_dem; - RASTER_MAP_TYPE data_type_tempka; - /************************************/ - G_gisinit(argv[0]); - - module = G_define_module(); - module->keywords = _("rohair, energy balance, SEBAL"); - module->description = _("Standard height-based Air Density as seen in Pawan (2004)."); - - /* Define the different options */ - input1 = G_define_option() ; - input1->key = _("dem"); - input1->type = TYPE_STRING; - input1->required = YES; - input1->gisprompt =_("old,cell,raster") ; - input1->description=_("Name of the DEM map [-]"); - input1->answer =_("dem"); - - input2 = G_define_option() ; - input2->key = _("dem"); - input2->type = TYPE_STRING; - input2->required = YES; - input2->gisprompt =_("old,cell,raster") ; - input2->description=_("Name of the Air Temperature map [K]"); - input2->answer =_("tempka"); - - output1 = G_define_option() ; - output1->key =_("rohair"); - output1->type = TYPE_STRING; - output1->required = YES; - output1->gisprompt =_("new,dcell,raster"); - output1->description=_("Name of the output rohair layer"); - output1->answer =_("rohair"); - - - flag1 = G_define_flag(); - flag1->key = 'q'; - flag1->description = _("Quiet"); - - /********************/ - if (G_parser(argc, argv)) - exit (EXIT_FAILURE); - - dem = input1->answer; - - result1 = output1->answer; - verbose = (!flag1->answer); - /***************************************************/ - mapset = G_find_cell2(dem, ""); - if (mapset == NULL) { - G_fatal_error(_("cell file [%s] not found"), dem); - } - data_type_dem = G_raster_map_type(dem,mapset); - if ( (infd_dem = G_open_cell_old (dem,mapset)) < 0) - G_fatal_error (_("Cannot open cell file [%s]"), dem); - if (G_get_cellhd (dem, mapset, &cellhd) < 0) - G_fatal_error (_("Cannot read file header of [%s])"), dem); - inrast_dem = G_allocate_raster_buf(data_type_dem); - /***************************************************/ - /***************************************************/ - mapset = G_find_cell2(tempka, ""); - if (mapset == NULL) { - G_fatal_error(_("cell file [%s] not found"), tempka); - } - data_type_tempka = G_raster_map_type(tempka,mapset); - if ( (infd_tempka = G_open_cell_old (tempka,mapset)) < 0) - G_fatal_error (_("Cannot open cell file [%s]"), tempka); - if (G_get_cellhd (tempka, mapset, &cellhd) < 0) - G_fatal_error (_("Cannot read file header of [%s])"), tempka); - inrast_tempka = G_allocate_raster_buf(data_type_tempka); - /***************************************************/ - G_debug(3, "number of rows %d",cellhd.rows); - nrows = G_window_rows(); - ncols = G_window_cols(); - outrast1 = G_allocate_raster_buf(data_type_output); - /* Create New raster files */ - if ( (outfd1 = G_open_raster_new (result1,data_type_output)) < 0) - G_fatal_error(_("Could not open <%s>"),result1); - /* Process pixels */ - for (row = 0; row < nrows; row++) - { - DCELL d; - DCELL d_dem; - DCELL d_tempka; - if(verbose) - G_percent(row,nrows,2); - /* read soil input maps */ - if(G_get_raster_row(infd_dem,inrast_dem,row,data_type_dem)<0) - G_fatal_error(_("Could not read from <%s>"),dem); - /*process the data */ - for (col=0; col < ncols; col++) - { - switch(data_type_dem){ - case CELL_TYPE: - d_dem = (double) ((CELL *) inrast_dem)[col]; - break; - case FCELL_TYPE: - d_dem = (double) ((FCELL *) inrast_dem)[col]; - break; - case DCELL_TYPE: - d_dem = ((DCELL *) inrast_dem)[col]; - break; - } - switch(data_type_tempka){ - case CELL_TYPE: - d_tempka = (double) ((CELL *) inrast_tempka)[col]; - break; - case FCELL_TYPE: - d_tempka = (double) ((FCELL *) inrast_tempka)[col]; - break; - case DCELL_TYPE: - d_tempka = ((DCELL *) inrast_tempka)[col]; - break; - } - if(G_is_d_null_value(&d_dem)||G_is_d_null_value(&d_tempka)){ - ((DCELL *) outrast1)[col] = -999.99; - } else { - /********************/ - /* calculate rohair */ - d = roh_air(d_dem, tempka); - ((DCELL *) outrast1)[col] = d; - } - } - if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) - G_fatal_error(_("Cannot write to output raster file")); - } - - G_free (inrast_dem); - G_free (inrast_tempka); - G_close_cell (infd_dem); - G_close_cell (infd_tempka); - - G_free (outrast1); - G_close_cell (outfd1); - - G_short_history(result1, "raster", &history); - G_command_history(&history); - G_write_history(result1,&history); - - exit(EXIT_SUCCESS); -} - Deleted: trunk/grassaddons/gipe/i.eb.disp/roh_air.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/roh_air.c 2007-07-01 10:07:52 UTC (rev 891) +++ trunk/grassaddons/gipe/i.eb.disp/roh_air.c 2007-07-01 10:20:10 UTC (rev 892) @@ -1,18 +0,0 @@ -#include -#include -#include - -/* Atmospheric Air Density - * Requires Air Temperature and DEM - */ - -double roh_air(double dem, double tempka) -{ - double b, result; - - b = (( tempka - 0.00627 * dem ) / tempka ); - - result = 349.467 * pow( b , 5.26 ) / tempka ; - - return result; -} From chemin at grass.itc.it Sun Jul 1 12:20:39 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 12:20:41 2007 Subject: [grass-addons] r893 - trunk/grassaddons/gipe/i.eb.disp Message-ID: <200707011020.l61AKdWl017398@grass.itc.it> Author: chemin Date: 2007-07-01 12:20:33 +0200 (Sun, 01 Jul 2007) New Revision: 893 Added: trunk/grassaddons/gipe/i.eb.disp/Makefile trunk/grassaddons/gipe/i.eb.disp/description.html trunk/grassaddons/gipe/i.eb.disp/main.c Log: Still trying to clean up mess Added: trunk/grassaddons/gipe/i.eb.disp/Makefile =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/Makefile (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/Makefile 2007-07-01 10:20:33 UTC (rev 893) @@ -0,0 +1,14 @@ +MODULE_TOPDIR = ../.. + +PGM = i.eb.disp + +LIBES = $(GISLIB) +DEPENDENCIES = $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +ifneq ($(USE_LARGEFILES),) + EXTRA_CFLAGS = -D_FILE_OFFSET_BITS=64 +endif + +default: cmd Added: trunk/grassaddons/gipe/i.eb.disp/description.html =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/description.html (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/description.html 2007-07-01 10:20:33 UTC (rev 893) @@ -0,0 +1,23 @@ +

DESCRIPTION

+ +i.eb.disp calculates the displacement height above the earth skin. +

NOTES

+This is found in Pawan (2004). +

TODO

+ + +

SEE ALSO

+ + +i.eb.psi
+i.eb.ublend
+
+ + +

AUTHORS

+ +Yann Chemin, Asian Institute of Technology, Thailand
+ + +

+Last changed: $Date: 2006/10/13 22:19:55 $ Added: trunk/grassaddons/gipe/i.eb.disp/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/main.c (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/main.c 2007-07-01 10:20:33 UTC (rev 893) @@ -0,0 +1,167 @@ +/**************************************************************************** + * + * MODULE: i.eb.disp + * AUTHOR(S): Yann Chemin - ychemin@gmail.com + * PURPOSE: Calculates the displacement height above skin surface + * as seen in Pawan (2004), a flag makes savi2lai instead of + * direct LAI input. + * + * COPYRIGHT: (C) 2002-2006 by the GRASS Development Team + * + * This program is free software under the GNU General Public + * License (>=v2). Read the file COPYING that comes with GRASS + * for details. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include + + +double dis_p(double lai); +double savi_lai(double savi); + +int main(int argc, char *argv[]) +{ + struct Cell_head cellhd; //region+header info + char *mapset; // mapset name + int nrows, ncols; + int row,col; + + int verbose=1; + struct GModule *module; + struct Option *input1, *output1; + + struct Flag *flag1, *flag2; + struct History history; //metadata + + /************************************/ + /* FMEO Declarations*****************/ + char *name; // input raster name + char *result1; //output raster name + //File Descriptors + int infd_lai; + int outfd1; + + char *disp; + char *lai; + int i=0,j=0; + + void *inrast_lai; + unsigned char *outrast1; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; + RASTER_MAP_TYPE data_type_lai; + /************************************/ + G_gisinit(argv[0]); + + module = G_define_module(); + module->keywords = _("disp, energy balance, SEBAL"); + module->description = _("Displacement height above skin surface, as seen in Pawan (2004). A flag (-s) permits direct SAVI input using the equation in the same document, be careful using it."); + + /* Define the different options */ + input1 = G_define_option() ; + input1->key = _("lai"); + input1->type = TYPE_STRING; + input1->required = YES; + input1->gisprompt =_("old,cell,raster") ; + input1->description=_("Name of the LAI map [-]"); + input1->answer =_("lai"); + + output1 = G_define_option() ; + output1->key =_("disp"); + output1->type = TYPE_STRING; + output1->required = YES; + output1->gisprompt =_("new,dcell,raster"); + output1->description=_("Name of the output disp layer"); + output1->answer =_("disp"); + + + flag1 = G_define_flag(); + flag1->key = 'q'; + flag1->description = _("Quiet"); + + flag2 = G_define_flag(); + flag2->key = 's'; + flag2->description = _("use savi2lai conversion (Pawan, 2004)"); + + /********************/ + if (G_parser(argc, argv)) + exit (EXIT_FAILURE); + + lai = input1->answer; + + result1 = output1->answer; + verbose = (!flag1->answer); + /***************************************************/ + mapset = G_find_cell2(lai, ""); + if (mapset == NULL) { + G_fatal_error(_("cell file [%s] not found"), lai); + } + data_type_lai = G_raster_map_type(lai,mapset); + if ( (infd_lai = G_open_cell_old (lai,mapset)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), lai); + if (G_get_cellhd (lai, mapset, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s])"), lai); + inrast_lai = G_allocate_raster_buf(data_type_lai); + /***************************************************/ + G_debug(3, "number of rows %d",cellhd.rows); + nrows = G_window_rows(); + ncols = G_window_cols(); + outrast1 = G_allocate_raster_buf(data_type_output); + /* Create New raster files */ + if ( (outfd1 = G_open_raster_new (result1,data_type_output)) < 0) + G_fatal_error(_("Could not open <%s>"),result1); + /* Process pixels */ + for (row = 0; row < nrows; row++) + { + DCELL d; + DCELL d_lai; + if(verbose) + G_percent(row,nrows,2); +// printf("row = %i/%i\n",row,nrows); + /* read soil input maps */ + if(G_get_raster_row(infd_lai,inrast_lai,row,data_type_lai)<0) + G_fatal_error(_("Could not read from <%s>"),lai); + /*process the data */ + for (col=0; col < ncols; col++) + { + d_lai = ((DCELL *) inrast_lai)[col]; + if(G_is_d_null_value(&d_lai)){ + ((DCELL *) outrast1)[col] = -999.99; + } else { + if(flag2->answer){ + /********************/ + /* savi2lai() */ + d = savi_lai(d_lai); + /********************/ + /* calculate disp */ + d = dis_p(d); + ((DCELL *) outrast1)[col] = d; + } else { + /********************/ + /* calculate disp */ + d = dis_p(d_lai); + ((DCELL *) outrast1)[col] = d; + } + } + } + if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) + G_fatal_error(_("Cannot write to output raster file")); + } + + G_free (inrast_lai); + G_close_cell (infd_lai); + + G_free (outrast1); + G_close_cell (outfd1); + + G_short_history(result1, "raster", &history); + G_command_history(&history); + G_write_history(result1,&history); + + exit(EXIT_SUCCESS); +} + From chemin at grass.itc.it Sun Jul 1 12:44:16 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 12:44:18 2007 Subject: [grass-addons] r894 - trunk/grassaddons/gipe Message-ID: <200707011044.l61AiGQu017431@grass.itc.it> Author: chemin Date: 2007-07-01 12:43:48 +0200 (Sun, 01 Jul 2007) New Revision: 894 Removed: trunk/grassaddons/gipe/i.eb.disp/ Modified: trunk/grassaddons/gipe/gmmenu.tcl Log: Still more cleaning mess Modified: trunk/grassaddons/gipe/gmmenu.tcl =================================================================== --- trunk/grassaddons/gipe/gmmenu.tcl 2007-07-01 10:20:33 UTC (rev 893) +++ trunk/grassaddons/gipe/gmmenu.tcl 2007-07-01 10:43:48 UTC (rev 894) @@ -575,6 +575,7 @@ {command {[G_msg "Net radiation"]} {} "i.eb.netrad" {} -command {execute i.eb.netrad }} {separator} {command {[G_msg "Displacement height"]} {} "i.eb.disp" {} -command {execute i.eb.disp }} + {command {[G_msg "Atm. Air Density"]} {} "i.eb.rohair" {} -command {execute i.eb.rohair }} {separator} {command {[G_msg "Monin-Obukov Length"]} {} "i.eb.molength" {} -command {execute i.eb.molength }} {command {[G_msg "Psichrometric param. for heat"]} {} "i.eb.psi" {} -command {execute i.eb.psi }} From chemin at grass.itc.it Sun Jul 1 12:47:25 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 12:47:27 2007 Subject: [grass-addons] r895 - in trunk/grassaddons/gipe: . i.eb.disp Message-ID: <200707011047.l61AlPaR017463@grass.itc.it> Author: chemin Date: 2007-07-01 12:46:54 +0200 (Sun, 01 Jul 2007) New Revision: 895 Added: trunk/grassaddons/gipe/i.eb.disp/ trunk/grassaddons/gipe/i.eb.disp/Makefile trunk/grassaddons/gipe/i.eb.disp/description.html trunk/grassaddons/gipe/i.eb.disp/disp.c trunk/grassaddons/gipe/i.eb.disp/main.c trunk/grassaddons/gipe/i.eb.disp/savi2lai.c Log: Still more cleaning mess Added: trunk/grassaddons/gipe/i.eb.disp/Makefile =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/Makefile (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/Makefile 2007-07-01 10:46:54 UTC (rev 895) @@ -0,0 +1,14 @@ +MODULE_TOPDIR = ../.. + +PGM = i.eb.disp + +LIBES = $(GISLIB) +DEPENDENCIES = $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +ifneq ($(USE_LARGEFILES),) + EXTRA_CFLAGS = -D_FILE_OFFSET_BITS=64 +endif + +default: cmd Added: trunk/grassaddons/gipe/i.eb.disp/description.html =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/description.html (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/description.html 2007-07-01 10:46:54 UTC (rev 895) @@ -0,0 +1,23 @@ +

DESCRIPTION

+ +i.eb.disp calculates the displacement height above the earth skin. +

NOTES

+This is found in Pawan (2004). +

TODO

+ + +

SEE ALSO

+ + +i.eb.psi
+i.eb.ublend
+
+ + +

AUTHORS

+ +Yann Chemin, Asian Institute of Technology, Thailand
+ + +

+Last changed: $Date: 2006/10/13 22:19:55 $ Added: trunk/grassaddons/gipe/i.eb.disp/disp.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/disp.c (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/disp.c 2007-07-01 10:46:54 UTC (rev 895) @@ -0,0 +1,14 @@ +#include +#include +#include + +// Found in Pawan (2004) + +double dis_p(double lai) +{ + double result; + + result = 1*(1-((1-exp(-(pow(20.6*lai,0.5))))/(pow(20.6*lai,0.5)))); + + return result; +} Added: trunk/grassaddons/gipe/i.eb.disp/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/main.c (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/main.c 2007-07-01 10:46:54 UTC (rev 895) @@ -0,0 +1,167 @@ +/**************************************************************************** + * + * MODULE: i.eb.disp + * AUTHOR(S): Yann Chemin - ychemin@gmail.com + * PURPOSE: Calculates the displacement height above skin surface + * as seen in Pawan (2004), a flag makes savi2lai instead of + * direct LAI input. + * + * COPYRIGHT: (C) 2002-2006 by the GRASS Development Team + * + * This program is free software under the GNU General Public + * License (>=v2). Read the file COPYING that comes with GRASS + * for details. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include + + +double dis_p(double lai); +double savi_lai(double savi); + +int main(int argc, char *argv[]) +{ + struct Cell_head cellhd; //region+header info + char *mapset; // mapset name + int nrows, ncols; + int row,col; + + int verbose=1; + struct GModule *module; + struct Option *input1, *output1; + + struct Flag *flag1, *flag2; + struct History history; //metadata + + /************************************/ + /* FMEO Declarations*****************/ + char *name; // input raster name + char *result1; //output raster name + //File Descriptors + int infd_lai; + int outfd1; + + char *disp; + char *lai; + int i=0,j=0; + + void *inrast_lai; + unsigned char *outrast1; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; + RASTER_MAP_TYPE data_type_lai; + /************************************/ + G_gisinit(argv[0]); + + module = G_define_module(); + module->keywords = _("disp, energy balance, SEBAL"); + module->description = _("Displacement height above skin surface, as seen in Pawan (2004). A flag (-s) permits direct SAVI input using the equation in the same document, be careful using it."); + + /* Define the different options */ + input1 = G_define_option() ; + input1->key = _("lai"); + input1->type = TYPE_STRING; + input1->required = YES; + input1->gisprompt =_("old,cell,raster") ; + input1->description=_("Name of the LAI map [-]"); + input1->answer =_("lai"); + + output1 = G_define_option() ; + output1->key =_("disp"); + output1->type = TYPE_STRING; + output1->required = YES; + output1->gisprompt =_("new,dcell,raster"); + output1->description=_("Name of the output disp layer"); + output1->answer =_("disp"); + + + flag1 = G_define_flag(); + flag1->key = 'q'; + flag1->description = _("Quiet"); + + flag2 = G_define_flag(); + flag2->key = 's'; + flag2->description = _("use savi2lai conversion (Pawan, 2004)"); + + /********************/ + if (G_parser(argc, argv)) + exit (EXIT_FAILURE); + + lai = input1->answer; + + result1 = output1->answer; + verbose = (!flag1->answer); + /***************************************************/ + mapset = G_find_cell2(lai, ""); + if (mapset == NULL) { + G_fatal_error(_("cell file [%s] not found"), lai); + } + data_type_lai = G_raster_map_type(lai,mapset); + if ( (infd_lai = G_open_cell_old (lai,mapset)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), lai); + if (G_get_cellhd (lai, mapset, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s])"), lai); + inrast_lai = G_allocate_raster_buf(data_type_lai); + /***************************************************/ + G_debug(3, "number of rows %d",cellhd.rows); + nrows = G_window_rows(); + ncols = G_window_cols(); + outrast1 = G_allocate_raster_buf(data_type_output); + /* Create New raster files */ + if ( (outfd1 = G_open_raster_new (result1,data_type_output)) < 0) + G_fatal_error(_("Could not open <%s>"),result1); + /* Process pixels */ + for (row = 0; row < nrows; row++) + { + DCELL d; + DCELL d_lai; + if(verbose) + G_percent(row,nrows,2); +// printf("row = %i/%i\n",row,nrows); + /* read soil input maps */ + if(G_get_raster_row(infd_lai,inrast_lai,row,data_type_lai)<0) + G_fatal_error(_("Could not read from <%s>"),lai); + /*process the data */ + for (col=0; col < ncols; col++) + { + d_lai = ((DCELL *) inrast_lai)[col]; + if(G_is_d_null_value(&d_lai)){ + ((DCELL *) outrast1)[col] = -999.99; + } else { + if(flag2->answer){ + /********************/ + /* savi2lai() */ + d = savi_lai(d_lai); + /********************/ + /* calculate disp */ + d = dis_p(d); + ((DCELL *) outrast1)[col] = d; + } else { + /********************/ + /* calculate disp */ + d = dis_p(d_lai); + ((DCELL *) outrast1)[col] = d; + } + } + } + if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) + G_fatal_error(_("Cannot write to output raster file")); + } + + G_free (inrast_lai); + G_close_cell (infd_lai); + + G_free (outrast1); + G_close_cell (outfd1); + + G_short_history(result1, "raster", &history); + G_command_history(&history); + G_write_history(result1,&history); + + exit(EXIT_SUCCESS); +} + Added: trunk/grassaddons/gipe/i.eb.disp/savi2lai.c =================================================================== --- trunk/grassaddons/gipe/i.eb.disp/savi2lai.c (rev 0) +++ trunk/grassaddons/gipe/i.eb.disp/savi2lai.c 2007-07-01 10:46:54 UTC (rev 895) @@ -0,0 +1,20 @@ +#include +#include +#include + +// Found in Pawan (2004) + +double savi_lai(double savi) +{ + double result; + + if (savi < 0.1){ + result = 0.00001; + } else if (savi > 0.689){ + result = 6.0; + } else { + result = -(log((0.69-savi)/0.59)/0.91); + } + + return result; +} From chemin at grass.itc.it Sun Jul 1 12:50:08 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 12:50:10 2007 Subject: [grass-addons] r896 - in trunk/grassaddons/gipe: . i.eb.rohair Message-ID: <200707011050.l61Ao8qC017483@grass.itc.it> Author: chemin Date: 2007-07-01 12:49:29 +0200 (Sun, 01 Jul 2007) New Revision: 896 Added: trunk/grassaddons/gipe/i.eb.rohair/ trunk/grassaddons/gipe/i.eb.rohair/Makefile trunk/grassaddons/gipe/i.eb.rohair/description.html trunk/grassaddons/gipe/i.eb.rohair/main.c trunk/grassaddons/gipe/i.eb.rohair/roh_air.c Log: Still more cleaning mess Added: trunk/grassaddons/gipe/i.eb.rohair/Makefile =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/Makefile (rev 0) +++ trunk/grassaddons/gipe/i.eb.rohair/Makefile 2007-07-01 10:49:29 UTC (rev 896) @@ -0,0 +1,14 @@ +MODULE_TOPDIR = ../.. + +PGM = i.eb.rohair + +LIBES = $(GISLIB) +DEPENDENCIES = $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +ifneq ($(USE_LARGEFILES),) + EXTRA_CFLAGS = -D_FILE_OFFSET_BITS=64 +endif + +default: cmd Added: trunk/grassaddons/gipe/i.eb.rohair/description.html =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/description.html (rev 0) +++ trunk/grassaddons/gipe/i.eb.rohair/description.html 2007-07-01 10:49:29 UTC (rev 896) @@ -0,0 +1,22 @@ +

DESCRIPTION

+ +i.eb.rohair calculates the Atmospheric Air Density. +

NOTES

+This is found in Bastiaanssen (1995). +

TODO

+ + +

SEE ALSO

+ + +i.eb.h_iter
+
+ + +

AUTHORS

+ +Yann Chemin
+ + +

+Last changed: $Date: 2007/06/30 12:04:02 $ Added: trunk/grassaddons/gipe/i.eb.rohair/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/main.c (rev 0) +++ trunk/grassaddons/gipe/i.eb.rohair/main.c 2007-07-01 10:49:29 UTC (rev 896) @@ -0,0 +1,194 @@ +/**************************************************************************** + * + * MODULE: i.eb.rohair + * AUTHOR(S): Yann Chemin - ychemin@gmail.com + * PURPOSE: Calculates the standard air density as seen in Pawan (2004) + * + * COPYRIGHT: (C) 2002-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 +#include +#include +#include +#include + + +double roh_air(double dem, double tempka); + +int main(int argc, char *argv[]) +{ + struct Cell_head cellhd; //region+header info + char *mapset; // mapset name + int nrows, ncols; + int row,col; + + int verbose=1; + struct GModule *module; + struct Option *input1, *input2, *output1; + + struct Flag *flag1; + struct History history; //metadata + + /************************************/ + /* FMEO Declarations*****************/ + char *name; // input raster name + char *result1; //output raster name + //File Descriptors + int infd_dem, infd_tempka; + int outfd1; + + char *rohair; + char *dem, *tempka; + int i=0,j=0; + + void *inrast_dem, *inrast_tempka; + unsigned char *outrast1; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; + RASTER_MAP_TYPE data_type_dem; + RASTER_MAP_TYPE data_type_tempka; + /************************************/ + G_gisinit(argv[0]); + + module = G_define_module(); + module->keywords = _("rohair, energy balance, SEBAL"); + module->description = _("Standard height-based Air Density as seen in Pawan (2004)."); + + /* Define the different options */ + input1 = G_define_option() ; + input1->key = _("dem"); + input1->type = TYPE_STRING; + input1->required = YES; + input1->gisprompt =_("old,cell,raster") ; + input1->description=_("Name of the DEM map [-]"); + input1->answer =_("dem"); + + input2 = G_define_option() ; + input2->key = _("dem"); + input2->type = TYPE_STRING; + input2->required = YES; + input2->gisprompt =_("old,cell,raster") ; + input2->description=_("Name of the Air Temperature map [K]"); + input2->answer =_("tempka"); + + output1 = G_define_option() ; + output1->key =_("rohair"); + output1->type = TYPE_STRING; + output1->required = YES; + output1->gisprompt =_("new,dcell,raster"); + output1->description=_("Name of the output rohair layer"); + output1->answer =_("rohair"); + + + flag1 = G_define_flag(); + flag1->key = 'q'; + flag1->description = _("Quiet"); + + /********************/ + if (G_parser(argc, argv)) + exit (EXIT_FAILURE); + + dem = input1->answer; + + result1 = output1->answer; + verbose = (!flag1->answer); + /***************************************************/ + mapset = G_find_cell2(dem, ""); + if (mapset == NULL) { + G_fatal_error(_("cell file [%s] not found"), dem); + } + data_type_dem = G_raster_map_type(dem,mapset); + if ( (infd_dem = G_open_cell_old (dem,mapset)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), dem); + if (G_get_cellhd (dem, mapset, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s])"), dem); + inrast_dem = G_allocate_raster_buf(data_type_dem); + /***************************************************/ + /***************************************************/ + mapset = G_find_cell2(tempka, ""); + if (mapset == NULL) { + G_fatal_error(_("cell file [%s] not found"), tempka); + } + data_type_tempka = G_raster_map_type(tempka,mapset); + if ( (infd_tempka = G_open_cell_old (tempka,mapset)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), tempka); + if (G_get_cellhd (tempka, mapset, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s])"), tempka); + inrast_tempka = G_allocate_raster_buf(data_type_tempka); + /***************************************************/ + G_debug(3, "number of rows %d",cellhd.rows); + nrows = G_window_rows(); + ncols = G_window_cols(); + outrast1 = G_allocate_raster_buf(data_type_output); + /* Create New raster files */ + if ( (outfd1 = G_open_raster_new (result1,data_type_output)) < 0) + G_fatal_error(_("Could not open <%s>"),result1); + /* Process pixels */ + for (row = 0; row < nrows; row++) + { + DCELL d; + DCELL d_dem; + DCELL d_tempka; + if(verbose) + G_percent(row,nrows,2); + /* read soil input maps */ + if(G_get_raster_row(infd_dem,inrast_dem,row,data_type_dem)<0) + G_fatal_error(_("Could not read from <%s>"),dem); + /*process the data */ + for (col=0; col < ncols; col++) + { + switch(data_type_dem){ + case CELL_TYPE: + d_dem = (double) ((CELL *) inrast_dem)[col]; + break; + case FCELL_TYPE: + d_dem = (double) ((FCELL *) inrast_dem)[col]; + break; + case DCELL_TYPE: + d_dem = ((DCELL *) inrast_dem)[col]; + break; + } + switch(data_type_tempka){ + case CELL_TYPE: + d_tempka = (double) ((CELL *) inrast_tempka)[col]; + break; + case FCELL_TYPE: + d_tempka = (double) ((FCELL *) inrast_tempka)[col]; + break; + case DCELL_TYPE: + d_tempka = ((DCELL *) inrast_tempka)[col]; + break; + } + if(G_is_d_null_value(&d_dem)||G_is_d_null_value(&d_tempka)){ + ((DCELL *) outrast1)[col] = -999.99; + } else { + /********************/ + /* calculate rohair */ + d = roh_air(d_dem, d_tempka); + ((DCELL *) outrast1)[col] = d; + } + } + if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) + G_fatal_error(_("Cannot write to output raster file")); + } + + G_free (inrast_dem); + G_free (inrast_tempka); + G_close_cell (infd_dem); + G_close_cell (infd_tempka); + + G_free (outrast1); + G_close_cell (outfd1); + + G_short_history(result1, "raster", &history); + G_command_history(&history); + G_write_history(result1,&history); + + exit(EXIT_SUCCESS); +} + Added: trunk/grassaddons/gipe/i.eb.rohair/roh_air.c =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/roh_air.c (rev 0) +++ trunk/grassaddons/gipe/i.eb.rohair/roh_air.c 2007-07-01 10:49:29 UTC (rev 896) @@ -0,0 +1,18 @@ +#include +#include +#include + +/* Atmospheric Air Density + * Requires Air Temperature and DEM + */ + +double roh_air(double dem, double tempka) +{ + double b, result; + + b = (( tempka - 0.00627 * dem ) / tempka ); + + result = 349.467 * pow( b , 5.26 ) / tempka ; + + return result; +} From chemin at grass.itc.it Sun Jul 1 13:09:41 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 13:09:43 2007 Subject: [grass-addons] r897 - trunk/grassaddons/gipe/i.eb.rohair Message-ID: <200707011109.l61B9fo4017545@grass.itc.it> Author: chemin Date: 2007-07-01 13:09:27 +0200 (Sun, 01 Jul 2007) New Revision: 897 Modified: trunk/grassaddons/gipe/i.eb.rohair/main.c Log: Bug fixing Modified: trunk/grassaddons/gipe/i.eb.rohair/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/main.c 2007-07-01 10:49:29 UTC (rev 896) +++ trunk/grassaddons/gipe/i.eb.rohair/main.c 2007-07-01 11:09:27 UTC (rev 897) @@ -69,7 +69,7 @@ input1->answer =_("dem"); input2 = G_define_option() ; - input2->key = _("dem"); + input2->key = _("tempka"); input2->type = TYPE_STRING; input2->required = YES; input2->gisprompt =_("old,cell,raster") ; From chemin at grass.itc.it Sun Jul 1 14:25:32 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 14:25:33 2007 Subject: [grass-addons] r898 - trunk/grassaddons/gipe/script_generator Message-ID: <200707011225.l61CPWlG018635@grass.itc.it> Author: chemin Date: 2007-07-01 14:25:29 +0200 (Sun, 01 Jul 2007) New Revision: 898 Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: Update script generator with i.eb.rohair Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 11:09:27 UTC (rev 897) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 12:25:29 UTC (rev 898) @@ -643,6 +643,10 @@ system("echo \"\" >> temp.txt"); sprintf(sys_24,"echo \"i.eb.disp -s lai=%s.savi disp=%s.disp --overwrite\" >> temp.txt",basedate,basedate); system(sys_24); + system("echo \"\" >> temp.txt"); + sprintf(sys_25,"echo \"i.eb.rohair dem=%s.dem tempka=%s.tempka rohair=%s.rohair --overwrite\" >> temp.txt",basedate,basedate,basedate); + system(sys_25); + system("echo \"\" >> temp.txt"); /*clean maps system("chmod +x temp.txt; cat temp.txt; echo \"Start GRASS Processing\n\" ; ./temp.txt"); */ From chemin at grass.itc.it Sun Jul 1 15:10:39 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 15:10:40 2007 Subject: [grass-addons] r899 - trunk/grassaddons/gipe/script_generator Message-ID: <200707011310.l61DAddn018704@grass.itc.it> Author: chemin Date: 2007-07-01 15:10:35 +0200 (Sun, 01 Jul 2007) New Revision: 899 Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: Updated script generator with automatic SRTM download/import for further Actual Evapotranspiration processing Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 12:25:29 UTC (rev 898) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 13:10:35 UTC (rev 899) @@ -86,6 +86,7 @@ char sys_15[1000],sys_16[1000],sys_17[1000],sys_18[1000]; char sys_19[1000],sys_20[1000],sys_21[1000],sys_22[1000]; char sys_23[1000],sys_24[1000],sys_25[1000],sys_26[1000]; + char sys_27[1000],sys_28[1000],sys_29[1000],sys_30[1000]; if(argc < 1){ usage(); @@ -644,9 +645,22 @@ sprintf(sys_24,"echo \"i.eb.disp -s lai=%s.savi disp=%s.disp --overwrite\" >> temp.txt",basedate,basedate); system(sys_24); system("echo \"\" >> temp.txt"); - sprintf(sys_25,"echo \"i.eb.rohair dem=%s.dem tempka=%s.tempka rohair=%s.rohair --overwrite\" >> temp.txt",basedate,basedate,basedate); + system("echo \"#DOWNLOAD SRTM DEM 90m unfinished\" >> temp.txt"); + system("echo \"\" >> temp.txt"); + sprintf(sys_25,"echo \"wget -c ftp://ftp.glcf.umiacs.umd.edu/glcf/SRTM/WRS2_Tiles/p%s/SRTM_u03_p%sr%s/SRTM_u03_p%sr%s.tif.gz \" >> temp.txt",path,path,row,path,row); system(sys_25); system("echo \"\" >> temp.txt"); + system("echo \"#IMPORT SRTM DEM 90m unfinished\" >> temp.txt"); + system("echo \"\" >> temp.txt"); + sprintf(sys_26,"echo \"gzip -d SRTM_u03_p%sr%s.tif.gz \" >> temp.txt",path,row); + system(sys_26); + system("echo \"\" >> temp.txt"); + sprintf(sys_27,"echo \"r.in.gdal -o input=SRTM_u03_p%sr%s.tif output=%s.dem title=SRTM_u03\" >> temp.txt",path,row,basedate); + system(sys_27); + system("echo \"\" >> temp.txt"); + sprintf(sys_28,"echo \"i.eb.rohair dem=%s.dem tempka=%s.tempka rohair=%s.rohair --overwrite\" >> temp.txt",basedate,basedate,basedate); + system(sys_28); + system("echo \"\" >> temp.txt"); /*clean maps system("chmod +x temp.txt; cat temp.txt; echo \"Start GRASS Processing\n\" ; ./temp.txt"); */ From chemin at grass.itc.it Sun Jul 1 15:24:07 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 15:24:08 2007 Subject: [grass-addons] r900 - trunk/grassaddons/gipe/i.eb.rohair Message-ID: <200707011324.l61DO7QZ018763@grass.itc.it> Author: chemin Date: 2007-07-01 15:24:03 +0200 (Sun, 01 Jul 2007) New Revision: 900 Modified: trunk/grassaddons/gipe/i.eb.rohair/main.c Log: Bug fixing Modified: trunk/grassaddons/gipe/i.eb.rohair/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/main.c 2007-07-01 13:10:35 UTC (rev 899) +++ trunk/grassaddons/gipe/i.eb.rohair/main.c 2007-07-01 13:24:03 UTC (rev 900) @@ -65,7 +65,7 @@ input1->type = TYPE_STRING; input1->required = YES; input1->gisprompt =_("old,cell,raster") ; - input1->description=_("Name of the DEM map [-]"); + input1->description=_("Name of the DEM map [m]"); input1->answer =_("dem"); input2 = G_define_option() ; @@ -94,6 +94,7 @@ exit (EXIT_FAILURE); dem = input1->answer; + tempka = input2->answer; result1 = output1->answer; verbose = (!flag1->answer); From chemin at grass.itc.it Sun Jul 1 15:54:42 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 15:54:43 2007 Subject: [grass-addons] r901 - trunk/grassaddons/gipe/i.eb.rohair Message-ID: <200707011354.l61DsgWb018815@grass.itc.it> Author: chemin Date: 2007-07-01 15:54:37 +0200 (Sun, 01 Jul 2007) New Revision: 901 Modified: trunk/grassaddons/gipe/i.eb.rohair/main.c trunk/grassaddons/gipe/i.eb.rohair/roh_air.c Log: Bug fixing Modified: trunk/grassaddons/gipe/i.eb.rohair/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/main.c 2007-07-01 13:24:03 UTC (rev 900) +++ trunk/grassaddons/gipe/i.eb.rohair/main.c 2007-07-01 13:54:37 UTC (rev 901) @@ -28,11 +28,9 @@ int nrows, ncols; int row,col; - int verbose=1; struct GModule *module; struct Option *input1, *input2, *output1; - struct Flag *flag1; struct History history; //metadata /************************************/ @@ -83,12 +81,7 @@ output1->gisprompt =_("new,dcell,raster"); output1->description=_("Name of the output rohair layer"); output1->answer =_("rohair"); - - flag1 = G_define_flag(); - flag1->key = 'q'; - flag1->description = _("Quiet"); - /********************/ if (G_parser(argc, argv)) exit (EXIT_FAILURE); @@ -97,7 +90,6 @@ tempka = input2->answer; result1 = output1->answer; - verbose = (!flag1->answer); /***************************************************/ mapset = G_find_cell2(dem, ""); if (mapset == NULL) { @@ -135,11 +127,11 @@ DCELL d; DCELL d_dem; DCELL d_tempka; - if(verbose) - G_percent(row,nrows,2); - /* read soil input maps */ + /* read input maps */ if(G_get_raster_row(infd_dem,inrast_dem,row,data_type_dem)<0) G_fatal_error(_("Could not read from <%s>"),dem); + if(G_get_raster_row(infd_tempka,inrast_tempka,row,data_type_tempka)<0) + G_fatal_error(_("Could not read from <%s>"),tempka); /*process the data */ for (col=0; col < ncols; col++) { @@ -165,8 +157,10 @@ d_tempka = ((DCELL *) inrast_tempka)[col]; break; } - if(G_is_d_null_value(&d_dem)||G_is_d_null_value(&d_tempka)){ + if(G_is_d_null_value(&d_dem)){ ((DCELL *) outrast1)[col] = -999.99; + } else if (G_is_d_null_value(&d_tempka)){ + ((DCELL *) outrast1)[col] = -999.99; } else { /********************/ /* calculate rohair */ Modified: trunk/grassaddons/gipe/i.eb.rohair/roh_air.c =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/roh_air.c 2007-07-01 13:24:03 UTC (rev 900) +++ trunk/grassaddons/gipe/i.eb.rohair/roh_air.c 2007-07-01 13:54:37 UTC (rev 901) @@ -10,7 +10,7 @@ { double b, result; - b = (( tempka - 0.00627 * dem ) / tempka ); + b = (( tempka - (0.00627 * dem )) / tempka ); result = 349.467 * pow( b , 5.26 ) / tempka ; From chemin at grass.itc.it Sun Jul 1 20:48:18 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Sun Jul 1 20:48:19 2007 Subject: [grass-addons] r902 - in trunk/grassaddons/gipe: . i.eb.deltat i.eb.h_iter i.eb.rohair script_generator Message-ID: <200707011848.l61ImIdt021109@grass.itc.it> Author: chemin Date: 2007-07-01 20:48:06 +0200 (Sun, 01 Jul 2007) New Revision: 902 Modified: trunk/grassaddons/gipe/i.eb.deltat/main.c trunk/grassaddons/gipe/i.eb.h_iter/main.c trunk/grassaddons/gipe/i.eb.rohair/roh_air.c trunk/grassaddons/gipe/menudata.py trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: Debugging/fixing Modified: trunk/grassaddons/gipe/i.eb.deltat/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.deltat/main.c 2007-07-01 13:54:37 UTC (rev 901) +++ trunk/grassaddons/gipe/i.eb.deltat/main.c 2007-07-01 18:48:06 UTC (rev 902) @@ -145,7 +145,7 @@ /****************************/ /* calculate delta T */ if(wim){ - d = -0.3225 * d_tempk + 91.743; + d = 0.3225 * d_tempk - 91.743; }else{ d = delta_t(d_tempk); } Modified: trunk/grassaddons/gipe/i.eb.h_iter/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.h_iter/main.c 2007-07-01 13:54:37 UTC (rev 901) +++ trunk/grassaddons/gipe/i.eb.h_iter/main.c 2007-07-01 18:48:06 UTC (rev 902) @@ -1,7 +1,7 @@ /**************************************************************************** * * MODULE: i.eb.h_iter - * AUTHOR(S): Yann Chemin - ychemin@gmail.com + * AUTHOR(S): Yann Chemin - yann.chemin@gmail.com * PURPOSE: Calculates sensible heat flux by SEBAL iteration * if your DeltaT (or eq. to make it from surf.temp) is validated. * ! Delta T will not be reassessed in the iterations ! @@ -9,13 +9,14 @@ * of surface temperature as used in his SEBAL model. * This has been seen in Pawan (2004). * - * COPYRIGHT: (C) 2002-2006 by the GRASS Development Team + * COPYRIGHT: (C) 2002-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. * - * CHANGELOG: 28 October: Added u2m input (wind speed at 2 meters height) + * CHANGELOG: 28 October 06: Added u2m input (wind speed at 2 meters height) + * 30 June 07: Debugging a Seg Fault * *****************************************************************************/ @@ -97,20 +98,19 @@ input2->answer =_("1004.16"); input3 = G_define_option() ; - input3->key =_("dtair"); + input3->key =_("tempk"); input3->type = TYPE_STRING; - input3->required = NO; + input3->required = YES; input3->gisprompt =_("old,cell,raster"); - input3->description=_("Name of the skin-air Surface temperature difference map ~[0.0-80.0]"); -// input3->answer =_("dtair"); + input3->description=_("Name of the surface skin temperature map [degrees Kelvin],if used with -s flag and affine coefs, it disables dtair input"); + input3->answer =_("tempk"); input4 = G_define_option() ; - input4->key =_("tempk"); + input4->key =_("dtair"); input4->type = TYPE_STRING; input4->required = NO; input4->gisprompt =_("old,cell,raster"); - input4->description=_("Name of the surface skin temperature map [degrees Kelvin],if used with -s flag and affine coefs, it disables dtair input"); - input4->answer =_("tempk"); + input4->description=_("Name of the skin-air Surface temperature difference map ~[0.0-80.0], required unless you use -s flag (then you must give a & b coefs below)"); input5 = G_define_option() ; input5->key =_("a"); @@ -179,10 +179,18 @@ rohair = input1->answer; cp = atof(input2->answer); - dtair = input3->answer; - tempk = input4->answer; - a = atof(input5->answer); - b = atof(input6->answer); + if(input3->answer){ + dtair = input3->answer; + } + if(input4->answer){ + tempk = input4->answer; + } + if(input5->answer){ + a = atof(input5->answer); + } + if(input6->answer){ + b = atof(input6->answer); + } disp = input7->answer; z0m = input8->answer; z0h = input9->answer; @@ -191,7 +199,18 @@ result = output1->answer; sebal = flag1->answer; verbose = (!flag2->answer); + /***************************************************/ + /* TEST FOR -s FLAG COEFS + * Return error if not proper flag coefs + * */ + /***************************************************/ + if (sebal&&!a&&!b){ + G_fatal_error(_("FATAL ERROR: -s Flag requires coefs a & b!")); + } else if (!sebal&&!dtair){ + G_fatal_error(_("FATAL ERROR: No -s Flag, use DeltaT map!")); + } + /***************************************************/ mapset = G_find_cell2(rohair, ""); if (mapset == NULL) { G_fatal_error(_("cell file [%s] not found"), rohair); @@ -293,8 +312,8 @@ DCELL d_u2m; if(verbose) G_percent(row,nrows,2); -// printf("row = %i/%i\n",row,nrows); - /* read soil input maps */ + /* printf("row = %i/%i\n",row,nrows);*/ + /* read input maps */ if(G_get_raster_row(infd_rohair,inrast_rohair,row,data_type_rohair)<0) G_fatal_error(_("Could not read from <%s>"),rohair); if(!sebal){ @@ -314,15 +333,85 @@ /*process the data */ for (col=0; col < ncols; col++) { - d_rohair = ((DCELL *) inrast_rohair)[col]; + switch(data_type_rohair){ + case CELL_TYPE: + d_rohair = (double) ((CELL *) inrast_rohair)[col]; + break; + case FCELL_TYPE: + d_rohair = (double) ((FCELL *) inrast_rohair)[col]; + break; + case DCELL_TYPE: + d_rohair = ((DCELL *) inrast_rohair)[col]; + break; + } if(!sebal){ - d_dtair = ((DCELL *) inrast_dtair)[col]; + switch(data_type_dtair){ + case CELL_TYPE: + d_dtair = (double) ((CELL *) inrast_dtair)[col]; + break; + case FCELL_TYPE: + d_dtair = (double) ((FCELL *) inrast_dtair)[col]; + break; + case DCELL_TYPE: + d_dtair = ((DCELL *) inrast_dtair)[col]; + break; + } } - d_tempk = ((DCELL *) inrast_tempk)[col]; - d_disp = ((DCELL *) inrast_disp)[col]; - d_z0m = ((DCELL *) inrast_z0m)[col]; - d_z0h = ((DCELL *) inrast_z0h)[col]; - d_u2m = ((DCELL *) inrast_u2m)[col]; + switch(data_type_tempk){ + case CELL_TYPE: + d_tempk = (double) ((CELL *) inrast_tempk)[col]; + break; + case FCELL_TYPE: + d_tempk = (double) ((FCELL *) inrast_tempk)[col]; + break; + case DCELL_TYPE: + d_tempk = ((DCELL *) inrast_tempk)[col]; + break; + } + switch(data_type_disp){ + case CELL_TYPE: + d_disp = (double) ((CELL *) inrast_disp)[col]; + break; + case FCELL_TYPE: + d_disp = (double) ((FCELL *) inrast_disp)[col]; + break; + case DCELL_TYPE: + d_disp = ((DCELL *) inrast_disp)[col]; + break; + } + switch(data_type_z0m){ + case CELL_TYPE: + d_z0m = (double) ((CELL *) inrast_z0m)[col]; + break; + case FCELL_TYPE: + d_z0m = (double) ((FCELL *) inrast_z0m)[col]; + break; + case DCELL_TYPE: + d_z0m = ((DCELL *) inrast_z0m)[col]; + break; + } + switch(data_type_z0h){ + case CELL_TYPE: + d_z0h = (double) ((CELL *) inrast_z0h)[col]; + break; + case FCELL_TYPE: + d_z0h = (double) ((FCELL *) inrast_z0h)[col]; + break; + case DCELL_TYPE: + d_z0h = ((DCELL *) inrast_z0h)[col]; + break; + } + switch(data_type_u2m){ + case CELL_TYPE: + d_u2m = (double) ((CELL *) inrast_u2m)[col]; + break; + case FCELL_TYPE: + d_u2m = (double) ((FCELL *) inrast_u2m)[col]; + break; + case DCELL_TYPE: + d_u2m = ((DCELL *) inrast_u2m)[col]; + break; + } if(G_is_d_null_value(&d_rohair)){ ((DCELL *) outrast)[col] = -999.99; }else if((!sebal)&&G_is_d_null_value(&d_dtair)){ @@ -340,16 +429,16 @@ }else { /************************************/ /* calculate sensible heat flux */ - if(sebal){//if -s flag then calculate Delta T from Coefs + if(sebal){/*if -s flag then calculate Delta T from Coefs*/ d_affine=a*d_tempk+b; - // Run iterations to find Rah + /* Run iterations to find Rah*/ d_rah=fixed_deltat(d_u2m,d_rohair,cp,d_affine,d_disp,d_z0m,d_z0h,d_tempk); - //Process h + /*Process h*/ d = h0(d_rohair,cp,d_rah,d_affine); - }else{// not -s flag then take delta T map input directly - // Run iterations to find Rah + }else{/* not -s flag then take delta T map input directly*/ + /* Run iterations to find Rah*/ d_rah=fixed_deltat(d_u2m,d_rohair,cp,d_dtair,d_disp,d_z0m,d_z0h,d_tempk); - //Process h + /*Process h*/ d = h0(d_rohair,cp,d_rah,d_dtair); } ((DCELL *) outrast)[col] = d; Modified: trunk/grassaddons/gipe/i.eb.rohair/roh_air.c =================================================================== --- trunk/grassaddons/gipe/i.eb.rohair/roh_air.c 2007-07-01 13:54:37 UTC (rev 901) +++ trunk/grassaddons/gipe/i.eb.rohair/roh_air.c 2007-07-01 18:48:06 UTC (rev 902) @@ -13,6 +13,12 @@ b = (( tempka - (0.00627 * dem )) / tempka ); result = 349.467 * pow( b , 5.26 ) / tempka ; - + + if (result > 1.5){ + result = -999.99; + } else if (result < 0.0){ + result = -999.99; + } + return result; } Modified: trunk/grassaddons/gipe/menudata.py =================================================================== --- trunk/grassaddons/gipe/menudata.py 2007-07-01 13:54:37 UTC (rev 901) +++ trunk/grassaddons/gipe/menudata.py 2007-07-01 18:48:06 UTC (rev 902) @@ -343,6 +343,7 @@ ("Net radiation", "net radiation", "self.RunMenuCmd", "i.eb.netrad"), ("","","", ""), ("Displacement height", "Displacement height", "self.RunMenuCmd", "i.eb.disp"), + ("Atmospheric Air Density", "Atmospheric Air Density", "self.RunMenuCmd", "i.eb.rohair"), ("","","", ""), ("Monin-Obukov Length", "Monin-Obukov Length", "self.RunMenuCmd", "i.eb.molength"), ("Psichrometric param. for heat", "psichrometric param. for heat", "self.RunMenuCmd", "i.eb.psi"), Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 13:54:37 UTC (rev 901) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 18:48:06 UTC (rev 902) @@ -87,6 +87,7 @@ char sys_19[1000],sys_20[1000],sys_21[1000],sys_22[1000]; char sys_23[1000],sys_24[1000],sys_25[1000],sys_26[1000]; char sys_27[1000],sys_28[1000],sys_29[1000],sys_30[1000]; + char sys_31[1000],sys_32[1000],sys_33[1000],sys_34[1000]; if(argc < 1){ usage(); @@ -537,7 +538,7 @@ /*Start Processing*/ system("echo \"#!/bin/bash\" > temp.txt"); system("echo \"\" >> temp.txt"); - system("echo \"#This is an auto-generated script by l7inread_ingrass().\n#It is created by a C code that extract useful information from the .met metadata file of Landsat 7\n#It runs several GRASS GIS modules to calculate (hopefully) automagically ET Potential\n\n#Q: I am bonehead, my script does not run because i am not running it from inside GRASS GIS\n#A: How many times we have to tell you that it will NOT work from outside GRASS GIS! (Actually, there might be a way :P, have to ask the dev-ML...) \" >> temp.txt"); + system("echo \"#This is an auto-generated script by l7inread_ingrass().\n#It is created by a C code that extract useful information from the .met metadata file of Landsat 7\n#It runs several GRASS GIS modules to calculate (hopefully) automagically ET Potential\n\n#Q: My script does not run because i am not running it from inside GRASS GIS\n#A: It will not work from outside GRASS GIS (Actually, there might be a way :P, have to ask the dev-ML...) \" >> temp.txt"); /*ungzip the L7 files*/ system("echo \"\" >> temp.txt"); system("echo \"#UNGZIP ALL LANDSAT BANDS\" >> temp.txt"); @@ -630,10 +631,10 @@ sprintf(sys_20,"echo \"i.emissivity ndvi=%s.ndvi emissivity=%s.e0 --overwrite\" >> temp.txt",basedate,basedate); system(sys_20); system("echo \"\" >> temp.txt"); - sprintf(sys_21,"echo \"i.eb.netrad albedo=%s.albedo ndvi=%s.ndvi tempk=%s.61 time=%s.time dtair=%s.delta emissivity=%s.e0 tsw=%s.tsw doy=%s.doy sunzangle=%s.sunza rnet=%s.rnet --overwrite\" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate); + sprintf(sys_21,"echo \"i.eb.netrad albedo=%s.albedo ndvi=%s.ndvi tempk=%s.61 time=%s.sath dtair=%s.delta emissivity=%s.e0 tsw=%s.tsw doy=%s.doy sunzangle=%s.sunza rnet=%s.rnet --overwrite\" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate); system(sys_21); system("echo \"\" >> temp.txt"); - sprintf(sys_22,"echo \"i.eb.g0 albedo=%s.albedo ndvi=%s.ndvi tempk=%s.61 rnet=%s.rnet time=%s.time g0=%s.g0 --overwrite\" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate); + sprintf(sys_22,"echo \"i.eb.g0 albedo=%s.albedo ndvi=%s.ndvi tempk=%s.61 rnet=%s.rnet time=%s.sath g0=%s.g0 --overwrite\" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate); system(sys_22); system("echo \"\" >> temp.txt"); sprintf(sys_23,"echo \"i.evapo.PT -z RNET=%s.rnetd G0=%s.g0 TEMPKA=%s.tempka PATM=%s.patm PT=1.26 output=%s.ETA_PT --overwrite\" >> temp.txt",basedate,basedate,basedate,basedate,basedate); @@ -658,9 +659,18 @@ sprintf(sys_27,"echo \"r.in.gdal -o input=SRTM_u03_p%sr%s.tif output=%s.dem title=SRTM_u03\" >> temp.txt",path,row,basedate); system(sys_27); system("echo \"\" >> temp.txt"); - sprintf(sys_28,"echo \"i.eb.rohair dem=%s.dem tempka=%s.tempka rohair=%s.rohair --overwrite\" >> temp.txt",basedate,basedate,basedate); + sprintf(sys_28,"echo \"r.colors map=%s.dem color=srtm\" >> temp.txt",basedate); system(sys_28); system("echo \"\" >> temp.txt"); + sprintf(sys_29,"echo \"i.eb.rohair dem=%s.dem tempka=%s.tempka rohair=%s.rohair --overwrite\" >> temp.txt",basedate,basedate,basedate); + system(sys_29); + system("echo \"\" >> temp.txt"); + sprintf(sys_30,"echo \"r.null map=%s.rohair setnull=-999.99\" >> temp.txt",basedate); + system(sys_30); + system("echo \"\" >> temp.txt"); + sprintf(sys_31,"echo \"i.eb.h_iter rohair=%s.rohair cp=1004.16 dtair=%s.delta tempk=%s.61 disp=%s.disp z0m=%s.z0m z0h=%s.z0h u2m=u2 h0=%s.h0 --overwrite \" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate); + system(sys_31); + system("echo \"\" >> temp.txt"); /*clean maps system("chmod +x temp.txt; cat temp.txt; echo \"Start GRASS Processing\n\" ; ./temp.txt"); */ From chemin at grass.itc.it Mon Jul 2 11:49:27 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Mon Jul 2 11:49:29 2007 Subject: [grass-addons] r903 - trunk/grassaddons/gipe/script_generator Message-ID: <200707020949.l629nRQ2030670@grass.itc.it> Author: chemin Date: 2007-07-02 11:49:23 +0200 (Mon, 02 Jul 2007) New Revision: 903 Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: Finishing automatic processing script for actual evapotranspiration of Landsat 7 Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-01 18:48:06 UTC (rev 902) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-02 09:49:23 UTC (rev 903) @@ -668,9 +668,15 @@ sprintf(sys_30,"echo \"r.null map=%s.rohair setnull=-999.99\" >> temp.txt",basedate); system(sys_30); system("echo \"\" >> temp.txt"); - sprintf(sys_31,"echo \"i.eb.h_iter rohair=%s.rohair cp=1004.16 dtair=%s.delta tempk=%s.61 disp=%s.disp z0m=%s.z0m z0h=%s.z0h u2m=u2 h0=%s.h0 --overwrite \" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate); + sprintf(sys_31,"echo \"i.eb.h_iter rohair=%s.rohair cp=1004.16 dtair=%s.delta tempk=%s.61 disp=%s.disp z0m=%s.z0m z0h=%s.z0h u2m=u2 h0=%s.h0 --overwrite; r.null map=%s.h0 setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate); system(sys_31); system("echo \"\" >> temp.txt"); + sprintf(sys_32,"echo \"i.eb.evapfr -m rnet=%s.rnet g0=%s.g0 h0=%s.h0 evapfr=%s.evapfr theta=%s.theta --overwrite; r.null map=%s.evapfr setnull=-999.99 ; r.null map=%s.theta setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate); + system(sys_32); + system("echo \"\" >> temp.txt"); + sprintf(sys_33,"echo \"i.eb.eta rnetday=%s.rnetd evapfr=%s.evapfr tempk=%s.61 eta=%s.eta --overwrite; r.null map=%s.eta setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate); + system(sys_33); + system("echo \"\" >> temp.txt"); /*clean maps system("chmod +x temp.txt; cat temp.txt; echo \"Start GRASS Processing\n\" ; ./temp.txt"); */ From chemin at grass.itc.it Mon Jul 2 11:55:54 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Mon Jul 2 11:55:56 2007 Subject: [grass-addons] r904 - trunk/grassaddons/gipe/i.eb.h_iter Message-ID: <200707020955.l629tshE031530@grass.itc.it> Author: chemin Date: 2007-07-02 11:55:48 +0200 (Mon, 02 Jul 2007) New Revision: 904 Modified: trunk/grassaddons/gipe/i.eb.h_iter/fixed_deltat.c trunk/grassaddons/gipe/i.eb.h_iter/main.c Log: Bug fixing Modified: trunk/grassaddons/gipe/i.eb.h_iter/fixed_deltat.c =================================================================== --- trunk/grassaddons/gipe/i.eb.h_iter/fixed_deltat.c 2007-07-02 09:49:23 UTC (rev 903) +++ trunk/grassaddons/gipe/i.eb.h_iter/fixed_deltat.c 2007-07-02 09:55:48 UTC (rev 904) @@ -22,10 +22,7 @@ for(i=0;i<10;i++){ ustar = 0.41*ublend/(log((100-disp)/z0m)-psim); rah = (log((2-disp)/z0h)-psih)/(0.41*ustar); - h_in = roh_air*cp*dt/rah; - if(h_in < 0.0){ - h_in = 0.01; - } + h_in = roh_air * cp * dt / rah; length= -roh_air*cp*pow(ustar,3)*tempk/(0.41*9.81*h_in); xm = pow(1.0-16.0*((100-disp)/length),0.25); xh = pow(1.0-16.0*((2-disp)/length),0.25); Modified: trunk/grassaddons/gipe/i.eb.h_iter/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.h_iter/main.c 2007-07-02 09:49:23 UTC (rev 903) +++ trunk/grassaddons/gipe/i.eb.h_iter/main.c 2007-07-02 09:55:48 UTC (rev 904) @@ -180,10 +180,10 @@ rohair = input1->answer; cp = atof(input2->answer); if(input3->answer){ - dtair = input3->answer; + tempk = input3->answer; } if(input4->answer){ - tempk = input4->answer; + dtair = input4->answer; } if(input5->answer){ a = atof(input5->answer); From chemin at grass.itc.it Mon Jul 2 14:13:43 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Mon Jul 2 14:13:45 2007 Subject: [grass-addons] r905 - trunk/grassaddons/gipe/script_generator Message-ID: <200707021213.l62CDhMb001869@grass.itc.it> Author: chemin Date: 2007-07-02 14:13:39 +0200 (Mon, 02 Jul 2007) New Revision: 905 Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: Bug fixing Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-02 09:55:48 UTC (rev 904) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-02 12:13:39 UTC (rev 905) @@ -583,7 +583,7 @@ /*Calculate ETPOT (and Rnetd for future ETa calculations)*/ system("echo \"\" >> temp.txt"); system("echo \"#ETPOT\" >> temp.txt"); - snprintf(sys_5,1000,"echo \"i.evapo.potrad -r albedo=%s.albedo tempk=%s.61 lat=%s.latitude doy=%s.doy tsw=%s.tsw etpot=%s.etpot rnetd=%s.rnetd --overwrite\" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate); + snprintf(sys_5,1000,"echo \"i.evapo.potrad -r albedo=%s.albedo tempk=%s.61 lat=%s.latitude doy=%s.doy tsw=%s.tsw etpot=%s.etpot rnetd=%s.rnetd --overwrite ; r.null map=%s.rnetd setnull=-999.99 \" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate); system(sys_5); snprintf(sys_7,1000,"echo \"r.colors map=%s.etpot color=grey ; r.null map=%s.etpot setnull=-999.99\" >> temp.txt", basedate, basedate); system(sys_7); @@ -626,7 +626,7 @@ /*Calculate ET Potential after Prestley and Taylor*/ system("echo \"#PRESTLEY AND TAYLOR ET POTENTIAL\" >> temp.txt"); system("echo \"\" >> temp.txt"); - sprintf(sys_19,"echo \"r.mapcalc %s.patm=1010.0\" >> temp.txt",basedate); + sprintf(sys_19,"echo \"r.mapcalc %s.patm=1010.0; r.mapcalc %s.sunza=90.0-%s.phi\" >> temp.txt",basedate,basedate,basedate); system(sys_19); sprintf(sys_20,"echo \"i.emissivity ndvi=%s.ndvi emissivity=%s.e0 --overwrite\" >> temp.txt",basedate,basedate); system(sys_20); @@ -671,10 +671,10 @@ sprintf(sys_31,"echo \"i.eb.h_iter rohair=%s.rohair cp=1004.16 dtair=%s.delta tempk=%s.61 disp=%s.disp z0m=%s.z0m z0h=%s.z0h u2m=u2 h0=%s.h0 --overwrite; r.null map=%s.h0 setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate,basedate); system(sys_31); system("echo \"\" >> temp.txt"); - sprintf(sys_32,"echo \"i.eb.evapfr -m rnet=%s.rnet g0=%s.g0 h0=%s.h0 evapfr=%s.evapfr theta=%s.theta --overwrite; r.null map=%s.evapfr setnull=-999.99 ; r.null map=%s.theta setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate); + sprintf(sys_32,"echo \"i.eb.evapfr -m rnet=%s.rnet g0=%s.g0 h0=%s.h0 evapfr=%s.evapfr theta=%s.theta --overwrite ; r.null map=%s.evapfr setnull=-999.99 ; r.null map=%s.theta setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate,basedate,basedate); system(sys_32); system("echo \"\" >> temp.txt"); - sprintf(sys_33,"echo \"i.eb.eta rnetday=%s.rnetd evapfr=%s.evapfr tempk=%s.61 eta=%s.eta --overwrite; r.null map=%s.eta setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate); + sprintf(sys_33,"echo \"i.eb.eta rnetday=%s.rnetd evapfr=%s.evapfr tempk=%s.61 eta=%s.eta --overwrite ; r.null map=%s.eta setnull=-999.99 \" >> temp.txt",basedate,basedate,basedate,basedate,basedate); system(sys_33); system("echo \"\" >> temp.txt"); /*clean maps From chemin at grass.itc.it Mon Jul 2 14:40:44 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Mon Jul 2 14:40:46 2007 Subject: [grass-addons] r906 - in trunk/grassaddons/gipe: i.dn2full.l7 script_generator Message-ID: <200707021240.l62CeifX001980@grass.itc.it> Author: chemin Date: 2007-07-02 14:40:39 +0200 (Mon, 02 Jul 2007) New Revision: 906 Modified: trunk/grassaddons/gipe/i.dn2full.l7/main.c trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: Debugging Modified: trunk/grassaddons/gipe/i.dn2full.l7/main.c =================================================================== --- trunk/grassaddons/gipe/i.dn2full.l7/main.c 2007-07-02 12:13:39 UTC (rev 905) +++ trunk/grassaddons/gipe/i.dn2full.l7/main.c 2007-07-02 12:40:39 UTC (rev 906) @@ -429,7 +429,7 @@ dout[i]=dn2rad_landsat7(lmin[i],lmax[i],qcalmax[i],qcalmin[i],d[i]); if(i==5||i==6){//if band 61/62, process brightness temperature if(dout[i]<=0.0){ - dout[i]=-999.99; + dout[i]=-999.990; }else{ dout[i]=tempk_landsat7(dout[i]); } Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-02 12:13:39 UTC (rev 905) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-02 12:40:39 UTC (rev 906) @@ -565,7 +565,7 @@ /*calibrate DN to TOA Reflectance*/ system("echo \"\" >> temp.txt"); system("echo \"#DN2REF\" >> temp.txt"); - snprintf(sys_1,1000,"echo \"i.dn2full.l7 metfile=%s output=%s --overwrite\" >> temp.txt",metfName,basedate); + snprintf(sys_1,1000,"echo \"i.dn2full.l7 metfile=%s output=%s --overwrite ; r.null map=%s.61 setnull=-999.99 ; r.null map=%s.62 setnull=-999.99 \" >> temp.txt",metfName,basedate,basedate,basedate); system(sys_1); /*Calculate Albedo*/ system("echo \"\" >> temp.txt"); @@ -583,7 +583,7 @@ /*Calculate ETPOT (and Rnetd for future ETa calculations)*/ system("echo \"\" >> temp.txt"); system("echo \"#ETPOT\" >> temp.txt"); - snprintf(sys_5,1000,"echo \"i.evapo.potrad -r albedo=%s.albedo tempk=%s.61 lat=%s.latitude doy=%s.doy tsw=%s.tsw etpot=%s.etpot rnetd=%s.rnetd --overwrite ; r.null map=%s.rnetd setnull=-999.99 \" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate); + snprintf(sys_5,1000,"echo \"i.evapo.potrad -r albedo=%s.albedo tempk=%s.61 lat=%s.latitude doy=%s.doy tsw=%s.tsw etpot=%s.etpot rnetd=%s.rnetd --overwrite ; r.null map=%s.rnetd setnull=-999.99 \" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate, basedate); system(sys_5); snprintf(sys_7,1000,"echo \"r.colors map=%s.etpot color=grey ; r.null map=%s.etpot setnull=-999.99\" >> temp.txt", basedate, basedate); system(sys_7); From chemin at grass.itc.it Mon Jul 2 15:06:14 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Mon Jul 2 15:06:19 2007 Subject: [grass-addons] r907 - in trunk/grassaddons/gipe: i.eb.eta i.eb.evapfr Message-ID: <200707021306.l62D6EkM002101@grass.itc.it> Author: chemin Date: 2007-07-02 15:06:04 +0200 (Mon, 02 Jul 2007) New Revision: 907 Modified: trunk/grassaddons/gipe/i.eb.eta/eta.c trunk/grassaddons/gipe/i.eb.eta/main.c trunk/grassaddons/gipe/i.eb.evapfr/main.c Log: Debugging Modified: trunk/grassaddons/gipe/i.eb.eta/eta.c =================================================================== --- trunk/grassaddons/gipe/i.eb.eta/eta.c 2007-07-02 12:40:39 UTC (rev 906) +++ trunk/grassaddons/gipe/i.eb.eta/eta.c 2007-07-02 13:06:04 UTC (rev 907) @@ -3,10 +3,13 @@ double et_a(double r_net_day, double evap_fr, double tempk) { - double result; + double latent, t_celsius, result; + + t_celsius = tempk - 273.15 ; + latent = 86400/((2.501-0.002361*t_celsius)*pow(10,6)); + + result = r_net_day * evap_fr * latent ; - result = (r_net_day * evap_fr) * 86400/((2.501-0.002361*(tempk-273.15))*pow(10,6)); - return result; } Modified: trunk/grassaddons/gipe/i.eb.eta/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.eta/main.c 2007-07-02 12:40:39 UTC (rev 906) +++ trunk/grassaddons/gipe/i.eb.eta/main.c 2007-07-02 13:06:04 UTC (rev 907) @@ -1,11 +1,11 @@ /**************************************************************************** * * MODULE: i.eb.eta - * AUTHOR(S): Yann Chemin - ychemin@gmail.com + * AUTHOR(S): Yann Chemin - yann.chemin@gmail.com * PURPOSE: Calculates the actual evapotranspiration for diurnal period * as seen in Bastiaanssen (1995) * - * COPYRIGHT: (C) 2002-2006 by the GRASS Development Team + * COPYRIGHT: (C) 2002-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 @@ -49,6 +49,7 @@ void *inrast_rnetday, *inrast_evapfr, *inrast_tempk; unsigned char *outrast1; + RASTER_MAP_TYPE data_type_output DCELL_TYPE; RASTER_MAP_TYPE data_type_rnetday; RASTER_MAP_TYPE data_type_evapfr; RASTER_MAP_TYPE data_type_tempk; @@ -156,8 +157,7 @@ DCELL d_tempk; if(verbose) G_percent(row,nrows,2); -// printf("row = %i/%i\n",row,nrows); - /* read soil input maps */ + /* read input maps */ if(G_get_raster_row(infd_rnetday,inrast_rnetday,row,data_type_rnetday)<0) G_fatal_error(_("Could not read from <%s>"),rnetday); if(G_get_raster_row(infd_evapfr,inrast_evapfr,row,data_type_evapfr)<0) @@ -167,13 +167,39 @@ /*process the data */ for (col=0; col < ncols; col++) { - // printf("col=%i/%i ",col,ncols); - d_rnetday = ((DCELL *) inrast_rnetday)[col]; - // printf("rnetday = %5.3f", d_rnetday); - d_evapfr = ((DCELL *) inrast_evapfr)[col]; - // printf(" evapfr = %5.3f", d_evapfr); - d_tempk = ((DCELL *) inrast_tempk)[col]; - // printf(" tempk = %5.3f", d_tempk); + switch(data_type_rnetday){ + case CELL_TYPE: + d_rnetday = (double) ((CELL *) inrast_rnetday)[col]; + break; + case FCELL_TYPE: + d_rnetday = (double) ((FCELL *) inrast_rnetday)[col]; + break; + case DCELL_TYPE: + d_rnetday = ((DCELL *) inrast_rnetday)[col]; + break; + } + switch(data_type_evapfr){ + case CELL_TYPE: + d_evapfr = (double) ((CELL *) inrast_evapfr)[col]; + break; + case FCELL_TYPE: + d_evapfr = (double) ((FCELL *) inrast_evapfr)[col]; + break; + case DCELL_TYPE: + d_evapfr = ((DCELL *) inrast_evapfr)[col]; + break; + } + switch(data_type_tempk){ + case CELL_TYPE: + d_tempk = (double) ((CELL *) inrast_tempk)[col]; + break; + case FCELL_TYPE: + d_tempk = (double) ((FCELL *) inrast_tempk)[col]; + break; + case DCELL_TYPE: + d_tempk = ((DCELL *) inrast_tempk)[col]; + break; + } if(G_is_d_null_value(&d_rnetday)){ ((DCELL *) outrast1)[col] = -999.99; }else if(G_is_d_null_value(&d_evapfr)){ @@ -184,15 +210,10 @@ /************************************/ /* calculate soil heat flux */ d = et_a(d_rnetday,d_evapfr,d_tempk); - // printf(" || d=%5.3f",d); ((DCELL *) outrast1)[col] = d; - // printf(" -> %5.3f\n",d); } - // if(row==50){ - // exit(EXIT_SUCCESS); - // } } - if (G_put_raster_row (outfd1, outrast1, data_type_tempk) < 0) + if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) G_fatal_error(_("Cannot write to output raster file")); } Modified: trunk/grassaddons/gipe/i.eb.evapfr/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.evapfr/main.c 2007-07-02 12:40:39 UTC (rev 906) +++ trunk/grassaddons/gipe/i.eb.evapfr/main.c 2007-07-02 13:06:04 UTC (rev 907) @@ -192,13 +192,39 @@ /*process the data */ for (col=0; col < ncols; col++) { - // printf("col=%i/%i ",col,ncols); - d_rnet = ((DCELL *) inrast_rnet)[col]; - // printf("rnet = %5.3f", d_rnet); - d_g0 = ((DCELL *) inrast_g0)[col]; - // printf(" g0 = %5.3f", d_g0); - d_h0 = ((DCELL *) inrast_h0)[col]; - // printf(" h0 = %5.3f", d_h0); + switch(data_type_rnet){ + case CELL_TYPE: + d_rnet = (double) ((CELL *) inrast_rnet)[col]; + break; + case FCELL_TYPE: + d_rnet = (double) ((FCELL *) inrast_rnet)[col]; + break; + case DCELL_TYPE: + d_rnet = ((DCELL *) inrast_rnet)[col]; + break; + } + switch(data_type_g0){ + case CELL_TYPE: + d_g0 = (double) ((CELL *) inrast_g0)[col]; + break; + case FCELL_TYPE: + d_g0 = (double) ((FCELL *) inrast_g0)[col]; + break; + case DCELL_TYPE: + d_g0 = ((DCELL *) inrast_g0)[col]; + break; + } + switch(data_type_h0){ + case CELL_TYPE: + d_h0 = (double) ((CELL *) inrast_h0)[col]; + break; + case FCELL_TYPE: + d_h0 = (double) ((FCELL *) inrast_h0)[col]; + break; + case DCELL_TYPE: + d_h0 = ((DCELL *) inrast_h0)[col]; + break; + } if(G_is_d_null_value(&d_rnet)){ ((DCELL *) outrast1)[col] = -999.99; if(makin){ From chemin at grass.itc.it Mon Jul 2 15:15:42 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Mon Jul 2 15:15:43 2007 Subject: [grass-addons] r908 - in trunk/grassaddons/gipe: i.albedo i.eb.eta i.eb.evapfr Message-ID: <200707021315.l62DFgY7002984@grass.itc.it> Author: chemin Date: 2007-07-02 15:15:34 +0200 (Mon, 02 Jul 2007) New Revision: 908 Modified: trunk/grassaddons/gipe/i.albedo/main.c trunk/grassaddons/gipe/i.eb.eta/main.c trunk/grassaddons/gipe/i.eb.evapfr/main.c Log: Debugging Modified: trunk/grassaddons/gipe/i.albedo/main.c =================================================================== --- trunk/grassaddons/gipe/i.albedo/main.c 2007-07-02 13:06:04 UTC (rev 907) +++ trunk/grassaddons/gipe/i.albedo/main.c 2007-07-02 13:15:34 UTC (rev 908) @@ -208,7 +208,7 @@ nrows = G_window_rows(); ncols = G_window_cols(); // printf("Passed Stage 3\n"); - out_data_type=FCELL_TYPE; + out_data_type=DCELL_TYPE; outrast = G_allocate_raster_buf(out_data_type); // printf("Passed Stage 4\n"); Modified: trunk/grassaddons/gipe/i.eb.eta/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.eta/main.c 2007-07-02 13:06:04 UTC (rev 907) +++ trunk/grassaddons/gipe/i.eb.eta/main.c 2007-07-02 13:15:34 UTC (rev 908) @@ -49,7 +49,7 @@ void *inrast_rnetday, *inrast_evapfr, *inrast_tempk; unsigned char *outrast1; - RASTER_MAP_TYPE data_type_output DCELL_TYPE; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; RASTER_MAP_TYPE data_type_rnetday; RASTER_MAP_TYPE data_type_evapfr; RASTER_MAP_TYPE data_type_tempk; @@ -144,9 +144,9 @@ G_debug(3, "number of rows %d",cellhd.rows); nrows = G_window_rows(); ncols = G_window_cols(); - outrast1 = G_allocate_raster_buf(data_type_tempk); + outrast1 = G_allocate_raster_buf(data_type_output); /* Create New raster files */ - if ( (outfd1 = G_open_raster_new (result1,data_type_tempk)) < 0) + if ( (outfd1 = G_open_raster_new (result1,data_type_output)) < 0) G_fatal_error(_("Could not open <%s>"),result1); /* Process pixels */ for (row = 0; row < nrows; row++) Modified: trunk/grassaddons/gipe/i.eb.evapfr/main.c =================================================================== --- trunk/grassaddons/gipe/i.eb.evapfr/main.c 2007-07-02 13:06:04 UTC (rev 907) +++ trunk/grassaddons/gipe/i.eb.evapfr/main.c 2007-07-02 13:15:34 UTC (rev 908) @@ -52,6 +52,7 @@ void *inrast_rnet, *inrast_g0, *inrast_h0; unsigned char *outrast1, *outrast2; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; RASTER_MAP_TYPE data_type_rnet; RASTER_MAP_TYPE data_type_g0; RASTER_MAP_TYPE data_type_h0; @@ -161,15 +162,15 @@ G_debug(3, "number of rows %d",cellhd.rows); nrows = G_window_rows(); ncols = G_window_cols(); - outrast1 = G_allocate_raster_buf(data_type_h0); + outrast1 = G_allocate_raster_buf(data_type_output); if(makin){ - outrast2 = G_allocate_raster_buf(data_type_h0); + outrast2 = G_allocate_raster_buf(data_type_output); } /* Create New raster files */ - if ( (outfd1 = G_open_raster_new (result1,data_type_h0)) < 0) + if ( (outfd1 = G_open_raster_new (result1,data_type_output)) < 0) G_fatal_error(_("Could not open <%s>"),result1); if(makin){ - if ( (outfd2 = G_open_raster_new (result2,data_type_h0)) < 0) + if ( (outfd2 = G_open_raster_new (result2,data_type_output)) < 0) G_fatal_error(_("Could not open <%s>"),result2); } /* Process pixels */ @@ -256,10 +257,10 @@ // exit(EXIT_SUCCESS); // } } - if (G_put_raster_row (outfd1, outrast1, data_type_h0) < 0) + if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) G_fatal_error(_("Cannot write to output raster file")); if(makin){ - if (G_put_raster_row (outfd2, outrast2, data_type_h0) < 0) + if (G_put_raster_row (outfd2, outrast2, data_type_output) < 0) G_fatal_error(_("Cannot write to output raster file")); } } From neteler at grass.itc.it Mon Jul 2 18:04:30 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Mon Jul 2 18:04:33 2007 Subject: [grass-addons] r909 - in trunk/grassaddons: . i.landsat.toar Message-ID: <200707021604.l62G4U7Y005866@grass.itc.it> Author: neteler Date: 2007-07-02 18:04:30 +0200 (Mon, 02 Jul 2007) New Revision: 909 Added: trunk/grassaddons/i.landsat.toar/ trunk/grassaddons/i.landsat.toar/Makefile trunk/grassaddons/i.landsat.toar/description.html trunk/grassaddons/i.landsat.toar/earth_sun.c trunk/grassaddons/i.landsat.toar/earth_sun.h trunk/grassaddons/i.landsat.toar/landsat.c trunk/grassaddons/i.landsat.toar/landsat.h trunk/grassaddons/i.landsat.toar/landsat_set.c trunk/grassaddons/i.landsat.toar/local_proto.h trunk/grassaddons/i.landsat.toar/main.c Log: E. Jorge Tizado, Spain: convert LANDSAT DNs to at-radiance Added: trunk/grassaddons/i.landsat.toar/Makefile =================================================================== --- trunk/grassaddons/i.landsat.toar/Makefile (rev 0) +++ trunk/grassaddons/i.landsat.toar/Makefile 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,10 @@ +MODULE_TOPDIR = ../.. + +PGM = i.landsat.toar + +LIBES = $(GISLIB) +DEPENDENCIES = $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +default: cmd Added: trunk/grassaddons/i.landsat.toar/description.html =================================================================== --- trunk/grassaddons/i.landsat.toar/description.html (rev 0) +++ trunk/grassaddons/i.landsat.toar/description.html 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,87 @@ +

DESCRIPTION

+ +i.landsat.toar is to transform digital number (DN) of +Landsat-4/5 TM or Landsat 7 ETM+ product to reflectance at top of +atmosphere (band 1, 2, 3, 4, 5, 7 or 8) and temperature (band 6). + +

For Landsat-4/5 TM need date and solar.
For Landsat-7 ETM+ +either metfile or date, solar, and gain

+ +

For flag -f, make distinction between acquisition and processing dates.

+ +

NOTES

+ +

The standard geometric and radiometric correction results in +digital number (DN) images. To further standardize the impact of +illumination geometry, the DN images are converted first to +at-satellite radiance and then to at-satellite reflectance.
+The thermal band is first converted from DN to at-satellite radiance, +and then to effective at-satellite temperature in Celsius (O Kelvin = +-273.15 Celsius).

+ +

In verbose mode, the program write the parameters used in +transformation to at-satellite radiance, to at-satellite reflectance +and constant to remove the atmospheric effect using DOS +method.

+ +To remove atmospheric effect, use + +

+r.mapcalc 'refc = if(ref < (a*dp+b), b, ref-a*dp)'
+
+being refc the reflectance corrected without atmospheric +effect, ref the at-satellite reflectance, and dp the +dark pixel in DN scale.

+ + +

+Other equations are:
+

    +
  • gain = (Lmax - Lmin) / (QCALmax - QCALmin)
  • +
  • bias = Lmin - gain * QCALmin
  • +
  • radiance = gain * DN + bias
  • +
  • cte_ref = (PI * d_earth_sun * d_earth_sun) / (ESUN * cos(90 - sun_elevation)
  • +
  • reflectance = cte_ref * radiance
  • +
  • a = cte_ref * gain
  • +
  • b = cte_ref * bias
  • +
+

+ +

More details on how to convert DN to at-satellite reflectance are +provided by Markham and Barker (1986), Irish (2000), and Huang et +al. (2002).

+ +

EXAMPLES

+ +

Transfor digital numbers from band raster 203_30.1, 203_30.2, +... to reflectance at top-of-atmosphere in output files 203_30.1r, +203_30.2r, ...

+ +
+i.landsat.toar band=203_30 met=p203r030_7x20010620.met
+
+ +

REFERENCES

+
    +
  1. http://landcover.usgs.gov/pdf/image_preprocessing.pdf
  2. +
  3. Gyanesh Chander (SAIC/EDC/USGS) and Brian Markham + (LPSO/GSFC/NASA): Revised L5 TM Radiometric Calibration + Procedures and Postcalibration Dynamic Ranges
  4. + +
+ + +

SEE ALSO

+ + +r.mapcalc
+r.in.gdal
+
+ + +

AUTHOR

+ +E. Jorge Tizado, University of León, Spain (ejtizado ono com)
+ +

+Last changed: $Date: 2006/11/17 00:00:00 $ Added: trunk/grassaddons/i.landsat.toar/earth_sun.c =================================================================== --- trunk/grassaddons/i.landsat.toar/earth_sun.c (rev 0) +++ trunk/grassaddons/i.landsat.toar/earth_sun.c 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,1101 @@ +/* + * Modified from LIBNOVA-0.12 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Some functions in this file use the VSOP87 solution by + * Messrs. Bretagnon and Francou. + * + * Copyright (C) 2000 - 2005 Liam Girdwood + * Modified to GRASS (C) 2006 E. Jorge Tizado + */ + +#include +#include +#include +#include + +#include "earth_sun.h" + +#define RADIUS_R0 523 +#define RADIUS_R1 290 +#define RADIUS_R2 134 +#define RADIUS_R3 20 +#define RADIUS_R4 9 +#define RADIUS_R5 2 + +static const struct ln_vsop earth_radius_r0[RADIUS_R0] = { + {1.00013988784, 0.00000000000, 0.00000000000}, + {0.01670699632, 3.09846350258, 6283.07584999140}, + {0.00013956024, 3.05524609456, 12566.15169998280}, + {0.00003083720, 5.19846674381, 77713.77146812050}, + {0.00001628463, 1.17387558054, 5753.38488489680}, + {0.00001575572, 2.84685214877, 7860.41939243920}, + {0.00000924799, 5.45292236722, 11506.76976979360}, + {0.00000542439, 4.56409151453, 3930.20969621960}, + {0.00000472110, 3.66100022149, 5884.92684658320}, + {0.00000328780, 5.89983686142, 5223.69391980220}, + {0.00000345969, 0.96368627272, 5507.55323866740}, + {0.00000306784, 0.29867139512, 5573.14280143310}, + {0.00000174844, 3.01193636733, 18849.22754997420}, + {0.00000243181, 4.27349530790, 11790.62908865880}, + {0.00000211836, 5.84714461348, 1577.34354244780}, + {0.00000185740, 5.02199710705, 10977.07880469900}, + {0.00000109835, 5.05510635860, 5486.77784317500}, + {0.00000098316, 0.88681311278, 6069.77675455340}, + {0.00000086500, 5.68956418946, 15720.83878487840}, + {0.00000085831, 1.27079125277, 161000.68573767410}, + {0.00000062917, 0.92177053978, 529.69096509460}, + {0.00000057056, 2.01374292245, 83996.84731811189}, + {0.00000064908, 0.27251341435, 17260.15465469040}, + {0.00000049384, 3.24501240359, 2544.31441988340}, + {0.00000055736, 5.24159799170, 71430.69561812909}, + {0.00000042520, 6.01110257982, 6275.96230299060}, + {0.00000046966, 2.57799853213, 775.52261132400}, + {0.00000038963, 5.36063832897, 4694.00295470760}, + {0.00000044666, 5.53715663816, 9437.76293488700}, + {0.00000035661, 1.67447135798, 12036.46073488820}, + {0.00000031922, 0.18368299942, 5088.62883976680}, + {0.00000031846, 1.77775642078, 398.14900340820}, + {0.00000033193, 0.24370221704, 7084.89678111520}, + {0.00000038245, 2.39255343973, 8827.39026987480}, + {0.00000028468, 1.21344887533, 6286.59896834040}, + {0.00000037486, 0.82961281844, 19651.04848109800}, + {0.00000036957, 4.90107587287, 12139.55350910680}, + {0.00000034537, 1.84270693281, 2942.46342329160}, + {0.00000026275, 4.58896863104, 10447.38783960440}, + {0.00000024596, 3.78660838036, 8429.24126646660}, + {0.00000023587, 0.26866098169, 796.29800681640}, + {0.00000027795, 1.89934427832, 6279.55273164240}, + {0.00000023927, 4.99598548145, 5856.47765911540}, + {0.00000020345, 4.65282190725, 2146.16541647520}, + {0.00000023287, 2.80783632869, 14143.49524243060}, + {0.00000022099, 1.95002636847, 3154.68708489560}, + {0.00000019509, 5.38233922479, 2352.86615377180}, + {0.00000017958, 0.19871369960, 6812.76681508600}, + {0.00000017178, 4.43322156854, 10213.28554621100}, + {0.00000016190, 5.23159323213, 17789.84561978500}, + {0.00000017315, 6.15224075188, 16730.46368959580}, + {0.00000013814, 5.18962074032, 8031.09226305840}, + {0.00000018834, 0.67280058021, 149854.40013480789}, + {0.00000018330, 2.25348717053, 23581.25817731760}, + {0.00000013639, 3.68511810757, 4705.73230754360}, + {0.00000013142, 0.65267698994, 13367.97263110660}, + {0.00000010414, 4.33285688501, 11769.85369316640}, + {0.00000009978, 4.20126336356, 6309.37416979120}, + {0.00000010170, 1.59366684542, 4690.47983635860}, + {0.00000007564, 2.62560597391, 6256.77753019160}, + {0.00000009654, 3.67583728703, 27511.46787353720}, + {0.00000006743, 0.56269927047, 3340.61242669980}, + {0.00000008743, 6.06359123461, 1748.01641306700}, + {0.00000007786, 3.67371235367, 12168.00269657460}, + {0.00000006633, 5.66149277789, 11371.70468975820}, + {0.00000007712, 0.31242577788, 7632.94325965020}, + {0.00000006586, 3.13580054586, 801.82093112380}, + {0.00000007460, 5.64758066660, 11926.25441366880}, + {0.00000006933, 2.92384586372, 6681.22485339960}, + {0.00000006805, 1.42327153767, 23013.53953958720}, + {0.00000006118, 5.13395999022, 1194.44701022460}, + {0.00000006477, 2.64986648493, 19804.82729158280}, + {0.00000005233, 4.62432817299, 6438.49624942560}, + {0.00000006147, 3.02863936662, 233141.31440436149}, + {0.00000004608, 1.72194702724, 7234.79425624200}, + {0.00000004221, 1.55697533726, 7238.67559160000}, + {0.00000005310, 2.40821524293, 11499.65622279280}, + {0.00000005128, 5.32398965690, 11513.88331679440}, + {0.00000004770, 0.25554311730, 11856.21865142450}, + {0.00000005519, 2.09089153789, 17298.18232732620}, + {0.00000005625, 4.34052903053, 90955.55169449610}, + {0.00000004578, 4.46569641570, 5746.27133789600}, + {0.00000003788, 4.90728294810, 4164.31198961300}, + {0.00000005337, 5.09957905103, 31441.67756975680}, + {0.00000003967, 1.20054555175, 1349.86740965880}, + {0.00000004005, 3.02853885902, 1059.38193018920}, + {0.00000003480, 0.76066308841, 10973.55568635000}, + {0.00000004232, 1.05485713117, 5760.49843189760}, + {0.00000004582, 3.76570026763, 6386.16862421000}, + {0.00000003335, 3.13829943354, 6836.64525283380}, + {0.00000003420, 3.00043974511, 4292.33083295040}, + {0.00000003595, 5.70703236079, 5643.17856367740}, + {0.00000003236, 4.16387400645, 9917.69687450980}, + {0.00000004154, 2.59940749519, 7058.59846131540}, + {0.00000003362, 4.54577164994, 4732.03062734340}, + {0.00000002978, 1.30561268820, 6283.14316029419}, + {0.00000002765, 0.51311975671, 26.29831979980}, + {0.00000002807, 5.66230537649, 8635.94200376320}, + {0.00000002927, 5.73787834080, 16200.77272450120}, + {0.00000003167, 1.69181759900, 11015.10647733480}, + {0.00000002598, 2.96244118358, 25132.30339996560}, + {0.00000003519, 3.62639325753, 244287.60000722769}, + {0.00000002676, 4.20727719487, 18073.70493865020}, + {0.00000002978, 1.74971565805, 6283.00853968860}, + {0.00000002287, 1.06976449088, 14314.16811304980}, + {0.00000002863, 5.92838917309, 14712.31711645800}, + {0.00000003071, 0.23793217000, 35371.88726597640}, + {0.00000002656, 0.89959301615, 12352.85260454480}, + {0.00000002415, 2.79975176800, 709.93304855830}, + {0.00000002811, 3.51513864541, 21228.39202354580}, + {0.00000001977, 2.61358297551, 951.71840625060}, + {0.00000002548, 2.47684686575, 6208.29425142410}, + {0.00000001999, 0.56090396506, 7079.37385680780}, + {0.00000002305, 1.05376463592, 22483.84857449259}, + {0.00000001855, 2.86093570752, 5216.58037280140}, + {0.00000002157, 1.31395211105, 154717.60988768269}, + {0.00000001970, 4.36931551625, 167283.76158766549}, + {0.00000001754, 2.14452400686, 6290.18939699220}, + {0.00000001628, 5.85704450617, 10984.19235169980}, + {0.00000002154, 6.03828353794, 10873.98603048040}, + {0.00000001714, 3.70158195222, 1592.59601363280}, + {0.00000001541, 6.21599512982, 23543.23050468179}, + {0.00000001602, 1.99860679677, 10969.96525769820}, + {0.00000001712, 1.34295218697, 3128.38876509580}, + {0.00000001647, 5.54948299069, 6496.37494542940}, + {0.00000001495, 5.43980459648, 155.42039943420}, + {0.00000001827, 5.91227480351, 3738.76143010800}, + {0.00000001726, 2.16765465036, 10575.40668294180}, + {0.00000001532, 5.35683107063, 13521.75144159140}, + {0.00000001824, 1.66056145084, 39302.09696219600}, + {0.00000001605, 1.90930973224, 6133.51265285680}, + {0.00000001282, 2.46013372544, 13916.01910964160}, + {0.00000001211, 4.41360631550, 3894.18182954220}, + {0.00000001394, 1.77801929250, 9225.53927328300}, + {0.00000001571, 4.95512957606, 25158.60171976540}, + {0.00000001205, 1.19212756308, 3.52311834900}, + {0.00000001132, 2.69830084955, 6040.34724601740}, + {0.00000001504, 5.77577388271, 18209.33026366019}, + {0.00000001393, 1.62625077326, 5120.60114558360}, + {0.00000001081, 2.93726744446, 17256.63153634140}, + {0.00000001232, 0.71651766504, 143571.32428481648}, + {0.00000001087, 0.99769687961, 955.59974160860}, + {0.00000001068, 5.28472576591, 65147.61976813770}, + {0.00000001169, 3.11663802316, 14945.31617355440}, + {0.00000000975, 5.10887260780, 6172.86952877200}, + {0.00000001202, 4.02992510403, 553.56940284240}, + {0.00000000979, 2.00000879106, 15110.46611986620}, + {0.00000000962, 4.02380771400, 6282.09552892320}, + {0.00000000999, 3.62643002790, 6262.30045449900}, + {0.00000001030, 5.84987815239, 213.29909543800}, + {0.00000001014, 2.84227679965, 8662.24032356300}, + {0.00000001185, 1.51330629149, 17654.78053974960}, + {0.00000000967, 2.67081017562, 5650.29211067820}, + {0.00000001222, 2.65423784904, 88860.05707098669}, + {0.00000000986, 2.36212814824, 6206.80977871580}, + {0.00000001034, 0.13634950642, 11712.95531823080}, + {0.00000001103, 3.08477302937, 43232.30665841560}, + {0.00000000781, 2.53374971725, 16496.36139620240}, + {0.00000001019, 3.04569392376, 6037.24420376200}, + {0.00000000795, 5.80662989126, 5230.80746680300}, + {0.00000000813, 3.57702871938, 10177.25767953360}, + {0.00000000962, 5.31470594766, 6284.05617105960}, + {0.00000000717, 5.95797471837, 12559.03815298200}, + {0.00000000967, 2.74413738053, 6244.94281435360}, + {0.00000000921, 0.10160160830, 29088.81141598500}, + {0.00000000719, 5.91788189939, 4136.91043351620}, + {0.00000000688, 3.89489045092, 1589.07289528380}, + {0.00000000772, 4.05505380285, 6127.65545055720}, + {0.00000000706, 5.49323197725, 22003.91463486980}, + {0.00000000665, 1.60002747134, 11087.28512591840}, + {0.00000000690, 4.50539825729, 426.59819087600}, + {0.00000000854, 3.26104645060, 20426.57109242200}, + {0.00000000656, 4.32410182940, 16858.48253293320}, + {0.00000000840, 2.59572585212, 28766.92442448400}, + {0.00000000686, 0.61944033771, 11403.67699557500}, + {0.00000000700, 3.40901412473, 7.11354700080}, + {0.00000000728, 0.04050185963, 5481.25491886760}, + {0.00000000653, 1.03869451230, 6062.66320755260}, + {0.00000000559, 4.79221805695, 20199.09495963300}, + {0.00000000633, 5.70229959167, 45892.73043315699}, + {0.00000000591, 6.10986487621, 9623.68827669120}, + {0.00000000520, 3.62310356479, 5333.90024102160}, + {0.00000000602, 5.58381898589, 10344.29506538580}, + {0.00000000496, 2.21027756314, 1990.74501704100}, + {0.00000000691, 1.96733114988, 12416.58850284820}, + {0.00000000640, 1.59062417043, 18319.53658487960}, + {0.00000000625, 3.82358168221, 13517.87010623340}, + {0.00000000475, 1.17025904180, 12569.67481833180}, + {0.00000000660, 5.08498512995, 283.85931886520}, + {0.00000000664, 4.50029469969, 47162.51635463520}, + {0.00000000569, 0.16318535463, 17267.26820169119}, + {0.00000000568, 3.86100969474, 6076.89030155420}, + {0.00000000462, 0.26368763517, 4590.91018048900}, + {0.00000000535, 4.83225423196, 18422.62935909819}, + {0.00000000466, 0.75873879417, 7342.45778018060}, + {0.00000000541, 3.07212190556, 226858.23855437008}, + {0.00000000610, 1.53597089605, 33019.02111220460}, + {0.00000000617, 2.62356328726, 11190.37790013700}, + {0.00000000548, 4.55798855803, 18875.52586977400}, + {0.00000000633, 4.60110281228, 66567.48586525429}, + {0.00000000587, 5.78087907808, 632.78373931320}, + {0.00000000603, 5.38458554802, 316428.22867391503}, + {0.00000000525, 5.01522072363, 12132.43996210600}, + {0.00000000469, 0.59975173763, 21954.15760939799}, + {0.00000000548, 3.50627043672, 17253.04110768959}, + {0.00000000502, 0.98804327589, 11609.86254401220}, + {0.00000000568, 1.98497313089, 7668.63742494250}, + {0.00000000482, 1.62460405687, 12146.66705610760}, + {0.00000000391, 3.68718382972, 18052.92954315780}, + {0.00000000457, 3.77214896610, 156137.47598479928}, + {0.00000000401, 5.29221540240, 15671.08175940660}, + {0.00000000469, 1.80963351735, 12562.62858163380}, + {0.00000000514, 3.37031288919, 20597.24396304120}, + {0.00000000452, 5.66811219778, 10454.50138660520}, + {0.00000000375, 4.98528185039, 9779.10867612540}, + {0.00000000523, 0.97215560834, 155427.54293624099}, + {0.00000000403, 5.13948189770, 1551.04522264800}, + {0.00000000372, 3.69883738807, 9388.00590941520}, + {0.00000000367, 4.43875659833, 4535.05943692440}, + {0.00000000406, 4.20863156497, 12592.45001978260}, + {0.00000000362, 2.55099560446, 242.72860397400}, + {0.00000000471, 4.61907324819, 5436.99301524020}, + {0.00000000388, 4.96020928400, 24356.78078864160}, + {0.00000000441, 5.83872966262, 3496.03282613400}, + {0.00000000349, 6.16307810648, 19800.94595622480}, + {0.00000000356, 0.23819081240, 5429.87946823940}, + {0.00000000346, 5.60809622572, 2379.16447357160}, + {0.00000000380, 2.72105213132, 11933.36796066960}, + {0.00000000432, 0.24215988572, 17996.03116822220}, + {0.00000000378, 5.22516848076, 7477.52286021600}, + {0.00000000337, 5.10885555836, 5849.36411211460}, + {0.00000000315, 0.57827745123, 10557.59416082380}, + {0.00000000318, 4.49949007320, 3634.62102451840}, + {0.00000000323, 1.55850824803, 10440.27429260360}, + {0.00000000314, 5.77154773334, 20.77539549240}, + {0.00000000303, 2.34615580398, 4686.88940770680}, + {0.00000000414, 5.93237602310, 51092.72605085480}, + {0.00000000362, 2.17561997119, 28237.23345938940}, + {0.00000000288, 0.18377405421, 13095.84266507740}, + {0.00000000277, 5.12952205030, 13119.72110282519}, + {0.00000000325, 6.18608287927, 6268.84875598980}, + {0.00000000273, 0.30522428863, 23141.55838292460}, + {0.00000000267, 5.76152585786, 5966.68398033480}, + {0.00000000345, 2.94246040875, 36949.23080842420}, + {0.00000000253, 5.20994580359, 24072.92146977640}, + {0.00000000342, 5.76212804329, 16460.33352952499}, + {0.00000000307, 6.01039067183, 22805.73556599360}, + {0.00000000261, 2.00304796059, 6148.01076995600}, + {0.00000000238, 5.08241964961, 6915.85958930460}, + {0.00000000249, 2.94762789744, 135.06508003540}, + {0.00000000306, 3.89765478921, 10988.80815753500}, + {0.00000000308, 0.05451027736, 4701.11650170840}, + {0.00000000319, 2.95712862064, 163096.18036118349}, + {0.00000000272, 2.07967681309, 4804.20927592700}, + {0.00000000209, 4.43768461442, 6546.15977336420}, + {0.00000000217, 0.73691592312, 6303.85124548380}, + {0.00000000203, 0.32033085531, 25934.12433108940}, + {0.00000000205, 5.22936478995, 20995.39296644940}, + {0.00000000213, 0.20671418919, 28286.99048486120}, + {0.00000000197, 0.48286131290, 16737.57723659660}, + {0.00000000230, 6.06567392849, 6287.00800325450}, + {0.00000000219, 1.29194216300, 5326.78669402080}, + {0.00000000201, 1.74700937253, 22743.40937951640}, + {0.00000000207, 4.45440927276, 6279.48542133960}, + {0.00000000269, 6.05640445030, 64471.99124174489}, + {0.00000000190, 0.99261116842, 29296.61538957860}, + {0.00000000194, 3.82656562755, 419.48464387520}, + {0.00000000262, 5.26961924126, 522.57741809380}, + {0.00000000210, 4.68618183158, 6254.62666252360}, + {0.00000000197, 2.80624554186, 4933.20844033260}, + {0.00000000252, 4.36220154620, 40879.44050464380}, + {0.00000000261, 1.07241516738, 55022.93574707440}, + {0.00000000233, 5.41751014958, 39609.65458316560}, + {0.00000000185, 4.14324541379, 5642.19824260920}, + {0.00000000247, 3.44855612987, 6702.56049386660}, + {0.00000000205, 4.04424043226, 536.80451209540}, + {0.00000000191, 3.15807087926, 16723.35014259500}, + {0.00000000222, 5.16259496507, 23539.70738633280}, + {0.00000000180, 4.56214752149, 6489.26139842860}, + {0.00000000227, 0.60156339452, 5905.70224207560}, + {0.00000000170, 0.93185903228, 16062.18452611680}, + {0.00000000159, 0.92751013112, 23937.85638974100}, + {0.00000000157, 4.69607868164, 6805.65326808520}, + {0.00000000218, 0.85533373430, 16627.37091537720}, + {0.00000000169, 0.94641052064, 3097.88382272579}, + {0.00000000207, 4.88410451334, 6286.66627864320}, + {0.00000000160, 4.95943826819, 10021.83728009940}, + {0.00000000175, 6.12762824563, 239424.39025435288}, + {0.00000000173, 3.13887234973, 6179.98307577280}, + {0.00000000157, 3.62822057807, 18451.07854656599}, + {0.00000000206, 5.74617821138, 3646.35037735440}, + {0.00000000157, 4.67695912207, 6709.67404086740}, + {0.00000000146, 3.09506069745, 4907.30205014560}, + {0.00000000165, 2.27139128760, 10660.68693504240}, + {0.00000000144, 3.96947747592, 6019.99192661860}, + {0.00000000171, 5.91302216729, 6058.73105428950}, + {0.00000000144, 2.13155655120, 26084.02180621620}, + {0.00000000151, 0.67417383565, 2388.89402044920}, + {0.00000000196, 1.67718461229, 2107.03450754240}, + {0.00000000146, 5.10373877968, 10770.89325626180}, + {0.00000000187, 1.23915444627, 19402.79695281660}, + {0.00000000137, 1.26247412216, 12566.21901028560}, + {0.00000000191, 5.03547476279, 263.08392337280}, + {0.00000000137, 3.52825454595, 639.89728631400}, + {0.00000000135, 0.73840670927, 5017.50837136500}, + {0.00000000164, 2.39195095081, 6357.85744855870}, + {0.00000000168, 0.05515907462, 9380.95967271720}, + {0.00000000161, 1.15721259392, 26735.94526221320}, + {0.00000000144, 1.76097645199, 5888.44996493220}, + {0.00000000131, 2.51859277344, 6599.46771964800}, + {0.00000000142, 2.43802911123, 5881.40372823420}, + {0.00000000159, 5.90325893762, 6281.59137728310}, + {0.00000000151, 3.72338532519, 12669.24447420140}, + {0.00000000132, 2.38417741883, 6525.80445396540}, + {0.00000000127, 0.00254936441, 10027.90319572920}, + {0.00000000148, 2.85102145528, 6418.14093002680}, + {0.00000000143, 5.74460279560, 26087.90314157420}, + {0.00000000172, 0.41289962240, 174242.46596404970}, + {0.00000000136, 4.15497742275, 6311.52503745920}, + {0.00000000170, 5.98194913129, 327574.51427678125}, + {0.00000000136, 2.48430537541, 13341.67431130680}, + {0.00000000149, 0.33002271275, 245.83164622940}, + {0.00000000165, 2.49667924600, 58953.14544329400}, + {0.00000000123, 1.67328384813, 32217.20018108080}, + {0.00000000123, 3.45660563754, 6277.55292568400}, + {0.00000000117, 0.86065134175, 6245.04817735560}, + {0.00000000149, 5.61358281003, 5729.50644714900}, + {0.00000000128, 0.71204006448, 103.09277421860}, + {0.00000000159, 2.43166592149, 221995.02880149524}, + {0.00000000137, 1.70657709200, 12566.08438968000}, + {0.00000000129, 2.80667872683, 6016.46880826960}, + {0.00000000113, 3.58302904101, 25685.87280280800}, + {0.00000000109, 3.26403795962, 6819.88036208680}, + {0.00000000122, 0.34120688202, 1162.47470440780}, + {0.00000000106, 1.59721172719, 17782.73207278420}, + {0.00000000144, 2.28891651774, 12489.88562870720}, + {0.00000000137, 5.82029768354, 44809.65020086340}, + {0.00000000134, 1.26539983018, 5331.35744374080}, + {0.00000000103, 5.96518130595, 6321.10352262720}, + {0.00000000109, 0.33808549034, 11300.58422135640}, + {0.00000000129, 5.89187277190, 12029.34718788740}, + {0.00000000122, 5.77325634636, 11919.14086666800}, + {0.00000000107, 6.24998989350, 77690.75950573849}, + {0.00000000107, 1.00535580713, 77736.78343050249}, + {0.00000000115, 5.86963518266, 12721.57209941700}, + {0.00000000102, 5.66283467269, 5540.08578945880}, + {0.00000000143, 0.24122178432, 4214.06901508480}, + {0.00000000143, 0.88529649733, 7576.56007357400}, + {0.00000000107, 2.92124030351, 31415.37924995700}, + {0.00000000100, 5.99485644501, 4061.21921539440}, + {0.00000000103, 2.41941934525, 5547.19933645960}, + {0.00000000104, 4.44106051277, 2118.76386037840}, + {0.00000000110, 0.37559635174, 5863.59120611620}, + {0.00000000124, 2.55619029611, 12539.85338018300}, + {0.00000000110, 3.66952094465, 238004.52415723629}, + {0.00000000112, 4.32512422724, 97238.62754448749}, + {0.00000000120, 1.26895630075, 12043.57428188900}, + {0.00000000097, 5.42612959752, 7834.12107263940}, + {0.00000000094, 2.56461130309, 19004.64794940840}, + {0.00000000105, 5.68272475301, 16522.65971600220}, + {0.00000000117, 3.65425622684, 34520.30930938080}, + {0.00000000108, 1.24206843948, 84672.47584450469}, + {0.00000000098, 0.13589994287, 11080.17157891760}, + {0.00000000097, 2.46722096722, 71980.63357473118}, + {0.00000000095, 5.36958330451, 6288.59877429880}, + {0.00000000096, 0.20796618776, 18139.29450141590}, + {0.00000000111, 5.01961920313, 11823.16163945020}, + {0.00000000090, 2.72355843779, 26880.31981303260}, + {0.00000000099, 0.90164266199, 18635.92845453620}, + {0.00000000126, 4.78722177847, 305281.94307104882}, + {0.00000000124, 5.00979495566, 172146.97134054029}, + {0.00000000090, 4.50544881196, 40077.61957352000}, + {0.00000000104, 5.63679680710, 2787.04302385740}, + {0.00000000091, 5.43564326147, 6272.03014972750}, + {0.00000000100, 2.00639461597, 12323.42309600880}, + {0.00000000117, 2.35555589778, 83286.91426955358}, + {0.00000000105, 2.59824000109, 30666.15495843280}, + {0.00000000090, 2.35779490026, 12491.37010141550}, + {0.00000000089, 3.57152453732, 11720.06886523160}, + {0.00000000095, 5.67015349858, 14919.01785375460}, + {0.00000000087, 1.86043406047, 27707.54249429480}, + {0.00000000106, 3.04150600352, 22345.26037610820}, + {0.00000000082, 5.58298993353, 10241.20229116720}, + {0.00000000083, 3.10607039533, 36147.40987730040}, + {0.00000000094, 5.47749711149, 9924.81042151060}, + {0.00000000082, 4.71988314145, 15141.39079431200}, + {0.00000000096, 3.89073946348, 6379.05507720920}, + {0.00000000110, 4.92131611151, 5621.84292321040}, + {0.00000000110, 4.89978492291, 72140.62866668739}, + {0.00000000097, 5.20764563059, 6303.43116939020}, + {0.00000000085, 1.61269222311, 33326.57873317420}, + {0.00000000093, 1.32651591333, 23020.65308658799}, + {0.00000000090, 0.57733016380, 26482.17080962440}, + {0.00000000078, 3.99588630754, 11293.47067435560}, + {0.00000000106, 3.92012705073, 62883.35513951360}, + {0.00000000098, 2.94397773524, 316.39186965660}, + {0.00000000076, 3.96310417608, 29026.48522950779}, + {0.00000000098, 0.95914722366, 48739.85989708300}, + {0.00000000078, 1.97068528043, 90279.92316810328}, + {0.00000000076, 0.23027966596, 21424.46664430340}, + {0.00000000079, 1.46227790922, 8982.81066930900}, + {0.00000000078, 2.28840998832, 266.60704172180}, + {0.00000000071, 1.51940765590, 33794.54372352860}, + {0.00000000076, 0.22880641443, 57375.80190084620}, + {0.00000000097, 0.39449562097, 24279.10701821359}, + {0.00000000075, 2.77638584795, 12964.30070339100}, + {0.00000000077, 5.18846946344, 11520.99686379520}, + {0.00000000068, 0.50006599129, 4274.51831083240}, + {0.00000000075, 2.07323762803, 15664.03552270859}, + {0.00000000077, 0.46665178780, 16207.88627150200}, + {0.00000000081, 4.10452219483, 161710.61878623239}, + {0.00000000071, 3.91415328513, 7875.67186362420}, + {0.00000000081, 0.91938383406, 74.78159856730}, + {0.00000000083, 4.69916218791, 23006.42599258639}, + {0.00000000069, 0.98999300277, 6393.28217121080}, + {0.00000000065, 5.41938745446, 28628.33622609960}, + {0.00000000073, 2.45564765251, 15508.61512327440}, + {0.00000000065, 3.02336771694, 5959.57043333400}, + {0.00000000064, 0.18375587635, 1066.49547719000}, + {0.00000000080, 5.81239171612, 12341.80690428090}, + {0.00000000066, 2.15105504851, 38.02767263580}, + {0.00000000067, 5.14047250153, 9814.60410029120}, + {0.00000000062, 2.43313614978, 10138.10951694860}, + {0.00000000068, 2.24442548639, 24383.07910844140}, + {0.00000000078, 1.39649333997, 9411.46461508720}, + {0.00000000059, 4.95362151577, 35707.71008290740}, + {0.00000000073, 1.35229143121, 5327.47610838280}, + {0.00000000057, 3.16018882154, 5490.30096152400}, + {0.00000000072, 5.91833527334, 10881.09957748120}, + {0.00000000067, 0.66414713064, 29864.33402730900}, + {0.00000000065, 0.30352816135, 7018.95236352320}, + {0.00000000059, 5.36231868425, 10239.58386601080}, + {0.00000000056, 3.22196331515, 2636.72547263700}, + {0.00000000068, 5.32086226658, 3116.65941225980}, + {0.00000000059, 1.63156134967, 61306.01159706580}, + {0.00000000054, 4.29491690425, 21947.11137270000}, + {0.00000000070, 0.29271565928, 6528.90749622080}, + {0.00000000057, 5.89190132575, 34513.26307268280}, + {0.00000000054, 2.51856815404, 6279.19451463340}, + {0.00000000074, 1.38235845304, 9967.45389998160}, + {0.00000000054, 0.92276712152, 6286.95718534940}, + {0.00000000070, 5.00933012248, 6453.74872061060}, + {0.00000000053, 3.86543309344, 32370.97899156560}, + {0.00000000055, 4.51794544854, 34911.41207609100}, + {0.00000000063, 5.41479412056, 11502.83761653050}, + {0.00000000063, 2.34416220742, 11510.70192305670}, + {0.00000000056, 0.91310629913, 9910.58332750900}, + {0.00000000067, 4.03308763854, 34596.36465465240}, + {0.00000000060, 5.57024703495, 5756.90800324580}, + {0.00000000072, 2.80863088166, 10866.87248347960}, + {0.00000000066, 6.12047940728, 12074.48840752400}, + {0.00000000051, 2.59519527563, 11396.56344857420}, + {0.00000000062, 5.14746754396, 25287.72379939980}, + {0.00000000054, 2.50994032776, 5999.21653112620}, + {0.00000000051, 4.51195861837, 29822.78323632420}, + {0.00000000059, 0.44167237876, 250570.67585721909}, + {0.00000000051, 3.68849066760, 6262.72053059260}, + {0.00000000049, 0.54704693048, 22594.05489571199}, + {0.00000000065, 2.38423614501, 52670.06959330260}, + {0.00000000069, 5.34363738671, 66813.56483573320}, + {0.00000000056, 2.67216180349, 17892.93839400359}, + {0.00000000049, 4.18361320516, 18606.49894600020}, + {0.00000000055, 0.83886167974, 20452.86941222180}, + {0.00000000050, 1.46327331958, 37455.72649597440}, + {0.00000000058, 3.34847975377, 33990.61834428620}, + {0.00000000065, 1.45522693982, 76251.32777062019}, + {0.00000000056, 2.35650664200, 37724.75341974820}, + {0.00000000048, 1.80689447612, 206.18554843720}, + {0.00000000056, 3.84224878744, 5483.25472482600}, + {0.00000000053, 0.17334326094, 77717.29458646949}, + {0.00000000053, 0.79879700631, 77710.24834977149}, + {0.00000000047, 0.43240779709, 735.87651353180}, + {0.00000000053, 4.58786566028, 11616.97609101300}, + {0.00000000048, 6.20230111054, 4171.42553661380}, + {0.00000000052, 2.91719053030, 6993.00889854970}, + {0.00000000057, 3.42008310383, 50317.20343953080}, + {0.00000000048, 0.12356889012, 13362.44970679920}, + {0.00000000060, 5.52056066934, 949.17560896980}, + {0.00000000045, 3.37963782356, 10763.77970926100}, + {0.00000000047, 5.50958184902, 12779.45079542080}, + {0.00000000052, 5.42770349015, 310145.15282392364}, + {0.00000000061, 2.93237974631, 5791.41255753260}, + {0.00000000044, 2.87440620802, 8584.66166590080}, + {0.00000000046, 4.03141796560, 10667.80048204320}, + {0.00000000044, 1.21579107625, 6272.43918464160}, + {0.00000000047, 2.57670800912, 11492.54267579200}, + {0.00000000044, 3.62570223167, 63658.87775083760}, + {0.00000000051, 0.84531181151, 12345.73905754400}, + {0.00000000046, 1.17584556517, 149.56319713460}, + {0.00000000043, 0.01524970172, 37853.87549938260}, + {0.00000000043, 0.79038834934, 640.87760738220}, + {0.00000000044, 2.22554419931, 6293.71251534120}, + {0.00000000049, 1.01528394907, 149144.46708624958}, + {0.00000000041, 3.27146326065, 8858.31494432060}, + {0.00000000045, 3.03765521215, 65236.22129328540}, + {0.00000000058, 5.45843180927, 1975.49254585600}, + {0.00000000041, 1.32190847146, 2547.83753823240}, + {0.00000000047, 3.67626039848, 28313.28880466100}, + {0.00000000047, 6.21438985953, 10991.30589870060}, + {0.00000000040, 2.37237751212, 8273.82086703240}, + {0.00000000056, 1.09773690181, 77376.20102240759}, + {0.00000000040, 2.35698541041, 2699.73481931760}, + {0.00000000043, 5.28030897946, 17796.95916678580}, + {0.00000000054, 2.59175932091, 22910.44676536859}, + {0.00000000055, 0.07988985505, 83467.15635301729}, + {0.00000000041, 4.47510694062, 5618.31980486140}, + {0.00000000040, 1.35670430524, 27177.85152920020}, + {0.00000000041, 2.48011323946, 6549.68289171320}, + {0.00000000050, 2.56387920528, 82576.98122099529}, + {0.00000000042, 4.78798367468, 7856.89627409019}, + {0.00000000047, 2.75482175292, 18202.21671665939}, + {0.00000000039, 1.97008298629, 24491.42579258340}, + {0.00000000042, 4.04346599946, 7863.94251078820}, + {0.00000000039, 3.01033936420, 853.19638175200}, + {0.00000000038, 0.49178679251, 38650.17350619900}, + {0.00000000044, 1.35931241699, 21393.54196985760}, + {0.00000000036, 4.86047906533, 4157.19844261220}, + {0.00000000043, 5.64354880978, 1062.90504853820}, + {0.00000000039, 3.92736779879, 3903.91137641980}, + {0.00000000040, 5.39694918320, 9498.21223063460}, + {0.00000000043, 2.40863861919, 29424.63423291600}, + {0.00000000046, 2.08022244271, 12573.26524698360}, + {0.00000000050, 6.15760345261, 78051.34191383338}, +}; + +static const struct ln_vsop earth_radius_r1[RADIUS_R1] = { + {0.00103018607, 1.10748968172, 6283.07584999140}, + {0.00001721238, 1.06442300386, 12566.15169998280}, + {0.00000702217, 3.14159265359, 0.00000000000}, + {0.00000032345, 1.02168583254, 18849.22754997420}, + {0.00000030801, 2.84358443952, 5507.55323866740}, + {0.00000024978, 1.31906570344, 5223.69391980220}, + {0.00000018487, 1.42428709076, 1577.34354244780}, + {0.00000010077, 5.91385248388, 10977.07880469900}, + {0.00000008635, 0.27158192945, 5486.77784317500}, + {0.00000008654, 1.42046854427, 6275.96230299060}, + {0.00000005069, 1.68613408916, 5088.62883976680}, + {0.00000004985, 6.01402338185, 6286.59896834040}, + {0.00000004667, 5.98749245692, 529.69096509460}, + {0.00000004395, 0.51800423445, 4694.00295470760}, + {0.00000003870, 4.74932206877, 2544.31441988340}, + {0.00000003755, 5.07053801166, 796.29800681640}, + {0.00000004100, 1.08424801084, 9437.76293488700}, + {0.00000003518, 0.02290216978, 83996.84731811189}, + {0.00000003436, 0.94937503872, 71430.69561812909}, + {0.00000003221, 6.15628775321, 2146.16541647520}, + {0.00000003418, 5.41151581880, 775.52261132400}, + {0.00000002863, 5.48433323746, 10447.38783960440}, + {0.00000002525, 0.24296913555, 398.14900340820}, + {0.00000002205, 4.94892172085, 6812.76681508600}, + {0.00000002186, 0.41991932164, 8031.09226305840}, + {0.00000002828, 3.41986300734, 2352.86615377180}, + {0.00000002554, 6.13241770582, 6438.49624942560}, + {0.00000001932, 5.31374587091, 8429.24126646660}, + {0.00000002427, 3.09118902115, 4690.47983635860}, + {0.00000001730, 1.53685999718, 4705.73230754360}, + {0.00000002250, 3.68836395620, 7084.89678111520}, + {0.00000002094, 1.28169060400, 1748.01641306700}, + {0.00000001483, 3.22226346483, 7234.79425624200}, + {0.00000001434, 0.81293662216, 14143.49524243060}, + {0.00000001754, 3.22883705112, 6279.55273164240}, + {0.00000001583, 4.09815978783, 11499.65622279280}, + {0.00000001575, 5.53890314149, 3154.68708489560}, + {0.00000001847, 1.82041234937, 7632.94325965020}, + {0.00000001499, 3.63177937611, 11513.88331679440}, + {0.00000001337, 4.64442556061, 6836.64525283380}, + {0.00000001275, 2.69329661394, 1349.86740965880}, + {0.00000001348, 6.15284035323, 5746.27133789600}, + {0.00000001126, 3.35676107739, 17789.84561978500}, + {0.00000001470, 3.65282991735, 1194.44701022460}, + {0.00000001101, 4.49747427670, 4292.33083295040}, + {0.00000001168, 2.58033028504, 13367.97263110660}, + {0.00000001236, 5.64980098028, 5760.49843189760}, + {0.00000000985, 0.65326301914, 5856.47765911540}, + {0.00000000928, 2.32555018290, 10213.28554621100}, + {0.00000001073, 5.82672338169, 12036.46073488820}, + {0.00000000918, 0.76907130762, 16730.46368959580}, + {0.00000000876, 1.50335727807, 11926.25441366880}, + {0.00000001023, 5.62071200879, 6256.77753019160}, + {0.00000000853, 0.65678134630, 155.42039943420}, + {0.00000000802, 4.10519132094, 951.71840625060}, + {0.00000000859, 1.42880883564, 5753.38488489680}, + {0.00000000992, 1.14238001610, 1059.38193018920}, + {0.00000000814, 1.63584008733, 6681.22485339960}, + {0.00000000664, 4.55039663226, 5216.58037280140}, + {0.00000000627, 1.50782904323, 5643.17856367740}, + {0.00000000644, 4.19480024859, 6040.34724601740}, + {0.00000000590, 6.18371704849, 4164.31198961300}, + {0.00000000635, 0.52423584770, 6290.18939699220}, + {0.00000000650, 0.97935492869, 25132.30339996560}, + {0.00000000568, 2.30121525349, 10973.55568635000}, + {0.00000000549, 5.26737827342, 3340.61242669980}, + {0.00000000547, 2.20143332641, 1592.59601363280}, + {0.00000000526, 0.92464258271, 11371.70468975820}, + {0.00000000493, 5.91036281399, 3894.18182954220}, + {0.00000000483, 1.66005711540, 12168.00269657460}, + {0.00000000514, 3.59683072524, 10969.96525769820}, + {0.00000000516, 3.97164781773, 17298.18232732620}, + {0.00000000529, 5.03538677680, 9917.69687450980}, + {0.00000000487, 2.50544745305, 6127.65545055720}, + {0.00000000419, 4.05235655996, 10984.19235169980}, + {0.00000000538, 5.54081539813, 553.56940284240}, + {0.00000000402, 2.16859478359, 7860.41939243920}, + {0.00000000552, 2.32219865498, 11506.76976979360}, + {0.00000000367, 3.39145698451, 6496.37494542940}, + {0.00000000360, 5.34467204596, 7079.37385680780}, + {0.00000000334, 3.61346365667, 11790.62908865880}, + {0.00000000454, 0.28755421898, 801.82093112380}, + {0.00000000419, 3.69613970002, 10575.40668294180}, + {0.00000000319, 0.30793759304, 16200.77272450120}, + {0.00000000376, 5.81560210508, 7058.59846131540}, + {0.00000000364, 1.08425056923, 6309.37416979120}, + {0.00000000294, 4.54798604178, 11856.21865142450}, + {0.00000000290, 1.26451946335, 8635.94200376320}, + {0.00000000394, 4.15683669084, 26.29831979980}, + {0.00000000260, 5.09424572996, 10177.25767953360}, + {0.00000000241, 2.25766000302, 11712.95531823080}, + {0.00000000239, 1.06936978753, 242.72860397400}, + {0.00000000276, 3.44260568764, 5884.92684658320}, + {0.00000000255, 5.38496803122, 21228.39202354580}, + {0.00000000307, 4.24313885601, 3738.76143010800}, + {0.00000000213, 3.44661200485, 213.29909543800}, + {0.00000000198, 0.69427265195, 1990.74501704100}, + {0.00000000195, 5.16563409007, 12352.85260454480}, + {0.00000000213, 3.89937836808, 13916.01910964160}, + {0.00000000214, 4.00445200772, 5230.80746680300}, + {0.00000000184, 5.59805976614, 6283.14316029419}, + {0.00000000184, 2.85275392124, 7238.67559160000}, + {0.00000000179, 2.54259058252, 14314.16811304980}, + {0.00000000236, 5.58826125715, 6069.77675455340}, + {0.00000000189, 2.72689937708, 6062.66320755260}, + {0.00000000184, 6.04216273598, 6283.00853968860}, + {0.00000000225, 1.66128561344, 4732.03062734340}, + {0.00000000230, 3.62591335086, 6284.05617105960}, + {0.00000000172, 0.97566476085, 3930.20969621960}, + {0.00000000162, 2.19467339429, 18073.70493865020}, + {0.00000000215, 1.04672844028, 3496.03282613400}, + {0.00000000182, 5.17782354566, 17253.04110768959}, + {0.00000000167, 2.17754938066, 6076.89030155420}, + {0.00000000167, 4.75672473773, 17267.26820169119}, + {0.00000000149, 0.80944185798, 709.93304855830}, + {0.00000000149, 0.17584214812, 9779.10867612540}, + {0.00000000192, 5.00680790235, 11015.10647733480}, + {0.00000000141, 4.38420380014, 4136.91043351620}, + {0.00000000158, 4.60969054283, 9623.68827669120}, + {0.00000000133, 3.30507062245, 154717.60988768269}, + {0.00000000166, 6.13191098325, 3.52311834900}, + {0.00000000181, 1.60715321141, 7.11354700080}, + {0.00000000150, 5.28136702046, 13517.87010623340}, + {0.00000000142, 0.49788089569, 25158.60171976540}, + {0.00000000124, 6.03440459813, 9225.53927328300}, + {0.00000000124, 0.99251562639, 65147.61976813770}, + {0.00000000128, 1.92032744711, 22483.84857449259}, + {0.00000000124, 3.99739675184, 4686.88940770680}, + {0.00000000121, 2.37814805239, 167283.76158766549}, + {0.00000000123, 5.62315112940, 5642.19824260920}, + {0.00000000117, 5.81755956156, 12569.67481833180}, + {0.00000000157, 3.40236948518, 16496.36139620240}, + {0.00000000130, 2.10499918142, 1589.07289528380}, + {0.00000000116, 0.55839966736, 5849.36411211460}, + {0.00000000123, 5.81645568991, 6282.09552892320}, + {0.00000000110, 0.42176497674, 6172.86952877200}, + {0.00000000150, 4.26279600865, 3128.38876509580}, + {0.00000000106, 2.27436561182, 5429.87946823940}, + {0.00000000114, 1.52894564202, 12559.03815298200}, + {0.00000000121, 0.39459045915, 12132.43996210600}, + {0.00000000104, 2.41845930933, 426.59819087600}, + {0.00000000109, 5.82786999856, 16858.48253293320}, + {0.00000000102, 4.46626484910, 23543.23050468179}, + {0.00000000100, 2.93812275274, 4535.05943692440}, + {0.00000000097, 3.97935904984, 6133.51265285680}, + {0.00000000098, 0.87616810121, 6525.80445396540}, + {0.00000000110, 6.22339014386, 12146.66705610760}, + {0.00000000098, 3.17344332543, 10440.27429260360}, + {0.00000000096, 2.44128701699, 3097.88382272579}, + {0.00000000099, 5.75642493267, 7342.45778018060}, + {0.00000000090, 0.18984343165, 13119.72110282519}, + {0.00000000099, 5.58884724219, 2388.89402044920}, + {0.00000000091, 6.04278320182, 20426.57109242200}, + {0.00000000080, 1.29028142103, 5650.29211067820}, + {0.00000000086, 3.94529200528, 10454.50138660520}, + {0.00000000085, 1.92836879835, 29088.81141598500}, + {0.00000000076, 2.70726317966, 143571.32428481648}, + {0.00000000091, 5.63859073351, 8827.39026987480}, + {0.00000000076, 1.80783856698, 28286.99048486120}, + {0.00000000075, 3.40858032804, 5481.25491886760}, + {0.00000000070, 4.53719487231, 17256.63153634140}, + {0.00000000089, 1.10064490942, 11769.85369316640}, + {0.00000000066, 2.78384937771, 536.80451209540}, + {0.00000000068, 3.88199295043, 17260.15465469040}, + {0.00000000088, 3.88075269535, 7477.52286021600}, + {0.00000000061, 6.17558202197, 11087.28512591840}, + {0.00000000060, 4.34824715818, 6206.80977871580}, + {0.00000000082, 4.59843208943, 9388.00590941520}, + {0.00000000079, 1.63139280394, 4933.20844033260}, + {0.00000000081, 1.55550779371, 9380.95967271720}, + {0.00000000078, 4.20905757519, 5729.50644714900}, + {0.00000000058, 5.76889633224, 3634.62102451840}, + {0.00000000060, 0.93813100594, 12721.57209941700}, + {0.00000000071, 6.11408885148, 8662.24032356300}, + {0.00000000057, 5.48112524468, 18319.53658487960}, + {0.00000000070, 0.01749174864, 14945.31617355440}, + {0.00000000074, 1.09976045820, 16460.33352952499}, + {0.00000000056, 1.63036186739, 15720.83878487840}, + {0.00000000055, 4.86788348404, 13095.84266507740}, + {0.00000000060, 5.93729841267, 12539.85338018300}, + {0.00000000054, 0.22608242982, 15110.46611986620}, + {0.00000000054, 2.30250047594, 16062.18452611680}, + {0.00000000064, 2.13513754101, 7875.67186362420}, + {0.00000000059, 5.87963500139, 5331.35744374080}, + {0.00000000058, 2.30546168615, 955.59974160860}, + {0.00000000049, 1.93839278478, 5333.90024102160}, + {0.00000000054, 5.80331607119, 12043.57428188900}, + {0.00000000054, 4.44671053809, 4701.11650170840}, + {0.00000000049, 0.30241161485, 6805.65326808520}, + {0.00000000046, 2.76898193028, 6709.67404086740}, + {0.00000000046, 3.98449608961, 98068.53671630539}, + {0.00000000049, 3.72022009896, 12323.42309600880}, + {0.00000000045, 3.30065998328, 22003.91463486980}, + {0.00000000048, 0.71071357303, 6303.43116939020}, + {0.00000000061, 1.66030429494, 6262.30045449900}, + {0.00000000047, 1.26317154881, 11919.14086666800}, + {0.00000000051, 1.08020906825, 10988.80815753500}, + {0.00000000045, 0.89150445122, 51868.24866217880}, + {0.00000000043, 0.57756724285, 24356.78078864160}, + {0.00000000043, 1.61526242998, 6277.55292568400}, + {0.00000000045, 2.96132920534, 8982.81066930900}, + {0.00000000043, 5.74295325645, 11403.67699557500}, + {0.00000000055, 3.14274403422, 33019.02111220460}, + {0.00000000057, 0.06379726305, 15671.08175940660}, + {0.00000000041, 2.53761820726, 6262.72053059260}, + {0.00000000040, 1.53130436944, 18451.07854656599}, + {0.00000000052, 1.71451922581, 1551.04522264800}, + {0.00000000055, 0.89439119424, 11933.36796066960}, + {0.00000000045, 3.88495384656, 60530.48898574180}, + {0.00000000040, 4.75740908001, 38526.57435087200}, + {0.00000000040, 3.77498297348, 26087.90314157420}, + {0.00000000039, 2.97113832621, 2118.76386037840}, + {0.00000000040, 3.36050962605, 10021.83728009940}, + {0.00000000047, 1.67051113434, 6303.85124548380}, + {0.00000000052, 5.21827368711, 77713.77146812050}, + {0.00000000047, 4.26356628717, 21424.46664430340}, + {0.00000000037, 1.66712389942, 6819.88036208680}, + {0.00000000037, 0.65746800933, 12029.34718788740}, + {0.00000000035, 3.36255650927, 24072.92146977640}, + {0.00000000036, 0.11087914947, 10344.29506538580}, + {0.00000000040, 4.14725582115, 2787.04302385740}, + {0.00000000035, 5.93650887012, 31570.79964939120}, + {0.00000000036, 2.15108874765, 30774.50164257480}, + {0.00000000036, 1.75078825382, 16207.88627150200}, + {0.00000000034, 2.75708224536, 12139.55350910680}, + {0.00000000034, 6.16891378800, 24491.42579258340}, + {0.00000000034, 2.31528650443, 55798.45835839840}, + {0.00000000032, 4.21446357042, 15664.03552270859}, + {0.00000000034, 3.19783054699, 32217.20018108080}, + {0.00000000039, 1.24979117796, 6418.14093002680}, + {0.00000000038, 5.89832942685, 640.87760738220}, + {0.00000000033, 4.80200120107, 16723.35014259500}, + {0.00000000032, 1.72442327688, 27433.88921587499}, + {0.00000000035, 4.44608896525, 18202.21671665939}, + {0.00000000031, 4.52790731280, 6702.56049386660}, + {0.00000000034, 3.96287980676, 18216.44381066100}, + {0.00000000030, 5.06259854444, 226858.23855437008}, + {0.00000000034, 1.43910280005, 49515.38250840700}, + {0.00000000030, 0.29303163371, 13521.75144159140}, + {0.00000000029, 2.02633840220, 11609.86254401220}, + {0.00000000030, 2.54923230240, 9924.81042151060}, + {0.00000000032, 4.91793198558, 11300.58422135640}, + {0.00000000030, 0.23284423547, 23581.25817731760}, + {0.00000000029, 1.62807736495, 639.89728631400}, + {0.00000000028, 3.84568936822, 2699.73481931760}, + {0.00000000029, 1.83149729794, 29822.78323632420}, + {0.00000000033, 4.60320094415, 19004.64794940840}, + {0.00000000027, 1.86151121799, 6288.59877429880}, + {0.00000000030, 4.46494072240, 36147.40987730040}, + {0.00000000028, 5.19684492912, 5863.59120611620}, + {0.00000000035, 4.52695674113, 36949.23080842420}, + {0.00000000027, 3.52528177609, 10770.89325626180}, + {0.00000000026, 1.48499438453, 11080.17157891760}, + {0.00000000035, 2.82154380962, 19402.79695281660}, + {0.00000000025, 2.46339998836, 6279.48542133960}, + {0.00000000026, 4.97688894643, 16737.57723659660}, + {0.00000000027, 0.40827112500, 12964.30070339100}, + {0.00000000029, 4.15148654061, 45892.73043315699}, + {0.00000000026, 4.56404104286, 17796.95916678580}, + {0.00000000025, 2.89309528854, 6286.66627864320}, + {0.00000000026, 4.82914580957, 1066.49547719000}, + {0.00000000031, 3.93096113738, 29864.33402730900}, + {0.00000000024, 6.14987193584, 18606.49894600020}, + {0.00000000024, 3.74225964547, 29026.48522950779}, + {0.00000000025, 5.70460621565, 27707.54249429480}, + {0.00000000025, 5.33928840652, 15141.39079431200}, + {0.00000000023, 2.37624087345, 17996.03116822220}, + {0.00000000026, 1.34231351782, 18875.52586977400}, + {0.00000000022, 5.50791626120, 6245.04817735560}, + {0.00000000024, 1.33998410121, 19800.94595622480}, + {0.00000000023, 0.22512280890, 6279.78949257360}, + {0.00000000022, 1.17576471775, 11925.27409260060}, + {0.00000000022, 3.58603606640, 6915.85958930460}, + {0.00000000023, 3.21621246666, 6286.36220740920}, + {0.00000000029, 2.09564449439, 15265.88651930040}, + {0.00000000022, 4.74660932338, 28230.18722269139}, + {0.00000000021, 2.30688751432, 5999.21653112620}, + {0.00000000028, 3.92087592807, 18208.34994259200}, + {0.00000000021, 3.22643339385, 25934.12433108940}, + {0.00000000021, 3.04956726238, 6566.93516885660}, + {0.00000000027, 5.35645770522, 33794.54372352860}, + {0.00000000025, 5.91542362188, 6489.26139842860}, + {0.00000000020, 1.52296293311, 135.06508003540}, + {0.00000000019, 1.78134428631, 156137.47598479928}, + {0.00000000019, 0.34388684087, 5327.47610838280}, + {0.00000000026, 3.41701003233, 25287.72379939980}, + {0.00000000019, 2.86664271911, 18422.62935909819}, + {0.00000000019, 4.71432851499, 77690.75950573849}, + {0.00000000019, 2.54227398241, 77736.78343050249}, + {0.00000000020, 5.91915117116, 48739.85989708300}, +}; + +static const struct ln_vsop earth_radius_r2[RADIUS_R2] = { + {0.00004359385, 5.78455133808, 6283.07584999140}, + {0.00000123633, 5.57935427994, 12566.15169998280}, + {0.00000012342, 3.14159265359, 0.00000000000}, + {0.00000008792, 3.62777893099, 77713.77146812050}, + {0.00000005689, 1.86958905084, 5573.14280143310}, + {0.00000003302, 5.47034879713, 18849.22754997420}, + {0.00000001471, 4.47964125007, 5507.55323866740}, + {0.00000001013, 2.81323115556, 5223.69391980220}, + {0.00000000854, 3.10776566900, 1577.34354244780}, + {0.00000001102, 2.84173992403, 161000.68573767410}, + {0.00000000648, 5.47348203398, 775.52261132400}, + {0.00000000608, 1.37894173533, 6438.49624942560}, + {0.00000000499, 4.41649242250, 6286.59896834040}, + {0.00000000416, 0.90332697974, 10977.07880469900}, + {0.00000000404, 3.20567269530, 5088.62883976680}, + {0.00000000351, 1.81081728907, 5486.77784317500}, + {0.00000000466, 3.65086758149, 7084.89678111520}, + {0.00000000458, 5.38585314743, 149854.40013480789}, + {0.00000000304, 3.51015066341, 796.29800681640}, + {0.00000000266, 6.17413982699, 6836.64525283380}, + {0.00000000281, 1.83874672540, 4694.00295470760}, + {0.00000000262, 1.41420110644, 2146.16541647520}, + {0.00000000264, 3.14103683911, 71430.69561812909}, + {0.00000000319, 5.35037932146, 3154.68708489560}, + {0.00000000238, 2.17695432424, 155.42039943420}, + {0.00000000229, 4.75969588070, 7234.79425624200}, + {0.00000000291, 4.61776401638, 4690.47983635860}, + {0.00000000211, 0.21864885298, 4705.73230754360}, + {0.00000000204, 4.22895113488, 1349.86740965880}, + {0.00000000195, 4.58550676556, 529.69096509460}, + {0.00000000255, 2.81442711144, 1748.01641306700}, + {0.00000000182, 5.70454011389, 6040.34724601740}, + {0.00000000180, 6.02147727878, 4292.33083295040}, + {0.00000000186, 1.58690991244, 6309.37416979120}, + {0.00000000167, 2.88802733052, 9437.76293488700}, + {0.00000000166, 1.99990574734, 8031.09226305840}, + {0.00000000160, 0.04412738495, 2544.31441988340}, + {0.00000000197, 2.01089431842, 1194.44701022460}, + {0.00000000165, 5.78372596774, 83996.84731811189}, + {0.00000000214, 3.38300910371, 7632.94325965020}, + {0.00000000140, 0.36669664351, 10447.38783960440}, + {0.00000000151, 0.95519595275, 6127.65545055720}, + {0.00000000136, 1.48417295645, 2352.86615377180}, + {0.00000000128, 5.48057748834, 951.71840625060}, + {0.00000000126, 5.26866506592, 6279.55273164240}, + {0.00000000127, 3.77552907014, 6812.76681508600}, + {0.00000000103, 4.95897533789, 398.14900340820}, + {0.00000000104, 0.70183576826, 1592.59601363280}, + {0.00000000101, 1.14481598642, 3894.18182954220}, + {0.00000000131, 0.76624310306, 553.56940284240}, + {0.00000000109, 5.41063597567, 6256.77753019160}, + {0.00000000078, 5.84775340741, 242.72860397400}, + {0.00000000097, 1.94685257714, 11856.21865142450}, + {0.00000000100, 5.19725292131, 244287.60000722769}, + {0.00000000076, 0.70480774041, 8429.24126646660}, + {0.00000000080, 6.18430772683, 1059.38193018920}, + {0.00000000068, 5.29561709093, 14143.49524243060}, + {0.00000000085, 5.39487308005, 25132.30339996560}, + {0.00000000055, 5.16874637579, 7058.59846131540}, + {0.00000000063, 0.48494730699, 801.82093112380}, + {0.00000000058, 4.07254840265, 13367.97263110660}, + {0.00000000051, 3.89696552232, 12036.46073488820}, + {0.00000000051, 5.56335232286, 1990.74501704100}, + {0.00000000060, 2.25046596710, 8635.94200376320}, + {0.00000000049, 5.58163417371, 6290.18939699220}, + {0.00000000051, 3.87240194908, 26.29831979980}, + {0.00000000051, 4.19300909995, 7860.41939243920}, + {0.00000000041, 3.97169191582, 10973.55568635000}, + {0.00000000041, 3.57080919230, 7079.37385680780}, + {0.00000000056, 2.76959005761, 90955.55169449610}, + {0.00000000042, 1.91461189163, 7477.52286021600}, + {0.00000000042, 0.42775891995, 10213.28554621100}, + {0.00000000042, 1.06925480488, 709.93304855830}, + {0.00000000038, 6.17935925345, 9917.69687450980}, + {0.00000000050, 0.81691517401, 11506.76976979360}, + {0.00000000053, 1.45828359397, 233141.31440436149}, + {0.00000000038, 3.32444534628, 5643.17856367740}, + {0.00000000047, 6.21543665927, 6681.22485339960}, + {0.00000000037, 0.36359309980, 10177.25767953360}, + {0.00000000045, 5.29587706357, 10575.40668294180}, + {0.00000000034, 5.63446915337, 6525.80445396540}, + {0.00000000034, 5.36385158519, 4933.20844033260}, + {0.00000000035, 5.36152295839, 25158.60171976540}, + {0.00000000042, 5.08837645072, 11015.10647733480}, + {0.00000000042, 4.22496037505, 88860.05707098669}, + {0.00000000039, 1.99171699618, 6284.05617105960}, + {0.00000000029, 3.19088628170, 11926.25441366880}, + {0.00000000029, 0.14996158324, 12168.00269657460}, + {0.00000000030, 1.58346276808, 9779.10867612540}, + {0.00000000026, 4.16210340581, 12569.67481833180}, + {0.00000000036, 2.74684637873, 3738.76143010800}, + {0.00000000026, 0.72824915320, 1589.07289528380}, + {0.00000000031, 5.34906371821, 143571.32428481648}, + {0.00000000025, 0.10240267494, 22483.84857449259}, + {0.00000000030, 3.47110495524, 14945.31617355440}, + {0.00000000026, 3.89359701125, 5753.38488489680}, + {0.00000000024, 1.18744224678, 4535.05943692440}, + {0.00000000033, 2.99317143244, 3930.20969621960}, + {0.00000000024, 1.57253767584, 6496.37494542940}, + {0.00000000024, 3.47434797542, 4136.91043351620}, + {0.00000000022, 3.91230073719, 6275.96230299060}, + {0.00000000025, 4.02978941287, 3128.38876509580}, + {0.00000000023, 1.07724492065, 12721.57209941700}, + {0.00000000021, 1.89591807148, 16730.46368959580}, + {0.00000000025, 2.42198937013, 5729.50644714900}, + {0.00000000020, 1.78163489101, 17789.84561978500}, + {0.00000000021, 0.49258939822, 29088.81141598500}, + {0.00000000026, 4.14947806747, 2388.89402044920}, + {0.00000000027, 2.54785812264, 3496.03282613400}, + {0.00000000020, 4.29944129273, 16858.48253293320}, + {0.00000000021, 5.97796936723, 7.11354700080}, + {0.00000000019, 0.80292033311, 16062.18452611680}, + {0.00000000024, 4.89894141052, 17260.15465469040}, + {0.00000000025, 1.37003752175, 6282.09552892320}, + {0.00000000022, 4.92663152168, 18875.52586977400}, + {0.00000000023, 5.68902059771, 16460.33352952499}, + {0.00000000023, 3.03021283729, 66567.48586525429}, + {0.00000000016, 3.89713736666, 5331.35744374080}, + {0.00000000016, 5.68562539832, 12559.03815298200}, + {0.00000000016, 3.95085099736, 3097.88382272579}, + {0.00000000016, 3.99041783945, 6283.14316029419}, + {0.00000000020, 6.10643919100, 167283.76158766549}, + {0.00000000015, 4.09775914607, 11712.95531823080}, + {0.00000000016, 5.71769940700, 17298.18232732620}, + {0.00000000016, 3.28894009404, 5884.92684658320}, + {0.00000000015, 4.42564243680, 13517.87010623340}, + {0.00000000016, 4.43452080930, 6283.00853968860}, + {0.00000000014, 1.44384279999, 4164.31198961300}, + {0.00000000014, 4.47380919159, 11790.62908865880}, + {0.00000000014, 4.77646531825, 7342.45778018060}, + {0.00000000011, 2.56768522896, 5481.25491886760}, + {0.00000000011, 1.51443332200, 16200.77272450120}, + {0.00000000011, 0.88708889185, 21228.39202354580}, + {0.00000000014, 4.50116508534, 640.87760738220}, +}; + +static const struct ln_vsop earth_radius_r3[RADIUS_R3] = { + {0.00000144595, 4.27319433901, 6283.07584999140}, + {0.00000006729, 3.91706261708, 12566.15169998280}, + {0.00000000774, 0.00000000000, 0.00000000000}, + {0.00000000247, 3.73021571217, 18849.22754997420}, + {0.00000000036, 2.80081409050, 6286.59896834040}, + {0.00000000033, 5.62990083112, 6127.65545055720}, + {0.00000000018, 3.72826142555, 6438.49624942560}, + {0.00000000016, 4.26011484232, 6525.80445396540}, + {0.00000000014, 3.47817116396, 6256.77753019160}, + {0.00000000012, 3.55747379482, 25132.30339996560}, + {0.00000000010, 4.43995693209, 4705.73230754360}, + {0.00000000010, 4.28045255470, 83996.84731811189}, + {0.00000000009, 5.36457057335, 6040.34724601740}, + {0.00000000008, 1.78458957263, 5507.55323866740}, + {0.00000000009, 0.47275199930, 6279.55273164240}, + {0.00000000009, 1.34741231639, 6309.37416979120}, + {0.00000000009, 0.77092900708, 5729.50644714900}, + {0.00000000007, 3.50146897332, 7058.59846131540}, + {0.00000000005, 2.89071061700, 775.52261132400}, + {0.00000000006, 2.36514111314, 6836.64525283380}, +}; + +static const struct ln_vsop earth_radius_r4[RADIUS_R4] = { + {0.00000003858, 2.56389016346, 6283.07584999140}, + {0.00000000306, 2.26911740541, 12566.15169998280}, + {0.00000000053, 3.44031471924, 5573.14280143310}, + {0.00000000015, 2.03136359366, 18849.22754997420}, + {0.00000000013, 2.05688873673, 77713.77146812050}, + {0.00000000007, 4.41218854480, 161000.68573767410}, + {0.00000000004, 5.33854414781, 6438.49624942560}, + {0.00000000006, 3.81514213664, 149854.40013480789}, + {0.00000000004, 4.26602478239, 6127.65545055720}, +}; + +static const struct ln_vsop earth_radius_r5[RADIUS_R5] = { + {0.00000000086, 1.21805304895, 6283.07584999140}, + {0.00000000012, 0.65572878044, 12566.15169998280}, +}; + + +/* Use in earth-sun function */ +double ln_calc_series(const struct ln_vsop *data, int terms, double t) +{ + double value = 0; + int i; + + for (i = 0; i < terms; i++) { + value += data->A * cos(data->B + data->C * t); + data++; + } + + return value; +} + +/* Get Julian day from Gregorian year, month and day */ +double julian_int(int year, int month, int day) +{ + int a, b; + + if (month < 3) { + year--; + month += 12; + } + + /* check for Julian or Gregorian calendar (starts Oct 4th 1582) */ + b = 0; + if (year > 1582 || + (year == 1582 && (month > 10 || (month == 10 && day >= 4)))) { + a = year / 100; + b = 2 - a + (a / 4); + } + + return ((int)(365.25 * (year + 4716)) + (int)(30.6001 * (month + 1)) + day + + b - 1524.5); +} + +/* Get Julian day form Gregorian string yyyy-mm-dd */ +double julian_char(char date[]) +{ + int day, month, year; + + year = atoi(date); + month = atoi(date + 5); + day = atoi(date + 8); + + return julian_int(year, month, day); +} + +/* Earth-Sun distance in astronomical units */ +double earth_sun(char *date) +{ + double t; + double R0, R1, R2, R3, R4, R5; + + t = (julian_char(date) - 2451545.0) / 365250.0; + + R0 = ln_calc_series(earth_radius_r0, RADIUS_R0, t); + R1 = ln_calc_series(earth_radius_r1, RADIUS_R1, t); + R2 = ln_calc_series(earth_radius_r2, RADIUS_R2, t); + R3 = ln_calc_series(earth_radius_r3, RADIUS_R3, t); + R4 = ln_calc_series(earth_radius_r4, RADIUS_R4, t); + R5 = ln_calc_series(earth_radius_r5, RADIUS_R5, t); + + return (R0 + R1 * t + R2 * t * t + R3 * t * t * t + R4 * t * t * t * t + + R5 * t * t * t * t * t); +} Added: trunk/grassaddons/i.landsat.toar/earth_sun.h =================================================================== --- trunk/grassaddons/i.landsat.toar/earth_sun.h (rev 0) +++ trunk/grassaddons/i.landsat.toar/earth_sun.h 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,25 @@ +/* + * Modified from LIBNOVA-0.12: see earth-sun.c + * + * Copyright (C) 2000 - 2005 Liam Girdwood + * Modified to GRASS (C) 2006 E. Jorge Tizado + */ + +#ifndef _EARTH_SUN_H +#define _EARTH_SUN_H + +struct ln_vsop +{ + double A; + double B; + double C; +}; + +/* Local prototypes */ + +double ln_calc_series(const struct ln_vsop *data, int terms, double t); +double julian_int(int year, int month, int day); +double julian_char(char date[]); +double earth_sun(char date[]); + +#endif Added: trunk/grassaddons/i.landsat.toar/landsat.c =================================================================== --- trunk/grassaddons/i.landsat.toar/landsat.c (rev 0) +++ trunk/grassaddons/i.landsat.toar/landsat.c 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,72 @@ +#include +#include +#include + +#define PI 3.1415926535897932384626433832795 +#define R2D 57.295779513082320877 +#define D2R 0.017453292519943295769 + +/**************************************************************************** + * PURPOSE: Calibrated digital number to Radiance + *****************************************************************************/ +double lsat_qcal2rad(int qcal, double lmax, double lmin, double qcalmax, double qcalmin) +{ + double gain, bias; + + gain = ((lmax - lmin) / (qcalmax - qcalmin)); + bias = lmin - gain * qcalmin; + + return (double)(((double)qcal) * gain + bias); +} + +/**************************************************************************** + * PURPOSE: Radiance of non-thermal band to TOA Reflectance + *****************************************************************************/ +double lsat_rad2ref(double rad, double dist_es, double sun_elev, double esun) +{ + double a, b; + + a = PI * dist_es * dist_es; + b = esun * cos((90 - sun_elev) * D2R); + + return (double)((rad * a) / b); +} + +double lsat_refrad_ratio(double dist_es, double sun_elev, double esun) +{ + double a, b; + + a = PI * dist_es * dist_es; + b = esun * cos((90 - sun_elev) * D2R); + + return (double)(a / b); +} + +/**************************************************************************** + * PURPOSE: Radiance of thermal band to Kinetic Temperature + *****************************************************************************/ +double lsat_rad2temp(double rad, double K1, double K2) +{ + return (double)(K2 / log((K1 / rad) + 1.0) - 273.15); +} + +/**************************************************************************** + * PUPOSE: Calibrated digital number of Landsat 5 to TOA Reflectance + ***************************************************************************** +double lsat_qcal2ref_tm5(int qcal, int band) +{ + static const double slope[] = + { 0.9398, 1.7731, 1.5348, 1.4239, 0.9828, 0., 1.3017 }; + static const double inter[] = + { 4.2934, 4.7289, 3.9796, 7.0320, 7.0185, 0., 7.6568 }; + + static const double gain[] = + { 0.7756863, 0.7956862, 0.6192157, 0.6372549, 0.1257255, 0., 0.0437255 }; + static const double bias[] = + { -6.1999969, -6.3999939, -5.0000000, -5.1000061, -0.9999981, 0., -0.3500004 }; + + --band; + return (gain[band] * ((double)(qcal) * slope[band] + inter[band]) + + bias[band]); +} +*/ Added: trunk/grassaddons/i.landsat.toar/landsat.h =================================================================== --- trunk/grassaddons/i.landsat.toar/landsat.h (rev 0) +++ trunk/grassaddons/i.landsat.toar/landsat.h 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,39 @@ +#ifndef _LANDSAT_H +#define _LANDSAT_H + +#define MAX_BANDS 9 + +/* Band data */ +typedef struct +{ + int number; /* Band number */ + int code; /* Band code */ + double lmax, lmin; /* Spectral radiance */ + double qcalmax, qcalmin; /* Quantized calibrated pixel */ + double esun; /* Solar espectral irradiance */ + +} band_data; + +/* Landsat data */ +typedef struct +{ + char date[11]; /* Satelite image date */ + double dist_es; /* Distance Earth-Sun */ + double sun_elev; /* Solar elevation */ + double K1, K2; /* Thermal calibration constant */ + int bands; /* Total number of bands */ + band_data band[MAX_BANDS]; /* Data for each band */ + +} lsat_data; + + +/***************************************************************************** + * Landsat Equations Prototypes + *****************************************************************************/ + +double lsat_qcal2rad(int qcal, double lmax, double lmin, double qcalmax, double qcalmin); +double lsat_rad2ref(double rad, double dist_es, double sun_elev, double esun); +double lsat_refrad_ratio(double dist_es, double sun_elev, double esun); +double lsat_rad2temp(double rad, double K1, double K2); + +#endif Added: trunk/grassaddons/i.landsat.toar/landsat_set.c =================================================================== --- trunk/grassaddons/i.landsat.toar/landsat_set.c (rev 0) +++ trunk/grassaddons/i.landsat.toar/landsat_set.c 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,257 @@ +#include +#include +#include +#include + +#include +#include + +#include "landsat.h" +#include "earth_sun.h" + +#define MET_SIZE 5600 /* .met file size 5516 bytes */ +#define MAX_STR 127 + +/* utility for read met file */ +void get_value_met(char *mettext, char *text, char *value) +{ + char *ptr; + + ptr = strstr(mettext, text); + if (ptr == NULL) + return; + + while (*ptr++ != '=') ; + sscanf(ptr, "%s", value); + return; +} + +/**************************************************************************** + * PURPOSE: Read values of Landsat-7 ETM+ from header (.met) file + *****************************************************************************/ +void met_ETM(char *metfile, lsat_data * lsat) +{ + FILE *f; + char mettext[MET_SIZE]; + char name[MAX_STR], value[MAX_STR]; + int i, j; + + static int band[] = { 1, 2, 3, 4, 5, 6, 6, 7, 8 }; + static int code[] = { 1, 2, 3, 4, 5, 61, 62, 7, 8 }; + + static double esun[] = + { 1969., 1840., 1551., 1044., 225.7, 0., 82.07, 1368. }; + + + if ((f = fopen(metfile, "r")) == NULL) { + G_fatal_error(_(".met file '%s' not found"), metfile); + } + fread(mettext, 1, MET_SIZE, f); + + get_value_met(mettext, "ACQUISITION_DATE", value); + strncpy(lsat->date, value, 11); + lsat->dist_es = earth_sun(lsat->date); + + get_value_met(mettext, "SUN_ELEVATION", value); + lsat->sun_elev = atof(value); + + lsat->K1 = 666.09; + lsat->K2 = 1282.71; + + lsat->bands = 9; + for (i = 0; i < lsat->bands; i++) { + lsat->band[i].number = *(band + i); + lsat->band[i].code = *(code + i); + lsat->band[i].esun = *(esun + lsat->band[i].number - 1); + + snprintf(name, MAX_STR, "LMAX_BAND%d", lsat->band[i].code); + get_value_met(mettext, name, value); + lsat->band[i].lmax = atof(value); + snprintf(name, MAX_STR, "LMIN_BAND%d", lsat->band[i].code); + get_value_met(mettext, name, value); + lsat->band[i].lmin = atof(value); + snprintf(name, MAX_STR, "QCALMAX_BAND%d", lsat->band[i].code); + get_value_met(mettext, name, value); + lsat->band[i].qcalmax = atof(value); + snprintf(name, MAX_STR, "QCALMIN_BAND%d", lsat->band[i].code); + get_value_met(mettext, name, value); + lsat->band[i].qcalmin = atof(value); + } + + (void)fclose(f); + return; +} + + +/**************************************************************************** + * PURPOSE: Store values of Landsat-4 TM + * + * date: adquisition date of image + * elevation: solar elevation angle + *****************************************************************************/ +void set_TM4(lsat_data * lsat, char date[], double elevation) +{ + int i; + + static int band[] = { 1, 2, 3, 4, 5, 6, 7 }; + static double esun[] = { 1958., 1828., 1559., 1045., 219.1, 0., 74.57 }; + static double lmax[] = { 185., 342., 245., 270., 36., 0., 19. }; + static double lmin[] = { -1.5, -3.1, -2.7, -2.5, -0.45, 0., -0.3 }; + + strncpy(lsat->date, date, 11); + lsat->sun_elev = elevation; + lsat->dist_es = earth_sun(lsat->date); + + lsat->K1 = 607.76; + lsat->K2 = 1260.56; + + lsat->bands = 7; + for (i = 0; i < lsat->bands; i++) { + lsat->band[i].number = *(band + i); + lsat->band[i].code = lsat->band[i].number; + lsat->band[i].esun = *(esun + lsat->band[i].number - 1); + lsat->band[i].lmax = *(lmax + lsat->band[i].number - 1); + lsat->band[i].lmin = *(lmin + lsat->band[i].number - 1); + lsat->band[i].qcalmax = 255.; + lsat->band[i].qcalmin = 0.; + } + return; +} + + +/**************************************************************************** + * PURPOSE: Store values of Landsat-5 TM + * + * date: adquisition date of image + * elevation: solar elevation angle + * after: flag for processing date + *****************************************************************************/ +void set_TM5(lsat_data * lsat, char date[], double elevation, char after) +{ + int i; + double *lmax, *lmin; + + static int band[] = { 1, 2, 3, 4, 5, 6, 7 }; + static double esun[] = { 1957., 1829., 1557., 1047., 219.3, 0., 74.52 }; + + /* Spectral radiances at detecter before May 4, 2003 */ + static double lmaxb[] = + { 152.10, 296.81, 204.30, 206.20, 27.19, 15.303, 14.38 }; + static double lminb[] = + { -1.52, -2.84, -1.17, -1.51, -0.37, 1.2378, -0.15 }; + + /* Spectral radiances at detecter after May 5, 2003 */ + static double lmaxa[] = + { 193.00, 365.00, 264.00, 221.00, 30.20, 15.303, 16.50 }; + static double lmina[] = + { -1.52, -2.84, -1.17, -1.51, -0.37, 1.2378, -0.15 }; + + strncpy(lsat->date, date, 11); + lsat->sun_elev = elevation; + lsat->dist_es = earth_sun(lsat->date); + + lsat->K1 = 607.76; + lsat->K2 = 1260.56; + + lsat->bands = 7; + if (after != 0) { + lmax = lmaxa; + lmin = lmina; + } + else { + lmax = lmaxb; + lmin = lminb; + } + for (i = 0; i < lsat->bands; i++) { + lsat->band[i].number = *(band + i); + lsat->band[i].code = lsat->band[i].number; + lsat->band[i].esun = *(esun + lsat->band[i].number - 1); + lsat->band[i].lmax = *(lmax + lsat->band[i].number - 1); + lsat->band[i].lmin = *(lmin + lsat->band[i].number - 1); + lsat->band[i].qcalmax = 255.; + lsat->band[i].qcalmin = 0.; + } + return; +} + + +/**************************************************************************** + * PURPOSE: Store values of Landsat-7 ETM+ + * + * date: adquisition date of image + * elevation: solar elevation angle + * gain: nine H/L chars for band gain + * before: flag for processing date + *****************************************************************************/ +void set_ETM(lsat_data * lsat, char date[], double elevation, char gain[], + char before) +{ + int i; + double *lmax, *lmin; + + static int band[] = { 1, 2, 3, 4, 5, 6, 6, 7, 8 }; + static int code[] = { 1, 2, 3, 4, 5, 61, 62, 7, 8 }; + + static double esun[] = + { 1969., 1840., 1551., 1044., 225.7, 0., 82.07, 1368. }; + + /* Spectral radiances at detector before July 1, 2000 */ + /* Low gain */ + static double lmaxLb[] = + { 297.5, 303.4, 235.5, 235.0, 47.70, 17.04, 16.600, 244.0 }; + static double lminLb[] = { -6.2, -6.0, -4.5, -4.5, -1.0, 0.0, -0.35, -5.0 }; + /* High gain */ + static double lmaxHb[] = + { 194.3, 202.4, 158.6, 157.5, 31.76, 12.65, 10.932, 158.4 }; + static double lminHb[] = { -6.2, -6.0, -4.5, -4.5, -1.0, 3.2, -0.35, -5.0 }; + + /* Spectral radiances at detector after July 1, 2000 */ + /* Low gain */ + static double lmaxLa[] = + { 293.7, 300.9, 234.4, 241.1, 47.57, 17.04, 16.540, 243.1 }; + static double lminLa[] = { -6.2, -6.4, -5.0, -5.1, -1.0, 0.0, -0.35, -4.7 }; + /* High gain */ + static double lmaxHa[] = + { 191.6, 196.5, 152.9, 157.4, 31.06, 12.65, 10.800, 158.3 }; + static double lminHa[] = { -6.2, -6.4, -5.0, -5.1, -1.0, 3.2, -0.35, -4.7 }; + + + strncpy(lsat->date, date, 11); + lsat->sun_elev = elevation; + lsat->dist_es = earth_sun(lsat->date); + + lsat->K1 = 666.09; + lsat->K2 = 1282.71; + + lsat->bands = 9; + for (i = 0; i < lsat->bands; i++) { + lsat->band[i].number = *(band + i); + lsat->band[i].code = *(code + i); + lsat->band[i].esun = *(esun + lsat->band[i].number - 1); + lsat->band[i].qcalmax = 255.; + lsat->band[i].qcalmin = 1.; + if (before != 0) { + if (gain[i] == 'H' || gain[i] == 'h') { + lmax = lmaxHb; + lmin = lminHb; + } + else { + lmax = lmaxLb; + lmin = lminLb; + } + } + else { + if (gain[i] == 'H' || gain[i] == 'h') { + lmax = lmaxHa; + lmin = lminHa; + } + else { + lmax = lmaxLa; + lmin = lminLa; + } + } + lsat->band[i].lmax = *(lmax + lsat->band[i].number - 1); + lsat->band[i].lmin = *(lmin + lsat->band[i].number - 1); + } + return; +} Added: trunk/grassaddons/i.landsat.toar/local_proto.h =================================================================== --- trunk/grassaddons/i.landsat.toar/local_proto.h (rev 0) +++ trunk/grassaddons/i.landsat.toar/local_proto.h 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,7 @@ +#include "landsat.h" + +void met_ETM (char *, lsat_data *); +void set_TM4 (lsat_data *, char, double); +void set_TM5 (lsat_data *, char, double, char); +void set_ETM (lsat_data *, char, double, char, char); + Added: trunk/grassaddons/i.landsat.toar/main.c =================================================================== --- trunk/grassaddons/i.landsat.toar/main.c (rev 0) +++ trunk/grassaddons/i.landsat.toar/main.c 2007-07-02 16:04:30 UTC (rev 909) @@ -0,0 +1,293 @@ + +/**************************************************************************** + * + * MODULE: r.landsat.toar + * + * AUTHOR(S): E. Jorge Tizado - ejtizado@unileon.es + * + * PURPOSE: Calculate TOA Reflectance and Kinectic Temperature + * for Landsat 4/5 TM or 7 ETM+ + * + * COPYRIGHT: (C) 2002,2005 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 +#include +#include +#include +#include + +#include "local_proto.h" +#include "landsat.h" + +int main(int argc, char *argv[]) +{ + struct Cell_head cellhd, window; + char *mapset; /* mapset name */ + + void *inrast; /* input buffer */ + unsigned char *outrast; /* output buffer */ + int nrows, ncols; + int row, col; + int infd, outfd; /* file descriptor */ + + RASTER_MAP_TYPE in_data_type; + RASTER_MAP_TYPE out_data_type = DCELL_TYPE; + + struct History history; /* holds meta-data (title, comments,..) */ + struct GModule *module; /* GRASS module for parsing arguments */ + + int verbose = 1; + struct Option *input, *output, *metfn, *date, *elev, *bgain; + char *name; /* band raster name */ + char *met; /* met filename */ + double elevation; /* solar elevation */ + struct Flag *sat4, *sat5, *sat7, *flag, *param; + + char band_in[127], band_out[127]; + int i, qcal; + double gain, bias, cref, rad, ref; + + lsat_data lsat; + + /* initialize GIS environment */ + G_gisinit(argv[0]); + + /* initialize module */ + module = G_define_module(); + module->description = _("Calculates reflectance at top of atmosphere or temperature for Landsat"); + + input = G_define_option(); + input->key = _("band_prefix"); + input->type = TYPE_STRING; + input->required = YES; + input->gisprompt = _("input,cell,raster"); + input->description = _("Base name of the landsat band rasters (.?)"); + + metfn = G_define_option(); + metfn->key = _("metfile"); + metfn->type = TYPE_STRING; + metfn->required = NO; + metfn->gisprompt = _(".met file"); + metfn->description = _("Header File [.met] (only ETM+)"); + + bgain = G_define_option(); + bgain->key = _("gain"); + bgain->type = TYPE_STRING; + bgain->required = NO; + bgain->gisprompt = _("band gain"); + bgain->description = _("Gain of bands 1,2,3,4,5,61,62,7,8 (only ETM+)"); + bgain->answer = "HHHLHLHHL"; + + date = G_define_option(); + date->key = _("date"); + date->type = TYPE_STRING; + date->required = NO; + date->gisprompt = _("image acquisition date"); + date->description = _("Image acquisition date (yyyy-mm-dd)"); + + elev = G_define_option(); + elev->key = _("solar"); + elev->type = TYPE_DOUBLE; + elev->required = NO; + elev->gisprompt = _("solar elevation"); + elev->description = _("Solar elevation in degrees"); + + /* Define the different flags */ + sat4 = G_define_flag(); + sat4->key = '4'; + sat4->description = _("Landsat-4 TM (specify date and solar)"); + sat4->answer = 0; + + sat5 = G_define_flag(); + sat5->key = '5'; + sat5->description = _("Landsat-5 TM (specify date and solar)"); + sat5->answer = 0; + + sat7 = G_define_flag(); + sat7->key = '7'; + sat7->description = _("Landsat-7 ETM+ (specify either met or date, solar, and gain"); + sat7->answer = 1; + + flag = G_define_flag(); + flag->key = 'f'; + flag->description = _("LANDSAT-5: product creation after instead of before May 5, 2003. " + "LANDSAT-7: product creation before instead of after July 1, 2000"); + flag->answer = 0; + + param = G_define_flag(); + param->key = 'v'; + param->description = _("Show parameters applied"); + + /* options and flags parser */ + if (G_parser(argc, argv)) + exit(EXIT_FAILURE); + + // -------------------------------- + // ----- START -------------------- + /* stores options and flags to variables */ + met = metfn->answer; + name = input->answer; + elevation = 0.; + + if (sat7->answer && met != NULL) { + met_ETM(met, &lsat); + fprintf(stdout, "Landsat-7 ETM+ with data in met file [%s]\n", met); + } + else if (date->answer == NULL || elev->answer == NULL) { + G_fatal_error(_("Need date and solar elevation")); + } + else { + elevation = atof(elev->answer); + if (sat7->answer) { + if (bgain->answer && strlen(bgain->answer) > 8) { + set_ETM(&lsat, date->answer, elevation, bgain->answer, flag->answer); + fprintf(stdout, "Landsat 7 ETM+ %s July 1, 2000\n", ((flag->answer) ? "before" : "after")); + } + else { + G_fatal_error(_("Need band gain with 9 (H/L) data for Landsat-7")); + } + } + else { + if (sat4->answer) { + set_TM4(&lsat, date->answer, elevation); + fprintf(stdout, "Landsat-4 TM\n"); + } + else { + set_TM5(&lsat, date->answer, elevation, flag->answer); + fprintf(stdout, "Landsat-5 TM %s May 5, 2003\n", ((flag->answer) ? "after" : "before")); + } + } + } + + if (param->answer) { + fprintf(stdout, " DATE %s\n", lsat.date); + fprintf(stdout, " earth-sun distance = %.8lf\n", lsat.dist_es); + fprintf(stdout, " solar elevation angle = %.8lf\n", lsat.sun_elev); + for (i = 0; i < lsat.bands; i++) { + fprintf(stdout, "-------------------\n"); + fprintf(stdout, " BAND %d (code %d)\n", lsat.band[i].number, lsat.band[i].code); + if (lsat.band[i].number == 6) { + fprintf(stdout, " const K1 = %lf\n", lsat.K1); + fprintf(stdout, " const K2 = %lf\n", lsat.K2); + } + else { + fprintf(stdout, " calibrated digital number (QCAL): %.1lf to %.1lf\n", lsat.band[i].qcalmin, + lsat.band[i].qcalmax); + fprintf(stdout, " radiance at-detector (L): %.3lf to %.3lf ", lsat.band[i].lmin, lsat.band[i].lmax); + + gain = (lsat.band[i].lmax - lsat.band[i].lmin) / (lsat.band[i].qcalmax - lsat.band[i].qcalmin); + bias = lsat.band[i].lmin - gain * lsat.band[i].qcalmin; + fprintf(stdout, "... radiance = %.8lf DN + %.8lf\n", gain, bias); + + cref = lsat_refrad_ratio(lsat.dist_es, lsat.sun_elev, lsat.band[i].esun); + fprintf(stdout, " exoatmospheric irradiance (ESUN): %.5lf ", lsat.band[i].esun); + fprintf(stdout, "... reflectance = %.8lf · radiance\n", cref); + + fprintf(stdout, " atmospheric effect: a = %.8lf, b = %.8lf\n", cref * gain, cref * bias); + fprintf(stdout, " r.mapcalc '%s.%drc=if(%s.%dr<(%.8lf*dp+%.8lf),%.8lf,%s.%dr-%.8lf*dp)'\n", + name, lsat.band[i].number, name, lsat.band[i].number, cref*gain, cref*bias, cref*bias, name, lsat.band[i].number, cref*gain); + } + } + fprintf(stdout, "-------------------\n"); + fflush(stdout); + } + + G_get_window(&window); + + for (i = 0; i < lsat.bands; i++) { + snprintf(band_in, 127, "%s.%d", name, lsat.band[i].code); + snprintf(band_out, 127, "%s.%dr", name, lsat.band[i].code); + + mapset = G_find_cell2(band_in, ""); + if (mapset == NULL) { + G_warning(_("cell file [%s] not found"), band_in); + continue; + } + + if (G_legal_filename(band_out) < 0) + G_fatal_error(_("[%s] is an illegal name"), band_out); + + /* determine the inputmap type (CELL/FCELL/DCELL) */ + in_data_type = G_raster_map_type(band_in, mapset); + if ((infd = G_open_cell_old(band_in, mapset)) < 0) + G_fatal_error(_("Cannot open cell file [%s]"), band_in); + + /* controlling, if we can open input raster */ + if (G_get_cellhd(band_in, mapset, &cellhd) < 0) + G_fatal_error(_("Cannot read file header of [%s]"), band_in); + + /* set same size as original band raster */ + if (G_set_window(&cellhd) < 0) + G_fatal_error(_("Unable to set region")); + + /* Allocate input and output buffer */ + inrast = G_allocate_raster_buf(in_data_type); + nrows = G_window_rows(); + ncols = G_window_cols(); + outrast = G_allocate_raster_buf(out_data_type); + + /* controlling, if we can write the raster */ + if ((outfd = G_open_raster_new(band_out, out_data_type)) < 0) + G_fatal_error(_("Could not open <%s>"), band_out); + + /* ================================================================= */ + /* ----- CORE ----- */ + G_message("Reflectance of %s to %s", band_in, band_out); + for (row = 0; row < nrows; row++) { + + if (verbose) + G_percent(row, nrows, 2); + + if (G_get_raster_row(infd, inrast, row, in_data_type) < 0) + G_fatal_error(_("Could not read from <%s>"), band_in); + + for (col = 0; col < ncols; col++) { + + qcal = (int)((CELL *) inrast)[col]; + + if (qcal < lsat.band[i].qcalmin) { + ref = -1.; + } + else { + rad = lsat_qcal2rad(qcal, lsat.band[i].lmax, lsat.band[i].lmin, lsat.band[i].qcalmax, lsat.band[i].qcalmin); + if (lsat.band[i].number == 6) { + ref = lsat_rad2temp(rad, lsat.K1, lsat.K2); + } + else { + ref = lsat_rad2ref(rad, lsat.dist_es, lsat.sun_elev, lsat.band[i].esun); + } + } + ((DCELL *) outrast)[col] = ref; + } + + if (G_put_raster_row(outfd, outrast, out_data_type) < 0) + G_fatal_error(_("Cannot write to <%s>"), band_out); + } + /* ----- END CORE ----- */ + /* ================================================================= */ + + G_free(inrast); + G_free(outrast); + G_close_cell(infd); + G_close_cell(outfd); + + /* TODO: set map color to grey */ + + /* TODO: set -1. to null */ + + /* add command line incantation to history file */ + G_short_history(band_out, "raster", &history); + G_command_history(&history); + G_write_history(band_out, &history); + } + + G_message("REMEMBER: -1 is a NULL value"); + G_set_window(&window); + exit(EXIT_SUCCESS); +} From landa at grass.itc.it Mon Jul 2 18:35:14 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Mon Jul 2 18:35:15 2007 Subject: [grass-addons] r910 - in trunk/grassaddons/gui: . gui_modules Message-ID: <200707021635.l62GZEEL005964@grass.itc.it> Author: landa Date: 2007-07-02 18:35:14 +0200 (Mon, 02 Jul 2007) New Revision: 910 Modified: 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/wxgui.py Log: Minor fixes in digitization tool Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-07-02 16:04:30 UTC (rev 909) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-07-02 16:35:14 UTC (rev 910) @@ -28,7 +28,10 @@ for details. """ -import sys, os, locale, string +import sys +import os +import locale +import string import wx import wx.lib.mixins.listctrl as listmix @@ -37,13 +40,6 @@ import cmd from debug import Debug as Debug -try: - import subprocess -except: - gmpath = os.path.join(os.getenv("GISBASE"), "etc/wx") - sys.path.append(gmpath) - from compat import subprocess - class Log: """ The log output is redirected to the status bar of the containing frame. @@ -640,7 +636,7 @@ self.layer != layer: continue - selected = self.mapInfo.SelectFromTable(layer, self.cat, self.queryCoords, self.qdist) + found, selected = self.mapInfo.SelectFromTable(layer, self.cat, self.queryCoords, self.qdist) if (self.action == "add" and selected > 0) or \ self.action == "update": self.SetTitle(_("Update attributes")) @@ -649,8 +645,8 @@ else: self.SetTitle(_("Display attributes")) - if (self.action == "display" or self.action == "update") and \ - selected == 0: + if not found or \ + (self.action != "add" and selected == 0): continue panel = wx.Panel(parent=notebook, id=wx.ID_ANY) @@ -725,6 +721,7 @@ mainSizer.Fit(self) if notebook.GetPageCount() == 0: + Debug.msg(4, "DisplayAttributesDialog(): Nothing found!") self.mapInfo = None def __SelectAttributes(self, layer): @@ -866,6 +863,7 @@ """ table = self.layers[layer]["table"] selected = 0 + found = False if queryCoords: # snapping distance cmdWhat = cmd.Command(cmd=['v.what', @@ -878,6 +876,7 @@ if cmdWhat.returncode == 0: read = False for item in cmdWhat.ReadStdOutput(): + found = True if read: name, value = item.split(':') name = name.strip() @@ -888,6 +887,7 @@ elif "key column" in item.lower(): read = True else: + found = True # select values selectCommand = cmd.Command(cmd=["v.db.select", "-v", "--q", "map=%s" % self.map, @@ -900,7 +900,7 @@ self.tables[table][name][1] = value selected+=1 - return selected + return (found, selected) def main(argv=None): if argv is None: Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-07-02 16:04:30 UTC (rev 909) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-07-02 16:35:14 UTC (rev 910) @@ -158,8 +158,9 @@ addstring += "%d %d" % (layer, cat) - Debug.msg (3, "VEdit.AddPoint(): map=%s, type=%s" % \ - (map, type)) + Debug.msg (3, "Vline.AddLine(): type=%s, layer=%d, cat=%d coords=%s" % \ + (key, layer, cat, coords)) + Debug.msg (4, "Vline.AddLine(): input=%s" % addstring) self._AddFeature (map=map, input=addstring) @@ -167,7 +168,10 @@ """ General method which adds feature to the vector map """ - command = ["v.edit", "-n", "map=%s" % map, "tool=add"] + command = ["v.edit", "-n", "--q", + "map=%s" % map, + "tool=add", + "thresh=-1.0" ] # run the command vedit = cmd.Command(cmd=command, stdin=input) Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-02 16:04:30 UTC (rev 909) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-02 16:35:14 UTC (rev 910) @@ -719,7 +719,7 @@ posWindow = self.ClientToScreen((self.mouse['begin'][0] + offset, self.mouse['begin'][1] + offset)) - if digit.action == "add": + if digit.action == "addLine": if digit.type in ["point", "centroid"]: # add new point self.DrawCross(self.mouse['begin'], 5) @@ -751,7 +751,11 @@ self.polycoords.append(event.GetPositionTuple()[:]) self.mouse['begin'] = self.polycoords[-1] self.DrawLines() - elif digit.action == "dispAttr": + elif digit.action == "deleteLine": + # delete selected feature + digit.DeleteLine(map=map, + east, north) + elif digit.action == "displayAttributes": 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, @@ -907,7 +911,7 @@ Debug.msg (5, "BufferedWindow.OnRightUp(): use=%s" % \ self.mouse["use"]) - if self.parent.digittoolbar and self.parent.digittoolbar.action == "add": + if self.parent.digittoolbar and self.parent.digittoolbar.action == "addLine": digit = self.parent.digittoolbar if digit.type in ["line", "boundary"]: try: @@ -941,7 +945,7 @@ layer=Digit.settings["layer"], cat=Digit.settings["category"], pos=posWindow, - action="add") + action="addLine") if addRecordDlg.mapInfo and \ addRecordDlg.ShowModal() == wx.ID_OK: sqlfile = tempfile.NamedTemporaryFile(mode="w") @@ -965,7 +969,7 @@ digit = self.parent.digittoolbar if self.mouse["use"] == "pointer" and \ digit and \ - digit.action == 'add' and \ + digit.action == "addLine" and \ digit.type in ["line", "boundary"]: self.mouse['end'] = event.GetPositionTuple()[:] Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \ @@ -981,7 +985,7 @@ digit = self.parent.digittoolbar if self.mouse["use"] == "pointer" and \ digit and \ - digit.action == 'add' and \ + digit.action == "addLine" and \ digit.type in ["line", "boundary"]: # remove last point from the line self.polycoords.pop() Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-02 16:04:30 UTC (rev 909) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-02 16:35:14 UTC (rev 910) @@ -167,7 +167,7 @@ self.layerSelectedID = None self.layers = [] # action (digitize new point, line, etc. - self.action = "add" + self.action = "addLine" self.type = "point" self.addString = "" @@ -259,29 +259,29 @@ def OnAddPoint(self, event): """Add point to the vector map layer""" - Debug.msg (3, "DigitToolbar.OnAddPoint()") - self.action = "add" + Debug.msg (4, "DigitToolbar.OnAddPoint()") + self.action = "addLine" self.type = "point" self.parent.MapWindow.mouse['box'] = 'point' def OnAddLine(self, event): """Add line to the vector map layer""" - Debug.msg (3, "DigitToolbar.OnAddLine()") - self.action = "add" + Debug.msg (4, "DigitToolbar.OnAddLine()") + 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 (3, "DigitToolbar.OnAddBoundary()") - self.action = "add" + Debug.msg (4, "DigitToolbar.OnAddBoundary()") + self.action = "addLine" self.type = "boundary" self.parent.MapWindow.mouse['box'] = 'line' def OnAddCentroid(self, event): """Add centroid to the vector map layer""" - Debug.msg (3, "DigitToolbar.OnAddCentroid()") - self.action = "add" + Debug.msg (4, "DigitToolbar.OnAddCentroid()") + self.action = "addLine" self.type = "centroid" self.parent.MapWindow.mouse['box'] = 'point' @@ -317,13 +317,14 @@ pass def OnDeleteLine(self, event): - pass + self.action = "deleteLine" + Debug.msg(4, "Digittoolbar.OnDeleteLine():") def OnDisplayCats(self, event): pass def OnDisplayAttr(self, event): - self.action="dispAttr" + self.action="displayAttributes" Debug.msg(4, "Digittoolbar.OnDisplayAttr():") def OnCopyCats(self, event): Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-07-02 16:04:30 UTC (rev 909) +++ trunk/grassaddons/gui/wxgui.py 2007-07-02 16:35:14 UTC (rev 910) @@ -40,7 +40,7 @@ try: import subprocess except: - from compat import subprocess + import compat.subprocess as subprocess import gui_modules gmpath = gui_modules.__path__[0] From bundala at grass.itc.it Mon Jul 2 21:41:35 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Mon Jul 2 21:41:38 2007 Subject: [grass-addons] r911 - trunk/grassaddons/v.generalize Message-ID: <200707021941.l62JfZ6i007771@grass.itc.it> Author: bundala Date: 2007-07-02 21:41:30 +0200 (Mon, 02 Jul 2007) New Revision: 911 Added: trunk/grassaddons/v.generalize/matrix.c trunk/grassaddons/v.generalize/matrix.h Modified: trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/point.c trunk/grassaddons/v.generalize/smoothing.c Log: Snakes Algorithms Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-02 16:35:14 UTC (rev 910) +++ trunk/grassaddons/v.generalize/main.c 2007-07-02 19:41:30 UTC (rev 911) @@ -31,6 +31,7 @@ #define DISTANCE_WEIGHTING 5 #define CHAIKEN 6 #define HERMITE 7 +#define SNAKES 8 int main(int argc, char *argv[]) { @@ -68,7 +69,7 @@ method_opt->required = YES; method_opt->multiple = NO; method_opt->options = - "douglas,lang,reduction,reumann,boyle,distance_weighting,chaiken,hermite"; + "douglas,lang,reduction,reumann,boyle,distance_weighting,chaiken,hermite,snakes"; method_opt->answer = "douglas"; method_opt->descriptions = "douglas;Douglass-Peucker Algorithm;" "lang;Lang Simplification Algorithm;" @@ -77,7 +78,8 @@ "boyle;Boyle's Forward-Looking Algorithm;" "distance_weighting;McMaster's Distance-Weighting Algorithm;" "chaiken;Chaiken's Algorithm;" - "hermite;Interpolation by Cubic Hermite Splines;"; + "hermite;Interpolation by Cubic Hermite Splines;" + "snakes;Snakes method for line smoothing;"; method_opt->description = _("Line simplification/smoothing algorithm"); thresh_opt = G_define_option(); @@ -155,8 +157,11 @@ else if (method_opt->answer[0] == 'c') { method = CHAIKEN; } + else if (method_opt->answer[0] == 'h') { + method = HERMITE; + } else { - method = HERMITE; + method = SNAKES; }; Points = Vect_new_line_struct(); @@ -215,8 +220,11 @@ else if (method == CHAIKEN) { after = chaiken(Points, thresh, with_z); } + else if (method == HERMITE) { + after = hermite(Points, thresh, with_z); + } else { - after = hermite(Points, thresh, with_z); + after = snakes(Points, (double)1.0, (double)1.0, with_z); }; }; Added: trunk/grassaddons/v.generalize/matrix.c =================================================================== --- trunk/grassaddons/v.generalize/matrix.c (rev 0) +++ trunk/grassaddons/v.generalize/matrix.c 2007-07-02 19:41:30 UTC (rev 911) @@ -0,0 +1,190 @@ + +/**************************************************************** + * + * MODULE: v.generalize + * + * AUTHOR(S): Daniel Bundala + * + * PURPOSE: Definition of a matrix and basic operations with + * matrices + * + * COPYRIGHT: (C) 2002-2005 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 "matrix.h" + +int matrix_init(int rows, int cols, MATRIX * res) +{ + + int i, j; + + res->rows = rows; + res->cols = cols; + res->a = (double **)G_malloc(rows * sizeof(double *)); + if (res->a == NULL) + return 0; + + for (i = 0; i < rows; i++) { + res->a[i] = (double *)G_malloc(cols * sizeof(double)); + if (res->a[i] == NULL) { + for (j = 0; j < i; j++) + G_free(res->a[j]); + G_free(res->a); + return 0; + }; + }; + + return 1; +}; + +void matrix_free(MATRIX m) +{ + int i; + for (i = 0; i < m.rows; i++) + G_free(m.a[i]); + G_free(m.a); + return; +}; + +int matrix_mult(MATRIX a, MATRIX b, MATRIX * res) +{ + if (a.cols != b.rows) + return 0; + + if (!matrix_init(a.rows, b.cols, res)) + return 0; + + int i, j, k; + for (i = 0; i < a.rows; i++) + for (j = 0; j < b.cols; j++) { + res->a[i][j] = 0; + for (k = 0; k < a.cols; k++) + res->a[i][j] += a.a[i][k] * b.a[k][j]; + }; + + return 1; +}; + +int matrix_add_identity(double s, MATRIX * m) +{ + if (m->rows != m->cols) + return 0; + int i; + for (i = 0; i < m->rows; i++) + m->a[i][i] += s; + + return 1; +}; + +/* three following functions implements elementary row operations on matrices */ + +/* auxialiry function for matrix_inverse, swaps two rows of given matrix */ +void matrix_swap_rows(int x, int y, MATRIX * m) +{ + int i; + for (i = 0; i < m->cols; i++) { + double t; + t = m->a[x][i]; + m->a[x][i] = m->a[y][i]; + m->a[y][i] = t; + }; + return; +}; + +/* auxiliary function for matrix_inverse, multiplies row of a matrix by + * a scalar */ +void matrix_row_scalar(int row, double s, MATRIX * m) +{ + int i; + for (i = 0; i < m->cols; i++) + m->a[row][i] *= s; + return; +}; + +/* auxiliary function for matrix_inverse, adds a multiple of + * one row to another. + * i.e row[ra] = row[ra] + row[rb] * s; + */ +void matrix_row_add_multiple(int ra, int rb, double s, MATRIX * m) +{ + int i; + for (i = 0; i < m->cols; i++) + m->a[ra][i] += m->a[rb][i] * s; + return; +}; + +/* TODO: don't test directly equality to zero */ +int matrix_inverse(MATRIX a, MATRIX * res) +{; + + /* not a square matrix */ + if (a.rows != a.cols) + return 0; + + int i, j; + + /* initialize output matrix to the identity matrix */ + if (!matrix_init(a.rows, a.rows, res)) + return 0; + for (i = 0; i < a.rows; i++) { + memset(res->a[i], 0, sizeof(double) * a.cols); + res->a[i][i] = 1; + }; + + + /* in order to obtain the inverse of a matrix, we run + * gauss elimination on the matrix and each time we apply + * elementary row operation on this matrix, we apply the + * same operation on the identity matrix. Correctness of + * this follows from the fact that an invertible matrix + * is row equivalent to the identity matrix. + */ + + int n = a.rows; + for (i = 0; i < n; i++) { + int found = 0; + for (j = i; j < n; j++) { + if (a.a[j][i] != 0) { /* need to change this row to something */ + found = 1; /* more sensible */ + matrix_swap_rows(i, j, &a); + matrix_swap_rows(i, j, res); + break; + }; + }; + if (!found) + return 0; + double c = (double)1.0 / a.a[i][i]; + matrix_row_scalar(i, c, &a); + matrix_row_scalar(i, c, res); + for (j = 0; j < n; j++) { + if (i == j) + continue; + double c = -a.a[j][i]; + matrix_row_add_multiple(j, i, c, &a); + matrix_row_add_multiple(j, i, c, res); + }; + }; + + return 1; +}; + +void matrix_print(MATRIX a) +{ + int i, j; + for (i = 0; i < a.rows; i++) { + double s = 0; + for (j = 0; j < a.cols; j++) { + printf("%.3lf ", a.a[i][j]); + s += a.a[i][j]; + }; + printf("|%.5lf\n", s); + }; + printf("\n"); + +}; Property changes on: trunk/grassaddons/v.generalize/matrix.c ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/v.generalize/matrix.h =================================================================== --- trunk/grassaddons/v.generalize/matrix.h (rev 0) +++ trunk/grassaddons/v.generalize/matrix.h 2007-07-02 19:41:30 UTC (rev 911) @@ -0,0 +1,48 @@ + +/**************************************************************** + * + * MODULE: v.generalize + * + * AUTHOR(S): Daniel Bundala + * + * PURPOSE: definition of a matrix and basic operations with + * with matrices + * + * COPYRIGHT: (C) 2002-2005 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. + * + ****************************************************************/ + +#ifndef MATRIX_H +#define MATRIX_H + +#include + +typedef struct +{ + int rows, cols; + double **a; +} MATRIX; + +/* return 1 on success, 0 on error (out of memory) */ +extern int matrix_init(int rows, int cols, MATRIX * res); +/* free the memory occupied by the values of m */ +extern void matrix_free(MATRIX m); +/* multiply two matrices, initialize the dimensions of res + * to correct values. Return 1 on success, 0 on failure. + * return value 0 means - bad dimensions or out of memory */ +extern int matrix_mult(MATRIX a, MATRIX b, MATRIX * res); +/* adds a multiple of the identity matrix to the given matrix + * M = M + s * Id. Returns 1 on success, 0 otherwise */ +extern int matrix_add_identity(double s, MATRIX * m); +/* calculate the inverse of given (square) matrix. Returns 0 if + * the matrix is not invertible or if an error occurs. + * Otherwise it returns 1 */ +extern int matrix_inverse(MATRIX a, MATRIX * res); +/* debug function */ +extern void matrix_print(MATRIX a); +#endif Property changes on: trunk/grassaddons/v.generalize/matrix.h ___________________________________________________________________ Name: svn:executable + * Modified: trunk/grassaddons/v.generalize/point.c =================================================================== --- trunk/grassaddons/v.generalize/point.c 2007-07-02 16:35:14 UTC (rev 910) +++ trunk/grassaddons/v.generalize/point.c 2007-07-02 19:41:30 UTC (rev 911) @@ -98,8 +98,6 @@ }; pl->next = NULL; - if (p.x < 10) - printf("%lf\n", p.x); pl->p = p; return pl; }; Modified: trunk/grassaddons/v.generalize/smoothing.c =================================================================== --- trunk/grassaddons/v.generalize/smoothing.c 2007-07-02 16:35:14 UTC (rev 910) +++ trunk/grassaddons/v.generalize/smoothing.c 2007-07-02 19:41:30 UTC (rev 911) @@ -22,6 +22,7 @@ #include #include #include "point.h" +#include "matrix.h" /* boyle's forward looking algorithm * return the number of points in the result = Points->n_points @@ -199,8 +200,6 @@ void refine_tangent(POINT * p) { double l = point_dist2(*p); - if (l < 0.0000001) - return; point_scalar(*p, 1 / sqrt(sqrt(sqrt(l))), p); return; }; @@ -300,3 +299,108 @@ point_list_free(head); return Points->n_points; }; + +/* snakes algorithm for line simplification/generalization + * returns the number of points in the output line. This is + * always equal to the number of points in the original line + * + * alfa, beta are 2 parameters which change the behaviour of the algorithm + * + * TODO: Add parameter iterations, so the runnining time is O(N^3 * log iterations) + * instead of O(N^3 * itearations) + * TODO: Solve the problems with the first and last few points. Probably, repeat + * the first/last point at the beginning/end of the line + */ +int snakes(struct line_pnts *Points, double alfa, double beta, int with_z) +{ + MATRIX g, ginv, xcoord, ycoord, zcoord, xout, yout, zout; + + int n = Points->n_points; + int i, j; + + int plus = 4; + + if (!matrix_init(n + 2 * plus, n + 2 * plus, &g)) { + G_fatal_error(_("Out of memory")); + return n; + }; + matrix_init(n + 2 * plus, 1, &xcoord); + matrix_init(n + 2 * plus, 1, &ycoord); + matrix_init(n + 2 * plus, 1, &zcoord); + + double x0 = Points->x[0]; + double y0 = Points->y[0]; + double z0 = Points->z[0]; + + /* store the coordinates in the column vectors */ + for (i = 0; i < n; i++) { + xcoord.a[i + plus][0] = Points->x[i] - x0; + ycoord.a[i + plus][0] = Points->y[i] - y0; + zcoord.a[i + plus][0] = Points->z[i] - z0; + }; + + /* repeat first and last point at the beginning and end + * of each vector respectively */ + for (i = 0; i < plus; i++) { + xcoord.a[i][0] = 0; + ycoord.a[i][0] = 0; + zcoord.a[i][0] = 0; + }; + + for (i = n + plus; i < n + 2 * plus; i++) { + xcoord.a[i][0] = Points->x[n - 1] - x0; + ycoord.a[i][0] = Points->y[n - 1] - y0; + zcoord.a[i][0] = Points->z[n - 1] - z0; + }; + + + /* calculate the matrix */ + double a = 2.0 * alfa + 6.0 * beta; + double b = -alfa - 4.0 * beta; + double c = beta; + + double val[5] = { c, b, a, b, c }; + + for (i = 0; i < n + 2 * plus; i++) + for (j = 0; j < n + 2 * plus; j++) { + int index = j - i + 2; + if (index >= 0 && index <= 4) + g.a[i][j] = val[index]; + else + g.a[i][j] = 0; + }; + + matrix_add_identity((double)1.0, &g); + + /* find its inverse */ + if (!matrix_inverse(g, &ginv)) { + G_fatal_error(_("Could not find the inverse matrix")); + return n; + }; + + if (!matrix_mult(ginv, xcoord, &xout) + || !matrix_mult(ginv, ycoord, &yout) + || !matrix_mult(ginv, zcoord, &zout)) { + G_fatal_error(_("Could not calculate the output vectors")); + return n; + }; + + /* copy the new values of coordinates, but + * never move the last and first point */ + for (i = 1; i < n - 1; i++) { + Points->x[i] = xout.a[i + plus][0] + x0; + Points->y[i] = yout.a[i + plus][0] + y0; + if (with_z) + Points->z[i] = zout.a[i + plus][0] + z0; + }; + + matrix_free(g); + matrix_free(ginv); + matrix_free(xcoord); + matrix_free(ycoord); + matrix_free(zcoord); + matrix_free(xout); + matrix_free(yout); + matrix_free(zout); + return Points->n_points; +}; From landa at grass.itc.it Tue Jul 3 10:45:43 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Tue Jul 3 10:45:45 2007 Subject: [grass-addons] r912 - trunk/grassaddons/gui/gui_modules Message-ID: <200707030845.l638jhIJ015613@grass.itc.it> Author: landa Date: 2007-07-03 10:45:43 +0200 (Tue, 03 Jul 2007) New Revision: 912 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Digitization tool:revert delete line (typo) Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-02 19:41:30 UTC (rev 911) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-03 08:45:43 UTC (rev 912) @@ -753,8 +753,9 @@ self.DrawLines() elif digit.action == "deleteLine": # delete selected feature - digit.DeleteLine(map=map, - east, north) + pass + #digit.DeleteLine(map=map, + #east, north) elif digit.action == "displayAttributes": qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width) # select attributes based on coordinates (all layers) From chemin at grass.itc.it Tue Jul 3 13:31:43 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Tue Jul 3 13:31:45 2007 Subject: [grass-addons] r913 - in trunk/grassaddons/gipe: i.evapo.potrad script_generator Message-ID: <200707031131.l63BVhuP017857@grass.itc.it> Author: chemin Date: 2007-07-03 13:31:33 +0200 (Tue, 03 Jul 2007) New Revision: 913 Added: trunk/grassaddons/gipe/i.evapo.potrad/solar_day_3d.c Modified: trunk/grassaddons/gipe/i.evapo.potrad/main.c trunk/grassaddons/gipe/i.evapo.potrad/solar_day.c trunk/grassaddons/gipe/script_generator/l7_in_read.c Log: Incorporated slope aspect effect on Net Radiation and modified script_generator accordingly Modified: trunk/grassaddons/gipe/i.evapo.potrad/main.c =================================================================== --- trunk/grassaddons/gipe/i.evapo.potrad/main.c 2007-07-03 08:45:43 UTC (rev 912) +++ trunk/grassaddons/gipe/i.evapo.potrad/main.c 2007-07-03 11:31:33 UTC (rev 913) @@ -21,6 +21,7 @@ #include double solar_day(double lat, double doy, double tsw ); +double solar_day_3d(double lat, double doy, double tsw, double slope, double aspect); double r_net_day( double bbalb, double solar, double tsw ); double et_pot_day( double bbalb, double solar, double tempk, double tsw, double roh_w ); @@ -35,10 +36,11 @@ int verbose=1; struct GModule *module; - struct Option *input1, *input2, *input3, *input4, *input5, *input6; + struct Option *input1, *input2, *input3, *input4; + struct Option *input5, *input6, *input7, *input8; struct Option *output1, *output2; - struct Flag *flag1, *flag2; + struct Flag *flag1, *flag2, *flag3; struct History history; //metadata /************************************/ @@ -47,13 +49,17 @@ char *result1,*result2; //output raster name //File Descriptors int infd_albedo, infd_tempk, infd_lat, infd_doy, infd_tsw; + int infd_slope, infd_aspect; int outfd1, outfd2; - char *albedo,*tempk,*lat,*doy,*tsw; + char *albedo,*tempk,*lat,*doy,*tsw,*slope,*aspect; double roh_w; int i=0,j=0; - void *inrast_albedo, *inrast_tempk, *inrast_lat, *inrast_doy, *inrast_tsw; + void *inrast_albedo, *inrast_tempk, *inrast_lat; + void *inrast_doy, *inrast_tsw; + void *inrast_slope, *inrast_aspect; + unsigned char *outrast1, *outrast2; RASTER_MAP_TYPE data_type_output=DCELL_TYPE; RASTER_MAP_TYPE data_type_albedo; @@ -61,6 +67,8 @@ RASTER_MAP_TYPE data_type_lat; RASTER_MAP_TYPE data_type_doy; RASTER_MAP_TYPE data_type_tsw; + RASTER_MAP_TYPE data_type_slope; + RASTER_MAP_TYPE data_type_aspect; /************************************/ G_gisinit(argv[0]); @@ -109,7 +117,6 @@ input5->description=_("Name of the single-way transmissivity map [0.0-1.0]"); input5->answer =_("tsw"); - input6 = G_define_option() ; input6->key =_("roh_w"); input6->type = TYPE_DOUBLE; @@ -118,7 +125,23 @@ input6->description=_("Value of the density of fresh water ~[1000-1020]"); input6->answer =_("1010.0"); + input7 = G_define_option() ; + input7->key =_("slope"); + input7->type = TYPE_STRING; + input7->required = NO; + input7->gisprompt =_("old,cell,raster"); + input7->description=_("Name of the Slope map ~[0-90]"); + input7->answer =_("slope"); + input8 = G_define_option() ; + input8->key =_("aspect"); + input8->type = TYPE_STRING; + input8->required = NO; + input8->gisprompt =_("old,cell,raster"); + input8->description=_("Name of the Aspect map ~[0-360]"); + input8->answer =_("aspect"); + + output1 = G_define_option() ; output1->key =_("etpot"); output1->type = TYPE_STRING; @@ -133,15 +156,18 @@ output2->required = NO; output2->gisprompt =_("new,cell,raster"); output2->description=_("Name of the output Diurnal Net Radiation layer"); -// output2->answer =_("rnetd"); flag1 = G_define_flag(); flag1->key = 'r'; flag1->description = _("Output Diurnal Net Radiation (for r.eb.eta)"); flag2 = G_define_flag(); - flag2->key = 'q'; - flag2->description = _("Quiet"); + flag2->key = 'd'; + flag2->description = _("Slope/Aspect correction"); + + flag3 = G_define_flag(); + flag3->key = 'q'; + flag3->description = _("Quiet"); /********************/ if (G_parser(argc, argv)) exit (EXIT_FAILURE); @@ -152,10 +178,12 @@ doy = input4->answer; tsw = input5->answer; roh_w = atof(input6->answer); + slope = input7->answer; + aspect = input8->answer; result1 = output1->answer; result2 = output2->answer; - verbose = (!flag1->answer); + verbose = (!flag3->answer); /***************************************************/ mapset = G_find_cell2(albedo, ""); if (mapset == NULL) { @@ -212,6 +240,32 @@ G_fatal_error(_("Cannot read file header of [%s]"), tsw); inrast_tsw = G_allocate_raster_buf(data_type_tsw); /***************************************************/ + if(flag2->answer){ + mapset = G_find_cell2 (slope, ""); + if (mapset == NULL) { + G_fatal_error(_("Cell file [%s] not found"), slope); + } + data_type_slope = G_raster_map_type(slope,mapset); + if ( (infd_slope = G_open_cell_old (slope,mapset)) < 0) + G_fatal_error(_("Cannot open cell file [%s]"), slope); + if (G_get_cellhd (slope, mapset, &cellhd) < 0) + G_fatal_error(_("Cannot read file header of [%s]"), slope); + inrast_slope = G_allocate_raster_buf(data_type_slope); + } + /***************************************************/ + if(flag2->answer){ + mapset = G_find_cell2 (aspect, ""); + if (mapset == NULL) { + G_fatal_error(_("Cell file [%s] not found"), aspect); + } + data_type_aspect = G_raster_map_type(aspect,mapset); + if ( (infd_aspect = G_open_cell_old (aspect,mapset)) < 0) + G_fatal_error(_("Cannot open cell file [%s]"), aspect); + if (G_get_cellhd (aspect, mapset, &cellhd) < 0) + G_fatal_error(_("Cannot read file header of [%s]"), aspect); + inrast_aspect = G_allocate_raster_buf(data_type_aspect); + } + /***************************************************/ G_debug(3, "number of rows %d",cellhd.rows); nrows = G_window_rows(); ncols = G_window_cols(); @@ -225,7 +279,6 @@ if(result2){ if ((outfd2 = G_open_raster_new (result2,data_type_output))< 0) G_fatal_error(_("Could not open <%s>"),result2); - } /* Process pixels */ for (row = 0; row < nrows; row++) @@ -239,6 +292,8 @@ // DCELL d_roh_w; DCELL d_solar; DCELL d_rnetd; + DCELL d_slope; + DCELL d_aspect; if(verbose) G_percent(row,nrows,2); /* read input maps */ @@ -252,6 +307,12 @@ G_fatal_error(_("Could not read from <%s>"),doy); if(G_get_raster_row(infd_tsw,inrast_tsw,row,data_type_tsw)<0) G_fatal_error(_("Could not read from <%s>"),tsw); + if(flag2->answer){ + if(G_get_raster_row(infd_slope,inrast_slope,row,data_type_slope)<0) + G_fatal_error(_("Could not read from <%s>"),slope); + if(G_get_raster_row(infd_aspect,inrast_aspect,row,data_type_aspect)<0) + G_fatal_error(_("Could not read from <%s>"),aspect); + } /*process the data */ for (col=0; col < ncols; col++) { @@ -310,6 +371,30 @@ d_tsw = (double) ((DCELL *) inrast_tsw)[col]; break; } + if(flag2->answer){ + switch(data_type_slope){ + case CELL_TYPE: + d_slope = (double) ((CELL *) inrast_slope)[col]; + break; + case FCELL_TYPE: + d_slope = (double) ((FCELL *) inrast_slope)[col]; + break; + case DCELL_TYPE: + d_slope = (double) ((DCELL *) inrast_slope)[col]; + break; + } + switch(data_type_aspect){ + case CELL_TYPE: + d_aspect = (double) ((CELL *) inrast_aspect)[col]; + break; + case FCELL_TYPE: + d_aspect = (double) ((FCELL *) inrast_aspect)[col]; + break; + case DCELL_TYPE: + d_aspect = (double) ((DCELL *) inrast_aspect)[col]; + break; + } + } if(G_is_d_null_value(&d_albedo)){ ((DCELL *) outrast1)[col] = -999.99; if (result2) @@ -334,8 +419,22 @@ ((DCELL *) outrast1)[col] = -999.99; if (result2) ((DCELL *) outrast2)[col] = -999.99; + }else if(flag2->answer){ + if(G_is_d_null_value(&d_slope)){ + ((DCELL *) outrast1)[col] = -999.99; + if (result2) + ((DCELL *) outrast2)[col] = -999.99; + }else if(G_is_d_null_value(&d_aspect)){ + ((DCELL *) outrast1)[col] = -999.99; + if (result2) + ((DCELL *) outrast2)[col] = -999.99; + } }else { - d_solar = solar_day(d_lat, d_doy, d_tsw ); + if(flag2->answer){ + d_solar = solar_day_3d(d_lat,d_doy,d_tsw,d_slope,d_aspect); + }else { + d_solar = solar_day(d_lat, d_doy, d_tsw ); + } if(result2){ d_rnetd = r_net_day(d_albedo,d_solar,d_tsw ); ((DCELL *) outrast2)[col] = d_rnetd; Modified: trunk/grassaddons/gipe/i.evapo.potrad/solar_day.c =================================================================== --- trunk/grassaddons/gipe/i.evapo.potrad/solar_day.c 2007-07-03 08:45:43 UTC (rev 912) +++ trunk/grassaddons/gipe/i.evapo.potrad/solar_day.c 2007-07-03 11:31:33 UTC (rev 913) @@ -9,17 +9,18 @@ double solar_day(double lat, double doy, double tsw ) { - double ws, cosun, n10_temp, delta, ds, result; + double ws, cosun, latrad, delta, deltarad, ds, result; ds = 1.0 + 0.01672 * sin(2*PI*(doy-93.5)/365.0); delta = 0.4093*sin((2*PI*doy/365)-1.39); + deltarad = delta*PI/180.0; + latrad = lat * PI / 180.0; - n10_temp = lat * PI / 180.0; - ws = acos(-tan(n10_temp)*tan(delta*PI/180.0)); - cosun = ws*sin(delta*PI/180.0)*sin(n10_temp)+cos(delta*PI/180.0)*cos(n10_temp)*sin(ws); - - result = ( cosun * 1367 * tsw ) / ( PI * ds * ds ); + ws = acos(-tan(latrad)*tan(deltarad)); + cosun = ws*sin(deltarad)*sin(latrad)+cos(deltarad)*cos(latrad)*sin(ws); + + result = ( cosun * 1367 * tsw ) / ( PI * ds * ds ); return result; Added: trunk/grassaddons/gipe/i.evapo.potrad/solar_day_3d.c =================================================================== --- trunk/grassaddons/gipe/i.evapo.potrad/solar_day_3d.c (rev 0) +++ trunk/grassaddons/gipe/i.evapo.potrad/solar_day_3d.c 2007-07-03 11:31:33 UTC (rev 913) @@ -0,0 +1,39 @@ +#include +#include +#include + +// Average Solar Diurnal Radiation after Bastiaanssen (1995) +// Includes Slope and aspect correction +// yann.chemin@gmail.com - Yann Chemin - LGPL, Copylefted, 2004. + +#define PI 3.1415927 + +double solar_day_3d(double lat, double doy, double tsw, double slope, double aspect ) +{ + double ws, costheta, latrad, delta, deltarad, ds, result; + double temp1, temp2, temp3, temp4, temp5; + double slrad, asprad; /*slope and aspect in radians*/ + + ds = 1.0 + 0.01672 * sin(2 * PI * (doy - 93.5) / 365.0); + delta = 0.4093 * sin((2 * PI * doy / 365) - 1.39); + deltarad = delta * PI / 180.0; + latrad = lat * PI / 180.0; + slrad = slope * PI / 180.0; + asprad = aspect * PI / 180.0; + + ws = acos(-tan(latrad)*tan(deltarad)); + + temp1 = sin(deltarad) * sin(latrad) * cos(slrad); + temp2 = sin(deltarad) * cos(latrad) * sin(slrad) * cos(asprad); + temp3 = cos(deltarad) * cos(latrad) * cos(slrad) * cos(ws*PI/180.0); + temp4 = cos(deltarad) * sin(slrad) * cos(asprad) * cos(ws*PI/180.0); + temp5 = cos(deltarad) * sin(slrad) * sin(asprad) * sin(ws*PI/180.0); + + costheta = (temp1 - temp2 + temp3 + temp4 + temp5) / cos(slrad); + + result = ( costheta * 1367 * tsw ) / ( PI * ds * ds ); + + return result; + +} + Modified: trunk/grassaddons/gipe/script_generator/l7_in_read.c =================================================================== --- trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-03 08:45:43 UTC (rev 912) +++ trunk/grassaddons/gipe/script_generator/l7_in_read.c 2007-07-03 11:31:33 UTC (rev 913) @@ -580,10 +580,27 @@ snprintf(sys_4,1000,"echo \"i.latitude input=%s.albedo latitude=%s.latitude --overwrite ; r.mapcalc %s.doy=%d ; r.mapcalc %s.tsw=0.7\" >> temp.txt", basedate, basedate, basedate, doy, basedate); /*Create a doy layer*/ system(sys_4); + system("echo \"\" >> temp.txt"); + /*DOWNLOAD/IMPORT SRTM*/ + system("echo \"#DOWNLOAD SRTM DEM 90m unfinished\" >> temp.txt"); + system("echo \"\" >> temp.txt"); + sprintf(sys_25,"echo \"wget -c ftp://ftp.glcf.umiacs.umd.edu/glcf/SRTM/WRS2_Tiles/p%s/SRTM_u03_p%sr%s/SRTM_u03_p%sr%s.tif.gz \" >> temp.txt",path,path,row,path,row); + system(sys_25); + system("echo \"\" >> temp.txt"); + system("echo \"#IMPORT SRTM DEM 90m unfinished\" >> temp.txt"); + system("echo \"\" >> temp.txt"); + sprintf(sys_26,"echo \"gzip -d SRTM_u03_p%sr%s.tif.gz \" >> temp.txt",path,row); + system(sys_26); + system("echo \"\" >> temp.txt"); + sprintf(sys_27,"echo \"r.in.gdal -o input=SRTM_u03_p%sr%s.tif output=%s.dem title=SRTM_u03\" >> temp.txt",path,row,basedate); + system(sys_27); + system("echo \"\" >> temp.txt"); + sprintf(sys_27,"echo \"r.slope.aspect elevation=%s.dem slope=%s.slope aspect=%s.aspect\" >> temp.txt",basedate,basedate,basedate); + system(sys_27); /*Calculate ETPOT (and Rnetd for future ETa calculations)*/ system("echo \"\" >> temp.txt"); system("echo \"#ETPOT\" >> temp.txt"); - snprintf(sys_5,1000,"echo \"i.evapo.potrad -r albedo=%s.albedo tempk=%s.61 lat=%s.latitude doy=%s.doy tsw=%s.tsw etpot=%s.etpot rnetd=%s.rnetd --overwrite ; r.null map=%s.rnetd setnull=-999.99 \" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate, basedate); + snprintf(sys_5,1000,"echo \"i.evapo.potrad -r -d albedo=%s.albedo tempk=%s.61 lat=%s.latitude doy=%s.doy tsw=%s.tsw slope=%s.slope aspect=%s.aspect etpot=%s.etpot rnetd=%s.rnetd --overwrite ; r.null map=%s.rnetd setnull=-999.99 \" >> temp.txt", basedate, basedate, basedate, basedate, basedate, basedate, basedate, basedate, basedate, basedate); system(sys_5); snprintf(sys_7,1000,"echo \"r.colors map=%s.etpot color=grey ; r.null map=%s.etpot setnull=-999.99\" >> temp.txt", basedate, basedate); system(sys_7); @@ -646,19 +663,6 @@ sprintf(sys_24,"echo \"i.eb.disp -s lai=%s.savi disp=%s.disp --overwrite\" >> temp.txt",basedate,basedate); system(sys_24); system("echo \"\" >> temp.txt"); - system("echo \"#DOWNLOAD SRTM DEM 90m unfinished\" >> temp.txt"); - system("echo \"\" >> temp.txt"); - sprintf(sys_25,"echo \"wget -c ftp://ftp.glcf.umiacs.umd.edu/glcf/SRTM/WRS2_Tiles/p%s/SRTM_u03_p%sr%s/SRTM_u03_p%sr%s.tif.gz \" >> temp.txt",path,path,row,path,row); - system(sys_25); - system("echo \"\" >> temp.txt"); - system("echo \"#IMPORT SRTM DEM 90m unfinished\" >> temp.txt"); - system("echo \"\" >> temp.txt"); - sprintf(sys_26,"echo \"gzip -d SRTM_u03_p%sr%s.tif.gz \" >> temp.txt",path,row); - system(sys_26); - system("echo \"\" >> temp.txt"); - sprintf(sys_27,"echo \"r.in.gdal -o input=SRTM_u03_p%sr%s.tif output=%s.dem title=SRTM_u03\" >> temp.txt",path,row,basedate); - system(sys_27); - system("echo \"\" >> temp.txt"); sprintf(sys_28,"echo \"r.colors map=%s.dem color=srtm\" >> temp.txt",basedate); system(sys_28); system("echo \"\" >> temp.txt"); From chemin at grass.itc.it Tue Jul 3 13:32:40 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Tue Jul 3 13:32:41 2007 Subject: [grass-addons] r914 - trunk/grassaddons/gipe/i.evapo.potrad Message-ID: <200707031132.l63BWe2O017888@grass.itc.it> Author: chemin Date: 2007-07-03 13:32:36 +0200 (Tue, 03 Jul 2007) New Revision: 914 Modified: trunk/grassaddons/gipe/i.evapo.potrad/main.c Log: Debug Modified: trunk/grassaddons/gipe/i.evapo.potrad/main.c =================================================================== --- trunk/grassaddons/gipe/i.evapo.potrad/main.c 2007-07-03 11:31:33 UTC (rev 913) +++ trunk/grassaddons/gipe/i.evapo.potrad/main.c 2007-07-03 11:32:36 UTC (rev 914) @@ -419,16 +419,14 @@ ((DCELL *) outrast1)[col] = -999.99; if (result2) ((DCELL *) outrast2)[col] = -999.99; - }else if(flag2->answer){ - if(G_is_d_null_value(&d_slope)){ - ((DCELL *) outrast1)[col] = -999.99; - if (result2) + }else if((flag2->answer)&&G_is_d_null_value(&d_slope)){ + ((DCELL *) outrast1)[col] = -999.99; + if (result2) ((DCELL *) outrast2)[col] = -999.99; - }else if(G_is_d_null_value(&d_aspect)){ - ((DCELL *) outrast1)[col] = -999.99; - if (result2) + }else if((flag2->answer)&&G_is_d_null_value(&d_aspect)){ + ((DCELL *) outrast1)[col] = -999.99; + if (result2) ((DCELL *) outrast2)[col] = -999.99; - } }else { if(flag2->answer){ d_solar = solar_day_3d(d_lat,d_doy,d_tsw,d_slope,d_aspect); From maldacker at grass.itc.it Tue Jul 3 17:18:38 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Tue Jul 3 17:18:40 2007 Subject: [grass-addons] r915 - trunk/grassaddons/v.path.obstacles Message-ID: <200707031518.l63FIc36021244@grass.itc.it> Author: maldacker Date: 2007-07-03 17:18:33 +0200 (Tue, 03 Jul 2007) New Revision: 915 Modified: trunk/grassaddons/v.path.obstacles/rotation_tree.c trunk/grassaddons/v.path.obstacles/rotation_tree.h trunk/grassaddons/v.path.obstacles/visibility.c Log: added the point inside polygon function to remove edges of the visibility graph if it's inside a polygon Modified: trunk/grassaddons/v.path.obstacles/rotation_tree.c =================================================================== --- trunk/grassaddons/v.path.obstacles/rotation_tree.c 2007-07-03 11:32:36 UTC (rev 914) +++ trunk/grassaddons/v.path.obstacles/rotation_tree.c 2007-07-03 15:18:33 UTC (rev 915) @@ -183,21 +183,3 @@ return pq_distance < e_distance ; } -/** dot product between qp and qr */ -double dot( struct Point * p, struct Point * q, struct Point * r ) -{ - double qp_x = p->x - q->x; - double qp_y = p->y - q->x; - double qr_x = r->x - q->x; - double qr_y = r->y - q->y; - return (qp_x * qr_x + qp_y * qr_y); -} - -double distance( struct Point * p, struct Point * q ) -{ - double dx = p->x - q->x; - double dy = p->y - q->y; - return sqrt( dx*dx + dy*dy); -} - - Modified: trunk/grassaddons/v.path.obstacles/rotation_tree.h =================================================================== --- trunk/grassaddons/v.path.obstacles/rotation_tree.h 2007-07-03 11:32:36 UTC (rev 914) +++ trunk/grassaddons/v.path.obstacles/rotation_tree.h 2007-07-03 15:18:33 UTC (rev 915) @@ -33,6 +33,8 @@ struct Point * right_brother; struct Point * father; struct Point * rightmost_son; + + int cat; }; struct Line Modified: trunk/grassaddons/v.path.obstacles/visibility.c =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-03 11:32:36 UTC (rev 914) +++ trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-03 15:18:33 UTC (rev 915) @@ -69,7 +69,8 @@ struct line_pnts* sites; int i; struct line_cats* cats; - int cat,type; + int cat =0; + int type; sites = Vect_new_line_struct(); cats = Vect_new_cats_struct(); @@ -93,9 +94,9 @@ G_message("For now %d and %d", index_point, index_line ); if ( type == GV_LINE ) - process_line(sites, points, &index_point, lines, &index_line, cat); + process_line(sites, points, &index_point, lines, &index_line, -1); else if ( type == GV_BOUNDARY ) - process_boundary(sites, points, &index_point, lines, &index_line, cat); + process_boundary(sites, points, &index_point, lines, &index_line, cat++); //else if ( type == GV_POINT ) @@ -113,6 +114,7 @@ (*points)[*index_point].x = sites->x[i]; (*points)[*index_point].y = sites->y[i]; + (*points)[*index_point].cat = cat; if ( i == 0 ) { @@ -155,7 +157,7 @@ for ( i = 0; i < n-1; i++ ) { - + (*points)[*index_point].cat = cat; (*points)[*index_point].x = sites->x[i]; (*points)[*index_point].y = sites->y[i]; @@ -283,6 +285,29 @@ } } +/** tests if the point (x, y ) is inside the boundary of p +*/ +int point_inside( struct Point * p, double x, double y ) +{ + int c = 0; + struct Point * n1 = p; + struct Point * n2 = other1(p); + + while ( n2 != p ) + { + if ( ( ( n2->y <=y && y < n1->y ) || + ( n1->y <= y && y< n2->y ) ) && + (x < (n1->x - n2->x) * (y - n2->y) / (n1->y - n2->y) + n2->x)) + c = !c; + + n1 = other1(n1); + n2 = other1(n2); + } + + return c; +} + + /** for a pair (p, q) of points, add the edge pq if their are visibile to each other */ void handle( struct Point* p, struct Point* q, struct Map_info * out ) @@ -321,7 +346,8 @@ { p->vis = q->vis; } - + + report(p, q, out ); } else if ( segment1(q) == p->vis && segment1(q) != NULL) @@ -332,7 +358,9 @@ else p->vis = q->vis ; - report( p,q, out ); + // check that p and q are not on the same boundary and that the edge pq is inside the boundary + if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) + report( p,q, out ); } else if ( segment2(q) == p->vis && segment2(q) != NULL ) { @@ -341,7 +369,9 @@ else p->vis = q->vis; - report( p,q, out ); + // check that p and q are not on the same boundary and that the edge pq is inside the boundary + if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) + report( p,q, out ); } else if ( before(p,q, p->vis ) ) { @@ -353,12 +383,14 @@ p->vis = segment1(q); else if ( !left_turn(p, q, other1(q) ) && left_turn( p, q, other2(q))) p->vis = segment2(q); - else if ( (dot(p,q, other1(q) )/ distance(q, other1(q)) ) < (dot(p,q,other2(q))/distance(q, other2(q))) ) + else if ( left_turn( q, other2(q), other1(q) ) ) p->vis = segment1(q); else p->vis = segment2(q); - report(p,q,out); + // check that p and q are not on the same boundary and that the edge pq is inside the boundary + if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) + report(p,q,out); } } From maldacker at grass.itc.it Tue Jul 3 17:36:42 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Tue Jul 3 17:36:44 2007 Subject: [grass-addons] r916 - trunk/grassaddons/v.path.obstacles Message-ID: <200707031536.l63Fagpd021336@grass.itc.it> Author: maldacker Date: 2007-07-03 17:36:38 +0200 (Tue, 03 Jul 2007) New Revision: 916 Added: trunk/grassaddons/v.path.obstacles/geometry.c trunk/grassaddons/v.path.obstacles/geometry.h Log: put all the geomtry functions here Added: trunk/grassaddons/v.path.obstacles/geometry.c =================================================================== --- trunk/grassaddons/v.path.obstacles/geometry.c (rev 0) +++ trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-03 15:36:38 UTC (rev 916) @@ -0,0 +1,126 @@ +/**************************************************************** + * MODULE: v.path.obstacles + * + * AUTHOR(S): Maximilian Maldacker + * + * + * COPYRIGHT: (C) 2002-2005 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 "geometry.h" + +/** returns the square distance between point q and segment e +*/ +double segment_sqdistance( struct Point * q, struct Line * e ) +{ + + double e2e1x = e->p1->x - e->p2->x ; + double e2e1y = e->p1->y - e->p2->y; + + double qe1x = q->x - e->p1->x; + double qe1y = q->y - e->p1->y; + + double qe2x = q->x - e->p2->x; + double qe2y = q->y - e->p2->y; + + double s = e2e1x * qe2x + e2e1y * qe2y; + double t; + + if ( s <= 0 ) + return qe2x * qe2x + qe2y * qe2y; + + t = e2e1x * e2e1x + e2e1y * e2e1y; + + if ( s >= t ) + return qe1x * qe1x + qe1y * qe1y; + + return qe2x * qe2x + qe2y * qe2y - s * s / t ; + +} + +/** true if q lies nearer to p than segment e +*/ +int before( struct Point * p, struct Point * q, struct Line * e ) +{ + /* first determine the square distance between p and e */ + + if ( e == NULL ) + return 1; + + double e_distance = segment_sqdistance(p, e); + double pqx = q->x - p->x; + double pqy = q->y - p->y; + double pq_distance = pqx*pqx + pqy*pqy; + + return pq_distance < e_distance ; +} + + + +/** returns true if p3 is left of the directed line p1p2 +*/ +int left_turn( struct Point * p1, struct Point * p2, struct Point * p3 ) +{ + double a, b, c, d; + double r; + + if ( p3->y == PORT_DOUBLE_MAX) + { + return ( p1->x < p2->x || (p1->x == p2->x && p1->y < p2->y ) ); + } + else + { + a = p1->x - p2->x; + b = p1->y - p2->y; + c = p3->x - p2->x; + d = p3->y - p2->y; + + return a*d-b*c < 0.0; + } +} + +/** returns true if p is inbetween the segment e along the x axis +*/ +int in_between( struct Point * p, struct Line * e ) +{ + int a = e->p1->x < p->x && e->p2->x > p->x ; + int b = e->p2->x < p->x && e->p1->x > p->x; + + return a || b; +} + +/** returns true if p is above the segment e ( y axis ) +*/ +int below( struct Point * p, struct Line * e ) +{ + return e->p1->y < p->y || e->p2->y < p->y ; +} + +/** tests if the point (x, y ) is inside the boundary of p +*/ +int point_inside( struct Point * p, double x, double y ) +{ + int c = 0; + struct Point * n1 = p; + struct Point * n2 = other1(p); + + while ( n2 != p ) + { + if ( ( ( n2->y <=y && y < n1->y ) || + ( n1->y <= y && y< n2->y ) ) && + (x < (n1->x - n2->x) * (y - n2->y) / (n1->y - n2->y) + n2->x)) + c = !c; + + n1 = other1(n1); + n2 = other1(n2); + } + + return c; +} + Property changes on: trunk/grassaddons/v.path.obstacles/geometry.c ___________________________________________________________________ Name: svn:eol-style + native Added: trunk/grassaddons/v.path.obstacles/geometry.h =================================================================== --- trunk/grassaddons/v.path.obstacles/geometry.h (rev 0) +++ trunk/grassaddons/v.path.obstacles/geometry.h 2007-07-03 15:36:38 UTC (rev 916) @@ -0,0 +1,35 @@ +/**************************************************************** + * MODULE: v.path.obstacles + * + * AUTHOR(S): Maximilian Maldacker + * + * + * COPYRIGHT: (C) 2002-2005 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. + * + ****************************************************************/ + +#ifndef GEOMETRY_H +#define GEOMETRY_H + +#include +#include +#include +#include +#include +#include "rotation_tree.h" + +int point_inside( struct Point * p, double x, double y ); +int below( struct Point * p, struct Line * e ); +int in_between( struct Point * p, struct Line * e ); +int left_turn( struct Point * p1, struct Point * p2, struct Point * p3 ); +int before( struct Point * p, struct Point * q, struct Line * e ); +double segment_sqdistance( struct Point * q, struct Line * e ); + + + +#endif Property changes on: trunk/grassaddons/v.path.obstacles/geometry.h ___________________________________________________________________ Name: svn:eol-style + native From maldacker at grass.itc.it Tue Jul 3 17:37:06 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Tue Jul 3 17:37:08 2007 Subject: [grass-addons] r917 - trunk/grassaddons/v.path.obstacles Message-ID: <200707031537.l63Fb6ah021356@grass.itc.it> Author: maldacker Date: 2007-07-03 17:37:00 +0200 (Tue, 03 Jul 2007) New Revision: 917 Modified: trunk/grassaddons/v.path.obstacles/main.c trunk/grassaddons/v.path.obstacles/rotation_tree.c trunk/grassaddons/v.path.obstacles/rotation_tree.h trunk/grassaddons/v.path.obstacles/visibility.c trunk/grassaddons/v.path.obstacles/visibility.h Log: changed the organisation of the function to make it clearer -- all geomtry related function ( angles, distance, .. ) are in geomtry.h -- everything related to the rotation tree is in rotation_tree.h -- the rest of the algorithm is in visibility.h, so the main loop and the handle and report functions -- the loading of the map is done in main.c This way it is easy to port the algorithm to another software as everything that's GRASS related is in main.c except for the report function Modified: trunk/grassaddons/v.path.obstacles/main.c =================================================================== --- trunk/grassaddons/v.path.obstacles/main.c 2007-07-03 15:36:38 UTC (rev 916) +++ trunk/grassaddons/v.path.obstacles/main.c 2007-07-03 15:37:00 UTC (rev 917) @@ -19,6 +19,11 @@ #include #include "visibility.h" +void load_lines( struct Map_info * map, struct Point ** points, int * num_points, struct Line ** lines, int * num_lines ); +void count( struct Map_info * map, int * num_points, int * num_lines); +void process_line( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat); +void process_boundary( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat); + int main( int argc, char* argv[]) { struct Map_info in, out; @@ -83,3 +88,185 @@ Vect_close(&in); exit(EXIT_SUCCESS); } + +/** counts the number of individual segments ( boundaries and lines ) and vertices +*/ +void count( struct Map_info * map, int * num_points, int * num_lines) +{ + int index_line = 0; + int index_point = 0; + struct line_pnts* sites; + struct line_cats* cats; + int type,i; + + sites = Vect_new_line_struct(); + cats = Vect_new_cats_struct(); + + G_message("N lines %d", map->plus.n_lines); + + for( i = 1; i <= map->plus.n_lines ; i++ ) + { + + type = Vect_read_line( map, sites, cats, i); + + if ( type != GV_LINE && type != GV_BOUNDARY) + continue; + + if ( type == GV_LINE ) + { + index_point+= sites->n_points; + index_line+= sites->n_points-1; + } + else if ( type == GV_BOUNDARY ) + { + index_point+= sites->n_points-1; + index_line+= sites->n_points-1; + } + + + } + + *num_points = index_point; + *num_lines = index_line; + +} + + +/** Get the lines and boundaries from the map and load them in an array +*/ +void load_lines( struct Map_info * map, struct Point ** points, int * num_points, struct Line ** lines, int * num_lines ) +{ + int index_line = 0; + int index_point = 0; + struct line_pnts* sites; + int i; + struct line_cats* cats; + int cat =0; + int type; + + sites = Vect_new_line_struct(); + cats = Vect_new_cats_struct(); + + count( map, num_points, num_lines); + + *points = G_malloc( *num_points * sizeof( struct Point )); + *lines = G_malloc( *num_lines * sizeof( struct Line )); + + G_message("We have %d points and %d segments", *num_points, *num_lines ); + + + while( ( type = Vect_read_next_line( map, sites, cats) ) > -1 ) + { + + if ( type != GV_LINE && type != GV_BOUNDARY) + continue; + + Vect_cat_get (cats, 1, &cat); + + G_message("For now %d and %d", index_point, index_line ); + + if ( type == GV_LINE ) + process_line(sites, points, &index_point, lines, &index_line, -1); + else if ( type == GV_BOUNDARY ) + process_boundary(sites, points, &index_point, lines, &index_line, cat++); + //else if ( type == GV_POINT ) + + + } +} + +/** extract all segments from the line +*/ +void process_line( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat) +{ + int n = sites->n_points; + int i; + + for ( i = 0; i < n; i++ ) + { + + (*points)[*index_point].x = sites->x[i]; + (*points)[*index_point].y = sites->y[i]; + (*points)[*index_point].cat = cat; + + if ( i == 0 ) + { + (*points)[*index_point].line1 = NULL; + (*points)[*index_point].line2 = &((*lines)[*index_line]); + } + else if ( i == n-1 ) + { + (*points)[*index_point].line1 = &((*lines)[(*index_line)-1]); + (*points)[*index_point].line2 = NULL; + } + else + { + (*points)[*index_point].line1 = &((*lines)[(*index_line)-1]); + (*points)[*index_point].line2 = &((*lines)[*index_line]); + } + + (*points)[*index_point].left_brother = NULL; + (*points)[*index_point].right_brother = NULL; + (*points)[*index_point].father = NULL; + (*points)[*index_point].rightmost_son = NULL; + + + (*index_point)++; + + if ( i < n-1 ) + { + (*lines)[*index_line].p1 = &((*points)[(*index_point)-1]); + (*lines)[*index_line].p2 = &((*points)[*index_point]); + (*index_line)++; + } + } +} + +/** extract all segments from the boundary +*/ +void process_boundary( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat) +{ + int n = sites->n_points; + int i; + + for ( i = 0; i < n-1; i++ ) + { + (*points)[*index_point].cat = cat; + (*points)[*index_point].x = sites->x[i]; + (*points)[*index_point].y = sites->y[i]; + + if ( i == 0 ) + { + (*points)[*index_point].line1 = &((*lines)[(*index_line)+n-2]); + (*points)[*index_point].line2 = &((*lines)[*index_line]); + } + else + { + (*points)[*index_point].line1 = &((*lines)[(*index_line)-1]); + (*points)[*index_point].line2 = &((*lines)[*index_line]); + } + + (*points)[*index_point].left_brother = NULL; + (*points)[*index_point].right_brother = NULL; + (*points)[*index_point].father = NULL; + (*points)[*index_point].rightmost_son = NULL; + + + (*index_point)++; + + if ( i == n-2 ) + { + (*lines)[*index_line].p1 = &((*points)[(*index_point)-1]); + (*lines)[*index_line].p2 = &((*points)[(*index_point)-n+1]); + } + else + { + (*lines)[*index_line].p1 = &((*points)[(*index_point)-1]); + (*lines)[*index_line].p2 = &((*points)[*index_point]); + } + + (*index_line)++; + } + +} + Modified: trunk/grassaddons/v.path.obstacles/rotation_tree.c =================================================================== --- trunk/grassaddons/v.path.obstacles/rotation_tree.c 2007-07-03 15:36:38 UTC (rev 916) +++ trunk/grassaddons/v.path.obstacles/rotation_tree.c 2007-07-03 15:37:00 UTC (rev 917) @@ -138,48 +138,3 @@ return p->line2->p1; } -double segment_sqdistance( struct Point * q, struct Line * e ) -{ - - double e2e1x = e->p1->x - e->p2->x ; - double e2e1y = e->p1->y - e->p2->y; - - double qe1x = q->x - e->p1->x; - double qe1y = q->y - e->p1->y; - - double qe2x = q->x - e->p2->x; - double qe2y = q->y - e->p2->y; - - double s = e2e1x * qe2x + e2e1y * qe2y; - double t; - - if ( s <= 0 ) - return qe2x * qe2x + qe2y * qe2y; - - t = e2e1x * e2e1x + e2e1y * e2e1y; - - if ( s >= t ) - return qe1x * qe1x + qe1y * qe1y; - - return qe2x * qe2x + qe2y * qe2y - s * s / t ; - -} - - -int before( struct Point * p, struct Point * q, struct Line * e ) -{ - /* true if q lies nearer to p than segment e*/ - - /* first determine the square distance between p and e */ - - if ( e == NULL ) - return 1; - - double e_distance = segment_sqdistance(p, e); - double pqx = q->x - p->x; - double pqy = q->y - p->y; - double pq_distance = pqx*pqx + pqy*pqy; - - return pq_distance < e_distance ; -} - Modified: trunk/grassaddons/v.path.obstacles/rotation_tree.h =================================================================== --- trunk/grassaddons/v.path.obstacles/rotation_tree.h 2007-07-03 15:36:38 UTC (rev 916) +++ trunk/grassaddons/v.path.obstacles/rotation_tree.h 2007-07-03 15:37:00 UTC (rev 917) @@ -45,7 +45,9 @@ void add_rightmost(struct Point* p, struct Point* q); void add_leftof(struct Point* p, struct Point* q); + void remove_point(struct Point* p); + struct Point* right_brother(struct Point* p); struct Point* left_brother(struct Point* p); struct Point* father( struct Point* p); @@ -55,10 +57,7 @@ struct Line * segment2( struct Point * p ); struct Point * other1( struct Point * p ); struct Point * other2( struct Point * p ); -int before( struct Point * p, struct Point * q, struct Line * e ); -double segment_sqdistance( struct Point * p, struct Line * e ); -double distance( struct Point * p, struct Point * q ); Modified: trunk/grassaddons/v.path.obstacles/visibility.c =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-03 15:36:38 UTC (rev 916) +++ trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-03 15:37:00 UTC (rev 917) @@ -19,223 +19,6 @@ #include "visibility.h" -void count( struct Map_info * map, int * num_points, int * num_lines) -{ - int index_line = 0; - int index_point = 0; - struct line_pnts* sites; - struct line_cats* cats; - int type,i; - - sites = Vect_new_line_struct(); - cats = Vect_new_cats_struct(); - - G_message("N lines %d", map->plus.n_lines); - - for( i = 1; i <= map->plus.n_lines ; i++ ) - { - - type = Vect_read_line( map, sites, cats, i); - - if ( type != GV_LINE && type != GV_BOUNDARY) - continue; - - if ( type == GV_LINE ) - { - index_point+= sites->n_points; - index_line+= sites->n_points-1; - } - else if ( type == GV_BOUNDARY ) - { - index_point+= sites->n_points-1; - index_line+= sites->n_points-1; - } - - - } - - *num_points = index_point; - *num_lines = index_line; - -} - - -/** Get the lines from the map and load them in an array -*/ -void load_lines( struct Map_info * map, struct Point ** points, int * num_points, struct Line ** lines, int * num_lines ) -{ - int index_line = 0; - int index_point = 0; - struct line_pnts* sites; - int i; - struct line_cats* cats; - int cat =0; - int type; - - sites = Vect_new_line_struct(); - cats = Vect_new_cats_struct(); - - count( map, num_points, num_lines); - - *points = G_malloc( *num_points * sizeof( struct Point )); - *lines = G_malloc( *num_lines * sizeof( struct Line )); - - G_message("We have %d points and %d segments", *num_points, *num_lines ); - - - while( ( type = Vect_read_next_line( map, sites, cats) ) > -1 ) - { - - if ( type != GV_LINE && type != GV_BOUNDARY) - continue; - - Vect_cat_get (cats, 1, &cat); - - G_message("For now %d and %d", index_point, index_line ); - - if ( type == GV_LINE ) - process_line(sites, points, &index_point, lines, &index_line, -1); - else if ( type == GV_BOUNDARY ) - process_boundary(sites, points, &index_point, lines, &index_line, cat++); - //else if ( type == GV_POINT ) - - - } -} - - -void process_line( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat) -{ - int n = sites->n_points; - int i; - - for ( i = 0; i < n; i++ ) - { - - (*points)[*index_point].x = sites->x[i]; - (*points)[*index_point].y = sites->y[i]; - (*points)[*index_point].cat = cat; - - if ( i == 0 ) - { - (*points)[*index_point].line1 = NULL; - (*points)[*index_point].line2 = &((*lines)[*index_line]); - } - else if ( i == n-1 ) - { - (*points)[*index_point].line1 = &((*lines)[(*index_line)-1]); - (*points)[*index_point].line2 = NULL; - } - else - { - (*points)[*index_point].line1 = &((*lines)[(*index_line)-1]); - (*points)[*index_point].line2 = &((*lines)[*index_line]); - } - - (*points)[*index_point].left_brother = NULL; - (*points)[*index_point].right_brother = NULL; - (*points)[*index_point].father = NULL; - (*points)[*index_point].rightmost_son = NULL; - - - (*index_point)++; - - if ( i < n-1 ) - { - (*lines)[*index_line].p1 = &((*points)[(*index_point)-1]); - (*lines)[*index_line].p2 = &((*points)[*index_point]); - (*index_line)++; - } - } -} - - -void process_boundary( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat) -{ - int n = sites->n_points; - int i; - - for ( i = 0; i < n-1; i++ ) - { - (*points)[*index_point].cat = cat; - (*points)[*index_point].x = sites->x[i]; - (*points)[*index_point].y = sites->y[i]; - - if ( i == 0 ) - { - (*points)[*index_point].line1 = &((*lines)[(*index_line)+n-2]); - (*points)[*index_point].line2 = &((*lines)[*index_line]); - } - else - { - (*points)[*index_point].line1 = &((*lines)[(*index_line)-1]); - (*points)[*index_point].line2 = &((*lines)[*index_line]); - } - - (*points)[*index_point].left_brother = NULL; - (*points)[*index_point].right_brother = NULL; - (*points)[*index_point].father = NULL; - (*points)[*index_point].rightmost_son = NULL; - - - (*index_point)++; - - if ( i == n-2 ) - { - (*lines)[*index_line].p1 = &((*points)[(*index_point)-1]); - (*lines)[*index_line].p2 = &((*points)[(*index_point)-n+1]); - } - else - { - (*lines)[*index_line].p1 = &((*points)[(*index_point)-1]); - (*lines)[*index_line].p2 = &((*points)[*index_point]); - } - - (*index_line)++; - } - -} - -/** returns true if p3 is left of the directed line p1p2 -*/ -int left_turn( struct Point * p1, struct Point * p2, struct Point * p3 ) -{ - double a, b, c, d; - double r; - - if ( p3->y == PORT_DOUBLE_MAX) - { - return ( p1->x < p2->x || (p1->x == p2->x && p1->y < p2->y ) ); - } - else - { - a = p1->x - p2->x; - b = p1->y - p2->y; - c = p3->x - p2->x; - d = p3->y - p2->y; - - return a*d-b*c < 0.0; - } -} - -/** returns true if p is inbetween the segment e along the x axis -*/ -int in_between( struct Point * p, struct Line * e ) -{ - int a = e->p1->x < p->x && e->p2->x > p->x ; - int b = e->p2->x < p->x && e->p1->x > p->x; - - return a || b; -} - -/** returns true if p is above the segment e ( y axis ) -*/ -int below( struct Point * p, struct Line * e ) -{ - return e->p1->y < p->y || e->p2->y < p->y ; -} - - /** for all points initiate their vis line to the one directly below */ void init_vis( struct Point * points, int num_points, struct Line * lines, int num_lines ) @@ -285,29 +68,8 @@ } } -/** tests if the point (x, y ) is inside the boundary of p -*/ -int point_inside( struct Point * p, double x, double y ) -{ - int c = 0; - struct Point * n1 = p; - struct Point * n2 = other1(p); - while ( n2 != p ) - { - if ( ( ( n2->y <=y && y < n1->y ) || - ( n1->y <= y && y< n2->y ) ) && - (x < (n1->x - n2->x) * (y - n2->y) / (n1->y - n2->y) + n2->x)) - c = !c; - - n1 = other1(n1); - n2 = other1(n2); - } - - return c; -} - /** for a pair (p, q) of points, add the edge pq if their are visibile to each other */ void handle( struct Point* p, struct Point* q, struct Map_info * out ) @@ -416,26 +178,6 @@ G_free(tmpy); } - -/** compare the points along the x axis -*/ -int cmp_points(struct Point * v1, struct Point* v2) { - struct Point *p1, *p2; - p1 = (struct Point*) v1; - p2 = (struct Point*) v2; - - if( p1->x < p2->x ) - return 1; - else if( p1->x > p2->x ) - return -1; - else if ( p1->y < p2->y ) - return 1; - else if ( p1->y > p2->y ) - return -1; - else - return 0; -} - /** the algorithm that computes the visibility graph */ int construct_visibility ( struct Point * points, int num_points, struct Line * lines, int num_lines, struct Map_info * out ) @@ -460,27 +202,13 @@ p_infinity->left_brother = NULL; p_infinity->right_brother = NULL; p_infinity->rightmost_son = NULL; - - - for ( i = 0 ; i < num_points ; i++ ) - G_message("Point %d with line %d and %d", &points[i], points[i].line1, points[i].line2 ); - for( i = 0 ; i < num_lines ; i++ ) - G_message("Line %d with points %d and %d", &lines[i], lines[i].p1, lines[i].p2 ); - - G_message("Initialisation of the stack ... "); init_stack(num_points); - - G_message("Sorting the points by decreasing order..."); /* sort points in decreasing x order*/ quickSort( points, 0, num_points-1 ); - - G_message("initialisation of the vis..."); init_vis( points, num_points, lines, num_lines ); - - - G_message("Initialisation of the rotation tree..."); + add_rightmost( p_ninfinity, p_infinity ); for ( i = 0; i < num_points ; i ++ ) @@ -490,10 +218,6 @@ push( &points[0] ); - int count = 0; - - G_message("Start of the main loop ... "); - /* main loop */ while( !empty_stack() ) { @@ -506,7 +230,6 @@ if ( q != p_ninfinity ) { handle(p,q, out); - count++; } z = left_brother(q); @@ -577,6 +300,24 @@ stack = G_malloc( size * sizeof( struct Point ) ); } +/** compare the points along the x axis +*/ +int cmp_points(struct Point * v1, struct Point* v2) { + struct Point *p1, *p2; + p1 = (struct Point*) v1; + p2 = (struct Point*) v2; + + if( p1->x < p2->x ) + return 1; + else if( p1->x > p2->x ) + return -1; + else if ( p1->y < p2->y ) + return 1; + else if ( p1->y > p2->y ) + return -1; + else + return 0; +} void quickSort( struct Point a[], int l, int r) { Modified: trunk/grassaddons/v.path.obstacles/visibility.h =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.h 2007-07-03 15:36:38 UTC (rev 916) +++ trunk/grassaddons/v.path.obstacles/visibility.h 2007-07-03 15:37:00 UTC (rev 917) @@ -21,17 +21,12 @@ #include #include #include +#include "geometry.h" #include "rotation_tree.h" -void load_lines( struct Map_info *map, struct Point ** points, int * num_points, struct Line ** lines, int * num_lines ); -void process_boundary( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat); -void process_line( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat); int construct_visibility( struct Point * points, int num_points, struct Line * lines, int num_lines, struct Map_info* out ); -int cmp_points(struct Point * v1, struct Point* v2); -int turn_left( struct Point p1, struct Point p2, struct Point p3 ); - void handle( struct Point* p, struct Point* q, struct Map_info * out ); void report( struct Point * p, struct Point * q, struct Map_info * out ); @@ -43,10 +38,12 @@ int empty_stack(); void init_stack(); +static int stack_index; +static struct Point ** stack; + +int cmp_points(struct Point * v1, struct Point* v2); void quickSort( struct Point a[], int l, int r); int partition( struct Point a[], int l, int r); -static int stack_index; -static struct Point ** stack; #endif From maldacker at grass.itc.it Tue Jul 3 17:39:03 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Tue Jul 3 17:39:04 2007 Subject: [grass-addons] r918 - trunk/grassaddons/v.path.obstacles Message-ID: <200707031539.l63Fd3Xb021411@grass.itc.it> Author: maldacker Date: 2007-07-03 17:39:00 +0200 (Tue, 03 Jul 2007) New Revision: 918 Modified: trunk/grassaddons/v.path.obstacles/description.html Log: update of the description Modified: trunk/grassaddons/v.path.obstacles/description.html =================================================================== --- trunk/grassaddons/v.path.obstacles/description.html 2007-07-03 15:37:00 UTC (rev 917) +++ trunk/grassaddons/v.path.obstacles/description.html 2007-07-03 15:39:00 UTC (rev 918) @@ -3,7 +3,7 @@ v.path.obstacles Computes the visibility graph of a map containing lines. This is the graph with vertices the end point of the lines and the edges are between two visibiles vertices. Two points are visibible if there no segments in between them, i.e. there are no lines e where the segment pq intersects it.

-The first argument is the input map. The module will only take in account the first segment of every lines. For the algorithm to work, lines must not be intersecting. +The first argument is the input map. It supports lines and boudaries ( so areas ). For the algorithm to work, lines must not be intersecting.

 input=map
 
@@ -36,4 +36,4 @@ Maximilian Maldacker -

Last changed: $Date: 2007/06/19 04:21:32 $ +

Last changed: Date: 03/07/2007 From bundala at grass.itc.it Tue Jul 3 21:32:34 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Tue Jul 3 21:32:36 2007 Subject: [grass-addons] r919 - trunk/grassaddons/v.generalize Message-ID: <200707031932.l63JWY9V023891@grass.itc.it> Author: bundala Date: 2007-07-03 21:32:32 +0200 (Tue, 03 Jul 2007) New Revision: 919 Modified: trunk/grassaddons/v.generalize/main.c Log: Added Alfa and Beta parameters in Snakes Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-03 15:39:00 UTC (rev 918) +++ trunk/grassaddons/v.generalize/main.c 2007-07-03 19:32:32 UTC (rev 919) @@ -42,10 +42,10 @@ char *mapset; struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out, *thresh_opt, *method_opt, *look_ahead_opt; - struct Option *iterations_opt, *cat_opt; + struct Option *iterations_opt, *cat_opt, *alfa_opt, *beta_opt; int with_z; int total_input, total_output; /* Number of points in the input/output map respectively */ - double thresh; + double thresh, alfa, beta; int method; int look_ahead, iterations; RANGE *ranges; @@ -71,15 +71,15 @@ method_opt->options = "douglas,lang,reduction,reumann,boyle,distance_weighting,chaiken,hermite,snakes"; method_opt->answer = "douglas"; - method_opt->descriptions = "douglas;Douglass-Peucker Algorithm;" - "lang;Lang Simplification Algorithm;" - "reduction;Vertex Reduction Algorithm eliminates points close to each other;" - "reumann;Reumann-Witkam Algorithm;" - "boyle;Boyle's Forward-Looking Algorithm;" - "distance_weighting;McMaster's Distance-Weighting Algorithm;" - "chaiken;Chaiken's Algorithm;" - "hermite;Interpolation by Cubic Hermite Splines;" - "snakes;Snakes method for line smoothing;"; + method_opt->descriptions = _("douglas;Douglass-Peucker Algorithm;" + "lang;Lang Simplification Algorithm;" + "reduction;Vertex Reduction Algorithm eliminates points close to each other;" + "reumann;Reumann-Witkam Algorithm;" + "boyle;Boyle's Forward-Looking Algorithm;" + "distance_weighting;McMaster's Distance-Weighting Algorithm;" + "chaiken;Chaiken's Algorithm;" + "hermite;Interpolation by Cubic Hermite Splines;" + "snakes;Snakes method for line smoothing;"); method_opt->description = _("Line simplification/smoothing algorithm"); thresh_opt = G_define_option(); @@ -97,6 +97,20 @@ look_ahead_opt->answer = "7"; look_ahead_opt->description = _("Look-ahead parameter"); + alfa_opt = G_define_option(); + alfa_opt->key = "alfa"; + alfa_opt->type = TYPE_DOUBLE; + alfa_opt->required = YES; + alfa_opt->answer = "1.0"; + alfa_opt->description = _("Snakes alfa parameter"); + + beta_opt = G_define_option(); + beta_opt->key = "beta"; + beta_opt->type = TYPE_DOUBLE; + beta_opt->required = YES; + beta_opt->answer = "1.0"; + beta_opt->description = _("Snakes beta parameter"); + iterations_opt = G_define_option(); iterations_opt->key = "iterations"; iterations_opt->type = TYPE_INTEGER; @@ -118,6 +132,8 @@ thresh = atof(thresh_opt->answer); look_ahead = atoi(look_ahead_opt->answer); + alfa = atof(alfa_opt->answer); + beta = atof(beta_opt->answer); iterations = atoi(iterations_opt->answer); @@ -224,7 +240,7 @@ after = hermite(Points, thresh, with_z); } else { - after = snakes(Points, (double)1.0, (double)1.0, with_z); + after = snakes(Points, alfa, beta, with_z); }; }; From barton at grass.itc.it Wed Jul 4 08:13:11 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Jul 4 08:13:40 2007 Subject: [grass-addons] r920 - trunk/grassaddons/gui Message-ID: <200707040613.l646DBhV000459@grass.itc.it> Author: barton Date: 2007-07-04 08:10:53 +0200 (Wed, 04 Jul 2007) New Revision: 920 Modified: trunk/grassaddons/gui/location_wizard.py Log: Major overhaul of location wizard. Close to being able to create valid PROJ.4 strings now. Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-07-03 19:32:32 UTC (rev 919) +++ trunk/grassaddons/gui/location_wizard.py 2007-07-04 06:10:53 UTC (rev 920) @@ -15,9 +15,6 @@ import gui_modules.cmd as cmd global coordsys -global georeffile -global datum -global transform global north global south global east @@ -26,9 +23,6 @@ global wizerror coordsys = '' -georeffile = '' -datum = '' -transform = '' north = '' south = '' east = '' @@ -77,19 +71,339 @@ size=size) +class DatabasePage(TitledPage): + def __init__(self, wizard, parent, grassdatabase): + TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") + + self.grassdatabase = grassdatabase + self.location = '' + + # buttons + self.bbrowse = self.MakeButton("Browse...") + + # text controls + self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, -1)) + self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1)) + + # layout + self.sizer.Add(self.MakeRLabel("GIS Data Directory:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=2) + self.sizer.Add(self.tgisdbase,0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=3) + self.sizer.Add(self.bbrowse, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=4) + # + self.sizer.Add(self.MakeRLabel("Project Location"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=2) + self.sizer.Add(self.tlocation,0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=3) + self.sizer.Add(self.MakeRLabel("(projection/coordinate system)"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=4) + + # bindings + self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged) + + def OnBrowse(self, event): + dlg = wx.DirDialog(self, "Choose GRASS data directory:", os.getcwd(),wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + self.grassdatabase = dlg.GetPath() + self.tgisdbase.SetValue(self.grassdatabase) + dlg.Destroy() + + def onPageChanging(self,event=None): + if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())): + dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\ + % str(self.tlocation.GetValue()),"Could not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + event.Veto() + return + + if not self.tlocation.GetValue(): + dlg = wx.MessageDialog(self, "Could not create new location: location not set "\ + ,"Could not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + event.Veto() + return + + self.location = self.tlocation.GetValue() + self.grassdatabase = self.tgisdbase.GetValue() + + def OnPageChanged(self,event=None): + self.grassdatabase = self.tgisdbase.GetValue() + self.location = self.tlocation.GetValue() + + +class CoordinateSystemPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose coordinate system for location") + + self.parent = parent + global coordsys + + # toggles + self.radio1 = wx.RadioButton( self, -1, " Select coordinate system " , style = wx.RB_GROUP) + self.radio2 = wx.RadioButton( self, -1, " Select EPSG code for coordinate system " ) + self.radio3 = wx.RadioButton( self, -1, " Use coordinate system of selected georeferenced file " ) + self.radio4 = wx.RadioButton( self, -1, " Create custom PROJ.4 parameters string for coordinate system " ) + self.radio5 = wx.RadioButton( self, -1, " Create arbitrary non-earth coordinate system (XY)" ) + + # layout + self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2) + self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2) + self.sizer.Add(self.radio3, 0, wx.ALIGN_LEFT, row=3, col=2) + self.sizer.Add(self.radio4, 0, wx.ALIGN_LEFT, row=4, col=2) + self.sizer.Add(self.radio5, 0, wx.ALIGN_LEFT, row=5, col=2) + + # bindings + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio3.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio4.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio5.GetId()) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) + + def OnPageChange(self,event=None): + global coordsys + if not coordsys: + wx.MessageBox('You must select a coordinate system') + event.Veto() + + if coordsys == "xy": + self.parent.bboxpage.cstate.Enable(False) + else: + self.parent.bboxpage.cstate.Enable(True) + + def SetVal(self,event): + global coordsys + if event.GetId() == self.radio1.GetId(): + coordsys = "proj" + self.SetNext(self.parent.projpage) + self.parent.datumpage.SetPrev(self.parent.projpage) + self.parent.bboxpage.SetPrev(self.parent.datumpage) + elif event.GetId() == self.radio2.GetId(): + coordsys = "epsg" + self.SetNext(self.parent.epsgpage) + self.parent.sumpage.SetPrev(self.parent.epsgpage) + elif event.GetId() == self.radio3.GetId(): + coordsys = "file" + self.SetNext(self.parent.filepage) + self.parent.sumpage.SetPrev(self.parent.filepage) + elif event.GetId() == self.radio4.GetId(): + coordsys = "custom" + self.SetNext(self.parent.custompage) + self.parent.sumpage.SetPrev(self.parent.custompage) + elif event.GetId() == self.radio5.GetId(): + coordsys = "xy" + self.SetNext(self.parent.bboxpage) + self.parent.bboxpage.cstate.Enable(False) + + +class ProjectionsPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose projection") + + self.parent = parent + self.proj = '' + self.projdesc = '' + + # text input + self.tproj = self.MakeTextCtrl("", size=(200,-1)) + + # search box + self.searchb = wx.SearchCtrl(self, size=(200,-1), + style=wx.TE_PROCESS_ENTER) + + self.projlist = wx.ListCtrl(self, id=wx.ID_ANY, + size=(650,275), + style=wx.LC_REPORT | + wx.LC_HRULES | + wx.EXPAND) + self.projlist.InsertColumn(0, 'Code') + self.projlist.InsertColumn(1, 'Description') + self.projlist.SetColumnWidth(0, 100) + self.projlist.SetColumnWidth(1, 500) + + # layout + self.sizer.Add(self.MakeRLabel("Projection code:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.tproj, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) + + self.sizer.Add(self.MakeRLabel("Search in projection description"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) + self.sizer.Add(self.searchb, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=3) + + self.sizer.Add(self.projlist, + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=3, col=1, colspan=4) + + # events + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.projlist) + self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) + + self._onBrowseProj(None, None) + + def OnPageChange(self,event): + if not self.proj: + wx.MessageBox('You must select a projection') + event.Veto() + if self.proj == 'utm': + self.parent.projtypepage.text_utm.SetEditable(True) + self.parent.projtypepage.hemischoices = ['north','south'] + else: + self.parent.projtypepage.text_utm.SetValue('') + self.parent.projtypepage.text_utm.SetEditable(False) + self.parent.projtypepage.hemischoices = [] + + global proj4string + proj4string = '+proj=%s' % self.proj + + def OnDoSearch(self,event): + str = self.searchb.GetValue() + listItem = self.projlist.GetColumn(1) + + for i in range(self.projlist.GetItemCount()): + listItem = self.projlist.GetItem(i,1) + if listItem.GetText().find(str) > -1: + self.proj = self.projlist.GetItem(i, 0).GetText() + self.tproj.SetValue(self.proj) + break + + self._onBrowseProj(None,str) + + def OnItemSelected(self,event): + index = event.m_itemIndex + item = event.GetItem() + + self.proj = item.GetText() + self.projdesc = self.projlist.GetItem(index, 1).GetText() + self.tproj.SetValue(self.proj) + + def _onBrowseProj(self,event,search=None): + try: + self.projlist.DeleteAllItems() + for item in self.parent.projections: + desc = self.parent.projections[item] + entry = self.projlist.GetItemCount() + if search and (item.lower().find(search.lower()) > -1 or \ + desc.lower().find(search.lower()) > -1) or \ + not search: + index = self.projlist.InsertStringItem(entry,item) + self.projlist.SetStringItem(index,1,desc) +# if item.lower() == 'utm': self.projlist.SetItem(item, m_itemId=0) +# if item.lower() == 'll': self.projlist.SetItem(item, m_itemId=1) + + self.projlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.projlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.projlist.SendSizeEvent() + + except StandardError, e: + dlg = wx.MessageDialog(self, "Could not read projections list: %s " % e, + "Could not read projections", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + +class ProjTypePage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters") + global coordsys + + self.utmzone = '' + self.utmhemisphere = '' + self.hemischoices = ["north","south"] + self.parent = parent + + self.radio1 = wx.RadioButton( self, -1, " Select datum with associated ellipsoid", style = wx.RB_GROUP ) + self.radio2 = wx.RadioButton( self, -1, " Select ellipsoid" ) + + # layout + self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2) + self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2) + + self.title_utm = self.MakeLLabel("Set zone for UTM projection") + self.text_utm = self.MakeTextCtrl(size=(100,-1)) + self.label_utm = self.MakeRLabel("Zone: ") + self.hemisphere = wx.Choice(self, -1, (100, 50), choices = self.hemischoices) + self.label_hemisphere = self.MakeRLabel("Hemisphere for zone: ") + + self.sizer.Add(self.title_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=4,col=2) + self.sizer.Add(self.label_utm, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=5,col=1) + self.sizer.Add(self.text_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=5,col=2) + self.sizer.Add(self.label_hemisphere, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=6,col=1) + self.sizer.Add(self.hemisphere, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=6,col=2) + + # bindings + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId()) + self.Bind(wx.EVT_CHOICE, self.OnHemisphere, self.hemisphere) + self.Bind(wx.EVT_TEXT, self.GetUTM, self.text_utm) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) + + def OnPageChange(self,event=None): + if self.parent.projpage.proj == 'utm' and self.utmzone == '': + wx.MessageBox('You must set a zone for a UTM projection') + event.Veto() + + def SetVal(self, event): + global coordsys + if event.GetId() == self.radio1.GetId(): + self.SetNext(self.parent.datumpage) + elif event.GetId() == self.radio2.GetId(): + self.SetNext(self.parent.ellipsepage) + + def GetUTM(self, event): + self.utmzone = int(event.GetString()) + + def OnHemisphere(self, event): + self.utmhemisphere = event.GetString() + + class DatumPage(TitledPage): def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Specify geodetic datum") self.parent = parent self.datum = '' - self.datumname = '' + self.datumdesc = '' self.ellipsoid = '' self.datumparams = '' self.transform = '' - self.transcountry = '' - self.transdesc = '' + self.transregion = '' self.transparams = '' + self.hastransform = False # text input self.tdatum = self.MakeTextCtrl("", size=(200,-1)) @@ -109,14 +423,12 @@ style=wx.LC_REPORT| wx.LC_HRULES| wx.EXPAND) - self.datumlist.InsertColumn(0, 'Short Name') - self.datumlist.InsertColumn(1, 'Full EPSG-style name') + self.datumlist.InsertColumn(0, 'Code') + self.datumlist.InsertColumn(1, 'Description') self.datumlist.InsertColumn(2, 'Ellipsoid') - self.datumlist.InsertColumn(3, 'Parameters') self.datumlist.SetColumnWidth(0, 100) - self.datumlist.SetColumnWidth(1, 225) + self.datumlist.SetColumnWidth(1, 250) self.datumlist.SetColumnWidth(2, 100) - self.datumlist.SetColumnWidth(3, 250) # create list control for datum transformation parameters list self.transformlist = wx.ListCtrl(self, id=wx.ID_ANY, @@ -124,17 +436,15 @@ style=wx.LC_REPORT | wx.LC_HRULES | wx.EXPAND) - self.transformlist.InsertColumn(0, 'ID') - self.transformlist.InsertColumn(1, 'Country') - self.transformlist.InsertColumn(2, 'Description ') - self.transformlist.InsertColumn(3, 'Parameters') + self.transformlist.InsertColumn(0, 'Code') + self.transformlist.InsertColumn(1, 'Datum') + self.transformlist.InsertColumn(2, 'Description') self.transformlist.SetColumnWidth(0, 50) self.transformlist.SetColumnWidth(1, 125) self.transformlist.SetColumnWidth(2, 250) - self.transformlist.SetColumnWidth(3, 250) # layout - self.sizer.Add(self.MakeRLabel("Geodetic datum:"), 0, + self.sizer.Add(self.MakeRLabel("Datum code:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, col=1, row=1) @@ -155,7 +465,7 @@ wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=2, col=2) - self.sizer.Add(self.datumlist, 0 , + self.sizer.Add(self.datumlist, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5, row=3, col=1, colspan=4) @@ -169,7 +479,7 @@ wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=5, col=2) - self.sizer.Add(self.transformlist, 0 , + self.sizer.Add(self.transformlist, wx.EXPAND | wx.ALIGN_LEFT | wx.ALL, 5, row=6, col=1, colspan=4) @@ -177,26 +487,26 @@ # events self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnDatumSelected, self.datumlist) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams) - self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - self.tdatum.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) + self.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + self.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) self._onBrowseDatums(None,None) - self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) - self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) - self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) - self.datumlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + def OnPageChange(self,event): + if not self.datum: + wx.MessageBox('You must select a datum') + event.Veto() + if self.hastransform == True and self.transform == '': + wx.MessageBox('You must select a datum transform') + event.Veto() + self.GetNext().SetPrev(self) - self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) - self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) - self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) - self.transformlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + global proj4string + for item in self.datumparams: + proj4string = '%s +%s' % (proj4string,item) - def onPageChange(self,event): - self.GetNext().SetPrev(self) - def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.datumlist.GetColumn(1) @@ -204,8 +514,8 @@ for i in range(self.datumlist.GetItemCount()): listItem = self.datumlist.GetItem(i,1) if listItem.GetText().find(str) > -1: - datumcode = self.datumlist.GetItem(i, 0) - self.tdatum.SetValue(datumcode.GetText()) + datum = self.datumlist.GetItem(i, 0) + self.tdatum.SetValue(datum.GetText()) break self._onBrowseDatums(None,str) @@ -215,70 +525,45 @@ item = event.GetItem() self.transform = item.GetText() - self.transcountry = self.transformlist.GetItem(index, 1).GetText() - self.transdesc = self.transformlist.GetItem(index, 2).GetText() - self.transparams = self.transformlist.GetItem(index, 3).GetText() + self.transdatum = self.parent.transforms[self.transform][0] + self.transregion = self.parent.transforms[self.transform][1] + self.transparams = self.parent.transforms[self.transform][2] self.ttrans.SetValue(str(self.transform)) - def OnDatumSelected(self,event): index = event.m_itemIndex item = event.GetItem() self.datum = item.GetText() - self.datumname = self.datumlist.GetItem(index, 1).GetText() - self.ellipsoid = self.datumlist.GetItem(index, 2).GetText() - self.datumparams = self.datumlist.GetItem(index, 3).GetText() + self.datumdesc = self.parent.datums[self.datum][0] + self.ellipsoid = self.parent.datums[self.datum][1] + self.datumparams = self.parent.datums[self.datum][2] self.tdatum.SetValue(self.datum) self._onBrowseParams() + event.Skip() def _onBrowseParams(self, event=None): - params = [["","Use whole region",""]] - file = os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table") - search = self.datum - + search = self.datum.strip() try: - f = open(file,"r") - rex=re.compile('^(.+)\s+"(.+)"\s+"(.+)"\s+"(.+)"') - for line in f.readlines(): - line = line.strip() - if line[0] == "#": continue - id,parm,country,descr = rex.findall(line)[0] - id=id.strip() - parm=parm.strip() - country = country.strip() - descr=descr.strip() - if id == search: - params.append([parm,country,descr]) - f.close() - + self.transform = '' self.transformlist.DeleteAllItems() - for i in range(len(params)): - # fill datum transformation parameters list control - index = self.transformlist.InsertStringItem(i,str(i+1)) - dtp1 = self.transformlist.SetStringItem(index,1,params[i][1]) - dtp2 = self.transformlist.SetStringItem(index,2,params[i][2]) - dtp3 = self.transformlist.SetStringItem(index,3,params[i][0]) - # format list control columns - if index != '': - self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(0, 30) - if dtp1 != '': - self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(1, 150) - if dtp2 != '': - self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(2, 250) - if dtp3 != '': - self.transformlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(3, 320) + for item in self.parent.transforms: + transdatum = self.parent.transforms[item][0] + transregion = self.parent.transforms[item][1] + entry = self.transformlist.GetItemCount() + if (transdatum.lower() == search.lower()): + index = self.transformlist.InsertStringItem(entry,item) + self.transformlist.SetStringItem(index,1,transdatum) + self.transformlist.SetStringItem(index,2,transregion) + self.hastransform = True + self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + self.transformlist.SendSizeEvent() + except IOError, e: self.transformlist.DeleteAllItems() dlg = wx.MessageDialog(self, "Could not read datum params: %s " % e, @@ -286,39 +571,385 @@ dlg.ShowModal() dlg.Destroy() - def _onBrowseDatums(self,event,search=None): try: + self.datum = '' self.datumlist.DeleteAllItems() - f = open(os.path.join(os.getenv("GISBASE"), "etc","datum.table"),"r") - # shortname "Full EPSG-style name" ellipsoid dx= dy= dz= - rex=re.compile('^(.+)\s+"(.+)"\s+(.+)\s+(dx=.+)') - j=0 + + for item in self.parent.datums: + datumdesc = self.parent.datums[item][0] + ellipse = self.parent.datums[item][1] + entry = self.datumlist.GetItemCount() + if search and (datum.lower().find(search.lower()) > -1 or\ + datumdesc.lower().find(search.lower()) > -1 or\ + ellipse.lower().find(search.lower()) > -1) or\ + not search: + index = self.datumlist.InsertStringItem(entry,item) + self.datumlist.SetStringItem(index,1,datumdesc) + self.datumlist.SetStringItem(index,2,ellipse) + + self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + self.datumlist.SendSizeEvent() + + except IOError, e: + dlg = wx.MessageDialog(self, "Could not read datums: %s " % e, + "Could not read datums list", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + +class EllipsePage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Specify ellipsoid") + + self.parent = parent + self.ellipse = '' + self.ellipsedesc = '' + self.ellipseparams = '' + + # text input + self.tellipse = self.MakeTextCtrl("", size=(200,-1)) + + # search box + self.searchb = wx.SearchCtrl(self, size=(200,-1), + style=wx.TE_PROCESS_ENTER) + + # create list control for ellipse list + self.ellipselist = wx.ListCtrl(self, id=wx.ID_ANY, + size=(650,250), + style=wx.LC_REPORT| + wx.LC_HRULES| + wx.EXPAND) + self.ellipselist.InsertColumn(0, 'Code') + self.ellipselist.InsertColumn(1, 'Description') + self.ellipselist.SetColumnWidth(0, 100) + self.ellipselist.SetColumnWidth(1, 250) + + # layout + self.sizer.Add(self.MakeRLabel("Ellipse code:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=1) + self.sizer.Add(self.tellipse, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.MakeRLabel("Search in description:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=1) + self.sizer.Add(self.searchb, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) + + self.sizer.Add(self.ellipselist, 0 , + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=3, col=1, colspan=3) + + # events + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnEllipseSelected, self.ellipselist) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) + self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + self.Bind(wx.EVT_TEXT_ENTER, self._onBrowseEllipse, self.tellipse) + + self._onBrowseEllipse(None,None) + + def OnPageChange(self,event): + if not self.ellipse: + wx.MessageBox('You must select an ellipse') + event.Veto() + self.GetNext().SetPrev(self) + + global proj4string + for item in self.ellipseparams: + proj4string = '%s +%s' % (proj4string,item) + + def OnDoSearch(self,event): + str = self.searchb.GetValue() + listItem = self.ellipselist.GetColumn(1) + + for i in range(self.ellipselist.GetItemCount()): + item = self.ellipselist.GetItem(i,0) + itemdesc = self.ellipselist.GetItem(i,1) + if itemdesc.GetText().find(str) > -1: + self.ellipse = item.GetText() + self.tellipse.SetValue(self.ellipse) + self.ellipselist.EnsureVisible(long(self.ellipselist.GetItem(i))) + break + + self._onBrowseEllipse(None,str) + + def OnEllipseSelected(self,event): + index = event.m_itemIndex + item = event.GetItem() + + self.ellipse = item.GetText() + self.ellipsedesc = self.parent.ellipsoids[self.ellipse][0] + self.ellipseparam = self.parent.ellipsoids[self.ellipse][1] + + self.tellipse.SetValue(self.ellipse) + self._onBrowseEllipse(None) + + def _onBrowseEllipse(self,event,search=None): + try: + self.ellipselist.DeleteAllItems() + for item in self.parent.ellipsoids: + desc = self.parent.ellipsoids[item][0] + entry = self.ellipselist.GetItemCount() + if search and (item.lower().find(search.lower()) > -1 or \ + desc.lower().find(search.lower()) > -1) or \ + not search: + index = self.ellipselist.InsertStringItem(entry,item) + self.ellipselist.SetStringItem(index,1,desc) + + self.ellipselist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.ellipselist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.ellipselist.SendSizeEvent() + except IOError, e: + dlg = wx.MessageDialog(self, "Could not read ellipse information: %s " % e, + "Problem parsing ellipse list", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + +class GeoreferencedFilePage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Select georeferenced file") + + self.georeffile = '' + + # create controls + self.lfile= wx.StaticText(self, -1, "Georeferenced file: ", + style=wx.ALIGN_RIGHT) + self.tfile = wx.TextCtrl(self,-1, "", size=(300,-1)) + self.bbrowse = wx.Button(self, -1, "Browse...") + + # do layout + self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTRE_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTRE_VERTICAL | + wx.ALL, 5, row=1, col=3) + self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | + wx.ALL, 5, row=1, col=4) + + self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse) + self.Bind(wx.EVT_TEXT, self.OnText, self.tfile) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) + + def OnPageChange(self, event): + if self.georeffile == '': + wx.MessageBox('You must select a file') + event.Veto() + self.GetNext().SetPrev(self) + + def OnText(self, event): + self.georeffile = event.GetString() + + def OnBrowse(self, event): + + dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN) + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + self.tfile.SetValue(path) + dlg.Destroy() + + def OnCreate(self, event): + pass + + +class EPSGPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose EPSG Code") + self.parent = parent + self.epsgcode = '' + self.epsgdesc = '' + + + # labels + self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ", + style=wx.ALIGN_RIGHT) + self.lcode= wx.StaticText(self, -1, "EPSG code: ", + style=wx.ALIGN_RIGHT) + self.lsearch= wx.StaticText(self, -1, "Search in code description: ", + style=wx.ALIGN_RIGHT) + + # text input + epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg') + self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1)) + self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1)) + + # buttons + self.bbrowse = wx.Button(self, -1, "Browse...") + self.bbcodes = wx.Button(self, -1, "Browse Codes...") + + # search box + self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) + + self.epsglist = wx.ListCtrl(self, id=wx.ID_ANY, + size=(650,275), + style=wx.LC_REPORT| + wx.LC_HRULES| + wx.EXPAND) + self.epsglist.InsertColumn(0, 'Code', wx.LIST_FORMAT_CENTRE) + self.epsglist.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT) + self.epsglist.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT) + self.epsglist.SetColumnWidth(0, 50) + self.epsglist.SetColumnWidth(1, 300) + self.epsglist.SetColumnWidth(2, 325) + + # layout + self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=1) + self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) + + self.sizer.Add(self.lcode, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=2) + self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) + + self.sizer.Add(self.lsearch, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=3) + self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3, col=2) + self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3, col=3) + + self.sizer.Add(self.epsglist, wx.ALIGN_LEFT|wx.EXPAND, 0, row=4, col=1, colspan=5) + + # events + self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse) + self.Bind(wx.EVT_BUTTON, self.OnBrowseCodes, self.bbcodes) + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsglist) + self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) + + def OnPageChange(self, event): + if not self.epsgcode: + wx.MessageBox('You must select an EPSG code') + event.Veto() + self.GetNext().SetPrev(self) + + def OnDoSearch(self,event): + str = self.searchb.GetValue() + listItem = self.epsglist.GetColumn(1) + + for i in range(self.epsglist.GetItemCount()): + listItem = self.epsglist.GetItem(i,1) + if listItem.GetText().find(str) > -1: + self.epsgcode = self.epsglist.GetItem(i, 0) + self.tcode.SetValue(self.epsgcode.GetText()) + break + + self.OnBrowseCodes(None,str) + + + def OnBrowse(self, event): + + dlg = wx.FileDialog(self, "Choose EPSG codes file:", + "/", "", "*.*", wx.OPEN) + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + self.tfile.SetValue(path) + dlg.Destroy() + + def OnItemSelected(self,event): + index = event.m_itemIndex + item = event.GetItem() + + self.epsgcode = item.GetText() + self.epsgdesc = self.epsglist.GetItem(index, 1).GetText() + self.tcode.SetValue(str(self.epsgcode)) + + def OnBrowseCodes(self,event,search=None): + try: + self.epsglist.DeleteAllItems() + f = open(self.tfile.GetValue(),"r") + i=1 + j = 0 + descr = None + code = None + params = "" + #self.epsglist.ClearAll() for line in f.readlines(): line = line.strip() - if not line: continue - if line[0] == "#": continue - shortname, epsgname, ellps, params = rex.findall(line)[0] - params = params.strip() - ellps = ellps.strip() - if search and (shortname.lower().find(search.lower()) > -1 or\ - ellps.lower().find(search.lower()) > -1 or\ - epsgname.lower().find(search.lower()) > -1) or\ + if line.find("#") == 0: + descr = line[1:].strip() + elif line.find("<") == 0: + code = line.split(" ")[0] + for par in line.split(" ")[1:]: + params += par + " " + code = code[1:-1] + if code == None: code = 'no code' + if descr == None: descr = 'no description' + if params == None: params = 'no parameters' + if i%2 == 0: + if search and descr.lower().find(search.lower()) > -1 or\ not search: - index = self.datumlist.InsertStringItem(j,shortname) - self.datumlist.SetStringItem(index,1,epsgname) - self.datumlist.SetStringItem(index,2,ellps) - self.datumlist.SetStringItem(index,3,params) - j += 1 + index = self.epsglist.InsertStringItem(j, code) + self.epsglist.SetStringItem(index, 1, descr) + self.epsglist.SetStringItem(index, 2, params) + j += 1 + # reset + descr = None; code = None; params = "" +# if i%2 == 0: +# self.epsglist.SetItemBackgroundColour(i, "grey") + i += 1 f.close() - self.datumlist.SendSizeEvent() - except IOError, e: - dlg = wx.MessageDialog(self, "Could not read datums: %s " % e, + self.epsglist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.epsglist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + self.SendSizeEvent() + except StandardError, e: + dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " % e, "Could not read file", wx.OK|wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() +class CustomPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters") + global coordsys + global proj4string + self.parent = parent + + self.text_proj4string = self.MakeTextCtrl(size=(400,100)) + self.label_proj4string = self.MakeRLabel("Enter PROJ.4 parameters string: ") + + self.sizer.Add(self.label_proj4string, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=5,col=1) + self.sizer.Add(self.text_proj4string, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=5,col=2) + + self.Bind(wx.EVT_TEXT, self.GetProjstring, self.text_proj4string) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) + + def OnPageChange(self, event): + global proj4string + if not proj4string: + wx.MessageBox('You must enter a PROJ.4 string') + event.Veto() + self.GetNext().SetPrev(self) + + def GetProjstring(self, event): + global proj4string + proj4string = event.GetString() + + class SummaryPage(TitledPage): def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Summary") @@ -338,19 +969,21 @@ self.sizer.Add(self.MakeRLabel("Rows:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=12, col=0) self.sizer.Add(self.MakeRLabel("Columns:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=13, col=0) self.sizer.Add(self.MakeRLabel("Cells:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=14, col=0) + self.sizer.Add(self.MakeRLabel("PROJ.4 string:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=16, col=0) # labels self.ldatabase = self.MakeLLabel("") self.llocation = self.MakeLLabel("") self.lprojection = self.MakeLLabel("") - self.lnorth = self.MakeLLabel("") - self.lsouth = self.MakeLLabel("") - self.least = self.MakeLLabel("") - self.lwest = self.MakeLLabel("") - self.lres = self.MakeLLabel("") - self.lrows = self.MakeLLabel("") - self.lcols = self.MakeLLabel("") - self.lcells = self.MakeLLabel("") + self.lnorth = self.MakeLLabel("") + self.lsouth = self.MakeLLabel("") + self.least = self.MakeLLabel("") + self.lwest = self.MakeLLabel("") + self.lres = self.MakeLLabel("") + self.lrows = self.MakeLLabel("") + self.lcols = self.MakeLLabel("") + self.lcells = self.MakeLLabel("") + self.lproj4 = self.MakeLLabel("") self.sizer.Add(self.ldatabase, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=1, col=1) self.sizer.Add(self.llocation, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=2, col=1) @@ -363,6 +996,7 @@ self.sizer.Add(self.lrows, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=12, col=1) self.sizer.Add(self.lcols, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=13, col=1) self.sizer.Add(self.lcells, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=14, col=1) + self.sizer.Add(self.lproj4, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=16, col=1) def FillVars(self,event=None): database = self.parent.startpage.grassdatabase @@ -373,6 +1007,7 @@ global east global west global resolution + global proj4string if not coordsys: coordsys = 0 @@ -392,37 +1027,33 @@ cols = int(round((float(east)-float(west))/float(resolution))) cells = int(rows*cols) - projection = self.parent.projpage.projname + projection = self.parent.projpage.proj projdesc = self.parent.projpage.projdesc - utmzone = self.parent.utmpage.utmzone - utmhemisphere = self.parent.utmpage.utmhemisphere + utmzone = self.parent.projtypepage.utmzone + utmhemisphere = self.parent.projtypepage.utmhemisphere + ellipse = self.parent.ellipsepage.ellipse + ellipsedesc = self.parent.ellipsepage.ellipsedesc datum = self.parent.datumpage.datum - datumname = self.parent.datumpage.datumname + datumname = self.parent.datumpage.datumdesc ellipsoid = self.parent.datumpage.ellipsoid datumparams = self.parent.datumpage.datumparams transform = self.parent.datumpage.transform - transcountry = self.parent.datumpage.transcountry - transdesc = self.parent.datumpage.transdesc + transcountry = self.parent.datumpage.transregion transparams = self.parent.datumpage.transparams self.ldatabase.SetLabel(str(database)) self.llocation.SetLabel(str(location)) + label = '' if coordsys == 'epsg': label = 'EPSG code %s: %s' % (self.parent.epsgpage.epsgcode,self.parent.epsgpage.epsgdesc) self.lprojection.SetLabel(label) elif coordsys == 'file': label = 'Matches file: %s' % self.parent.filepage.georeffile self.lprojection.SetLabel(label) - elif coordsys == 'utm': - label = ('UTM zone: %s%s, datum: %s %s' % (utmzone,utmhemisphere, datumname, ellipsoid)) + elif coordsys == 'proj': + label = ('Projection: %s, %s%s' % (projdesc, datumdesc, ellipsedesc)) self.lprojection.SetLabel(label) - elif coordsys == 'latlon': - label = ('Geographic (latlon), datum: %s %s' % (datumname, ellipsoid)) - self.lprojection.SetLabel(label) - elif coordsys == 'custom': - label = ('%s %s, datum: %s %s' % (projection, projdesc, datumname, ellipsoid)) - self.lprojection.SetLabel(label) elif coordsys == 'xy': label = ('XY coordinate system. Not projected') self.lprojection.SetLabel(label) @@ -436,6 +1067,7 @@ self.lrows.SetLabel(str(rows)) self.lcols.SetLabel(str(cols)) self.lcells.SetLabel(str(cells)) + self.lproj4.SetLabel(proj4string) class BBoxPage(TitledPage): @@ -620,7 +1252,7 @@ wx.ALL, 5, row=17,col=1, colspan=3) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) self.Bind(wx.EVT_COMBOBOX, self.OnItemSelected, self.cstate) self.Bind(wx.EVT_TEXT, self.OnStateText, self.cstate) self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset) @@ -758,7 +1390,7 @@ # self.cstate.Select(idx) # break - def onPageChange(self, event): + def OnPageChange(self, event): self.GetNext().FillVars() self.GetNext().SetPrev(self) @@ -787,7 +1419,7 @@ else: if self.parent.csystemspage.cs == "epsg": to="+init=epsg:%d" % (int(self.parent.epsgpage.tcode.GetValue())) - elif self.parent.csystemspage.cs == "custom": + elif self.parent.csystemspage.cs == "proj": to="+proj=%s" % (self.parent.projpage.tproj.GetValue()) elif self.parent.csystemspage.cs == "utm": to="+proj=utm" @@ -811,509 +1443,131 @@ self.tright.SetValue( str(e) ) self.tleft.SetValue( str(w) ) -class ProjectionsPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose projection name") - self.parent = parent - # text input - self.tproj = self.MakeTextCtrl("", size=(200,-1)) - # search box - self.searchb = wx.SearchCtrl(self, size=(200,-1), - style=wx.TE_PROCESS_ENTER) +class GWizard: + def __init__(self, parent, grassdatabase): + wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","images","wizard.png"), wx.BITMAP_TYPE_PNG) + wizbmp.Rescale(250,600) + wizbmp = wizbmp.ConvertToBitmap() - # table -# self.tablewidth=675 - self.list = wx.ListCtrl(self, id=wx.ID_ANY, - size=(650,275), - style=wx.LC_REPORT | - wx.LC_HRULES | - wx.EXPAND) - self.list.InsertColumn(0, 'Name') - self.list.InsertColumn(1, 'Description') - self.list.SetColumnWidth(0, 100) - self.list.SetColumnWidth(1, 500) - - # layout - self.sizer.Add(self.MakeRLabel("Projection name:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.tproj, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=3) - - self.sizer.Add(self.MakeRLabel("Search in projection description"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2, col=2) - self.sizer.Add(self.searchb, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2, col=3) - - self.sizer.Add(self.list, - wx.EXPAND | - wx.ALIGN_LEFT | - wx.ALL, 5, row=3, col=1, colspan=4) - - # events - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) - self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) - - self._onBrowseDatums(None, None) - - self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE) - self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE) - - def OnDoSearch(self,event): - str = self.searchb.GetValue() - listItem = self.list.GetColumn(1) - - for i in range(self.list.GetItemCount()): - listItem = self.list.GetItem(i,1) - if listItem.GetText().find(str) > -1: - datumcode = self.list.GetItem(i, 0) - self.tproj.SetValue(datumcode.GetText()) - break - - self._onBrowseDatums(None,str) - - - def OnItemSelected(self,event): - index = event.m_itemIndex - item = event.GetItem() - - self.projname = item.GetText() - self.projdesc = self.list.GetItem(index, 1).GetText() - self.tproj.SetValue(str(self.projname)) - - def _onBrowseDatums(self,event,search=None): - try: - self.list.DeleteAllItems() - f = open(os.path.join(os.getenv("GISBASE"), "etc","projections"),"r") - i=1 - j = 0 - descr = None - proj = None - for line in f.readlines(): - line = line.strip() - if not line: - continue - if line[0] == "#": - continue - proj,descr = string.split(line, ":", maxsplit=1) - if search and (descr.lower().find(search.lower()) > -1 or\ - proj.lower().find(search.lower()) > -1) or\ - not search: - self.list.InsertStringItem(j,proj) - self.list.SetStringItem(j,1,descr) - j += 1 - # reset - descr = None; proj = "" - f.close() - self.SendSizeEvent() - except StandardError, e: - dlg = wx.MessageDialog(self, "Could not read datums: %s " % e, - "Could not read file", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - def onPageChange(self,event): - pass -# global projection -# projection = self.tproj.GetValue() - -class GeoreferencedFilePage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Select georeferenced file") - - self.georeffile = '' - - # create controls - self.lfile= wx.StaticText(self, -1, "Georeferenced file: ", - style=wx.ALIGN_RIGHT) - self.tfile = wx.TextCtrl(self,-1, "", size=(300,-1)) - self.bbrowse = wx.Button(self, -1, "Browse...") - - # do layout - self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTRE_VERTICAL | - wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTRE_VERTICAL | - wx.ALL, 5, row=1, col=3) - self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | - wx.ALL, 5, row=1, col=4) - - self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse) - self.Bind(wx.EVT_TEXT, self.OnText, self.tfile) - - def OnText(self, event): - self.georeffile = event.GetString() - - def OnBrowse(self, event): - - dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN) - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - self.tfile.SetValue(path) - dlg.Destroy() - - def OnCreate(self, event): - pass - -class EPSGPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose EPSG Code") - self.parent = parent - - # labels - self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ", - style=wx.ALIGN_RIGHT) - self.lcode= wx.StaticText(self, -1, "EPSG code: ", - style=wx.ALIGN_RIGHT) - self.lsearch= wx.StaticText(self, -1, "Search in code description: ", - style=wx.ALIGN_RIGHT) - - # text input - epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg') - self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1)) - self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1)) - - self.epsgdesc = '' - self.epsgcode = '' - - # buttons - self.bbrowse = wx.Button(self, -1, "Browse...") - self.bbcodes = wx.Button(self, -1, "Browse Codes...") - - # search box - self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) - - # table -# self.tablewidth=675 - self.epsgs = wx.ListCtrl(self, id=wx.ID_ANY, - size=(650,275), - style=wx.LC_REPORT| - wx.LC_HRULES| - wx.EXPAND) - self.epsgs.InsertColumn(0, 'EPSG', wx.LIST_FORMAT_CENTRE) - self.epsgs.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT) - self.epsgs.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT) - self.epsgs.SetColumnWidth(0, 50) - self.epsgs.SetColumnWidth(1, 300) - self.epsgs.SetColumnWidth(2, 325) - - # layout - self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=1) - self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=3) - - self.sizer.Add(self.lcode, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=2) - self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2, col=2) - - self.sizer.Add(self.lsearch, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=3) - self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=3, col=2) - self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=3, col=3) - - self.sizer.Add(self.epsgs, wx.ALIGN_LEFT|wx.EXPAND, 0, row=4, col=1, colspan=5) - - # events - self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse) - self.Bind(wx.EVT_BUTTON, self.OnBrowseCodes, self.bbcodes) - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsgs) - self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) - - def onPageChange(self, event): - self.parent.bboxpage.SetPrev(self) - - def OnDoSearch(self,event): - str = self.searchb.GetValue() - listItem = self.epsgs.GetColumn(1) - - for i in range(self.epsgs.GetItemCount()): - listItem = self.epsgs.GetItem(i,1) - if listItem.GetText().find(str) > -1: - self.epsgcode = self.epsgs.GetItem(i, 0) - self.tcode.SetValue(self.epsgcode.GetText()) - break - - self.OnBrowseCodes(None,str) - - - def OnBrowse(self, event): - - dlg = wx.FileDialog(self, "Choose a georeferenced file:", - "/", "", "*.*", wx.OPEN) - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - self.tfile.SetValue(path) - dlg.Destroy() - - def OnItemSelected(self,event): - index = event.m_itemIndex - item = event.GetItem() - - self.epsgcode = item.GetText() - self.epsgdesc = self.epsgs.GetItem(index, 1).GetText() - self.tcode.SetValue(str(self.epsgcode)) - - def OnBrowseCodes(self,event,search=None): - try: - self.epsgs.DeleteAllItems() - f = open(self.tfile.GetValue(),"r") - i=1 - j = 0 - descr = None - code = None - params = "" - #self.epsgs.ClearAll() - for line in f.readlines(): - line = line.strip() - if line.find("#") == 0: - descr = line[1:].strip() - elif line.find("<") == 0: - code = line.split(" ")[0] - for par in line.split(" ")[1:]: - params += par + " " - code = code[1:-1] - if code == None: code = 'no code' - if descr == None: descr = 'no description' - if params == None: params = 'no parameters' - if i%2 == 0: - if search and descr.lower().find(search.lower()) > -1 or\ - not search: - index = self.epsgs.InsertStringItem(j, code) - self.epsgs.SetStringItem(index, 1, descr) - self.epsgs.SetStringItem(index, 2, params) - j += 1 - # reset - descr = None; code = None; params = "" -# if i%2 == 0: -# self.epsgs.SetItemBackgroundColour(i, "grey") - i += 1 - f.close() - self.epsgs.SetColumnWidth(1, wx.LIST_AUTOSIZE) - self.epsgs.SetColumnWidth(2, wx.LIST_AUTOSIZE) - self.SendSizeEvent() - except StandardError, e: - dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " % e, - "Could not read file", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - -class CoordinateSystemPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose coordinate system for location") - - self.parent = parent - self.cs = "xy" - - # toggles - self.radio1 = wx.RadioButton( self, -1, " XY (arbitrary non-earth coordinate system)", style = wx.RB_GROUP ) - self.radio2 = wx.RadioButton( self, -1, " Latitude/Longitude (geographical) " ) - self.radio3 = wx.RadioButton( self, -1, " Universal Transverse Mercator (UTM) " ) - self.radio4 = wx.RadioButton( self, -1, " Other coordinate system " ) - self.radio5 = wx.RadioButton( self, -1, " Based on EPSG code " ) - self.radio6 = wx.RadioButton( self, -1, " Based on Georeferenced file " ) - - # layout - self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2) - self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2) - self.sizer.Add(self.radio3, 0, wx.ALIGN_LEFT, row=3, col=2) - self.sizer.Add(self.radio4, 0, wx.ALIGN_LEFT, row=4, col=2) - self.sizer.Add(self.radio5, 0, wx.ALIGN_LEFT, row=5, col=2) - self.sizer.Add(self.radio6, 0, wx.ALIGN_LEFT, row=6, col=2) - - # bindings - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio3.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio4.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio5.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio6.GetId()) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) - - def SetVal(self,event): global coordsys - if event.GetId() == self.radio1.GetId(): - coordsys = "xy" - self.SetNext(self.parent.bboxpage) - self.parent.bboxpage.cstate.Enable(False) - elif event.GetId() == self.radio2.GetId(): - coordsys = "latlong" - self.SetNext(self.parent.datumpage) - self.parent.datumpage.SetPrev(self.parent.csystemspage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) - elif event.GetId() == self.radio3.GetId(): - coordsys = "utm" - self.SetNext(self.parent.utmpage) - self.parent.datumpage.SetPrev(self.parent.utmpage) - elif event.GetId() == self.radio4.GetId(): - coordsys = "custom" - self.SetNext(self.parent.projpage) - self.parent.datumpage.SetPrev(self.parent.projpage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) - elif event.GetId() == self.radio5.GetId(): - coordsys = "epsg" - self.SetNext(self.parent.epsgpage) - self.parent.sumpage.SetPrev(self.parent.epsgpage) - elif event.GetId() == self.radio6.GetId(): - coordsys = "file" - self.SetNext(self.parent.filepage) - self.parent.sumpage.SetPrev(self.parent.filepage) - def onPageChange(self,event=None): - global coordsys - if coordsys == "xy": - self.parent.bboxpage.cstate.Enable(False) - else: - self.parent.bboxpage.cstate.Enable(True) + # get georeferencing information from tables in $GISBASE/etc -class UTMPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose zone for UTM coordinate system") + # make projections dictionary + f = open(os.path.join(os.getenv("GISBASE"), "etc","projections"),"r") + self.projections = {} + for line in f.readlines(): + line = line.expandtabs(1) + line = line.strip() + if not line: + continue + if line == '' or line[0] == "#": + continue + proj,projdesc = line.split(":", 1) + proj = proj.strip() + projdesc = projdesc.strip() + self.projections[proj] = projdesc + f.close() + # sort the projections dictionary + templist = self.projections.items() + self.projections = {} + templist.sort() + for item in templist: + self.projections[item[0]]=item[1] - self.utmzone = '' - self.utmhemisphere = '' + f = open(os.path.join(os.getenv("GISBASE"), "etc","datum.table"),"r") + self.datums = {} + paramslist = [] + for line in f.readlines(): + line = line.expandtabs(1) + line = line.strip() + if not line: + continue + if line == '' or line[0] == "#": + continue + datum,info = line.split(" ", 1) + info = info.strip() + datumdesc,params = info.split(" ",1) + datumdesc = datumdesc.strip('"') + paramlist = params.split() + ellipsoid = paramlist.pop(0) + self.datums[datum] = (datumdesc,ellipsoid,paramlist) + f.close() + # sort datums dictionary + templist = self.datums.items() + self.datums = {} + templist.sort() + for item in templist: + self.datums[item[0]]=item[1] - self.parent = parent - self.text_utm = self.MakeTextCtrl(size=(100,-1)) - self.label_utm = self.MakeRLabel("Set UTM zone: ") - hemischoices = ["north","south"] - self.hemisphere = wx.Choice(self, -1, (100, 50), choices = hemischoices) - self.label_hemisphere = self.MakeRLabel("Set hemisphere: ") + # make datum transforms dictionary + f = open(os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table"),"r") + self.transforms = {} + j = 1 + for line in f.readlines(): + transcode = 'T'+str(j) + line = line.expandtabs(1) + line = line.strip() + if not line: + continue + if line == '' or line[0] == "#": + continue + datum,rest = line.split(" ", 1) + rest = rest.strip('" ') + params,rest = rest.split('"', 1) + params = params.strip() + rest = rest.strip('" ') + try: + region,info = rest.split('"', 1) + info = info.strip('" ') + info = region+': '+info + except: + info = rest + self.transforms[transcode] = (datum,info,params) + j+=1 + f.close() - self.sizer.Add(self.label_utm, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=1,col=1) - self.sizer.Add(self.text_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=1,col=2) - self.sizer.Add(self.label_hemisphere, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=2,col=1) - self.sizer.Add(self.hemisphere, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=2,col=2) + # make ellipsiods dictionary + f = open(os.path.join(os.getenv("GISBASE"), "etc","ellipse.table"),"r") + self.ellipsoids = {} + for line in f.readlines(): + line = line.expandtabs(1) + line = line.strip() + if not line: + continue + if line == '' or line[0] == "#": + continue + ellipse,rest = line.split(" ", 1) + rest = rest.strip('" ') + desc,params = rest.split('"', 1) + desc = desc.strip('" ') + paramslist = params.split() + self.ellipsoids[ellipse] = (desc,paramslist) + f.close() + # sort ellipsoid dictionary + templist = self.ellipsoids.items() + self.ellipsoids = {} + templist.sort() + for item in templist: + self.ellipsoids[item[0]]=item[1] - self.Bind(wx.EVT_CHOICE, self.OnHemisphere, self.hemisphere) - self.Bind(wx.EVT_TEXT, self.GetUTM, self.text_utm) - - def GetUTM(self, event): - self.utmzone = int(event.GetString()) - - def OnHemisphere(self, event): - self.utmhemisphere = event.GetString() - -class DatabasePage(TitledPage): - def __init__(self, wizard, parent, grassdatabase): - TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") - - self.grassdatabase = '' - self.location = '' - - # buttons - self.bbrowse = self.MakeButton("Browse...") - - # text controls - self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, -1)) - self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1)) - - # layout - self.sizer.Add(self.MakeRLabel("GIS Data Directory:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=1, col=2) - self.sizer.Add(self.tgisdbase,0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=1, col=3) - self.sizer.Add(self.bbrowse, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=1, col=4) - # - self.sizer.Add(self.MakeRLabel("Project Location"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=2, col=2) - self.sizer.Add(self.tlocation,0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=2, col=3) - self.sizer.Add(self.MakeRLabel("(projection/coordinate system)"), 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=2, col=4) - - # bindings - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging) - - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.onPageChanged) - - def onPageChanging(self,event=None): - if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())): - dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\ - % str(self.tlocation.GetValue()),"Could not create location", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - event.Veto() - return - - if not self.tlocation.GetValue(): - dlg = wx.MessageDialog(self, "Could not create new location: location not set "\ - ,"Could not create location", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - event.Veto() - return - - self.location = self.tlocation.GetValue() - self.grassdatabase = self.tgisdbase.GetValue() - - def onPageChanged(self,event=None): - self.grassdatabase = self.tgisdbase.GetValue() - self.location = self.tlocation.GetValue() - - -class GWizard: - def __init__(self, parent, grassdatabase): - wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","images","wizard.png"), wx.BITMAP_TYPE_PNG) - wizbmp.Rescale(250,600) - wizbmp = wizbmp.ConvertToBitmap() + # define wizard pages self.wizard = wiz.Wizard(parent, -1, "Define new Location", bitmap=wizbmp) self.startpage = DatabasePage(self.wizard, self, grassdatabase) self.csystemspage = CoordinateSystemPage(self.wizard, self) + self.projpage = ProjectionsPage(self.wizard, self) + self.projtypepage = ProjTypePage(self.wizard,self) self.epsgpage = EPSGPage(self.wizard, self) self.bboxpage = BBoxPage(self.wizard, self) self.filepage = GeoreferencedFilePage(self.wizard, self) - self.projpage = ProjectionsPage(self.wizard, self) + self.datumpage = DatumPage(self.wizard, self) + self.ellipsepage = EllipsePage(self.wizard, self) + self.custompage = CustomPage(self.wizard, self) self.sumpage = SummaryPage(self.wizard, self) - self.datumpage = DatumPage(self.wizard, self) - self.utmpage = UTMPage(self.wizard,self) - global coordsys # Set the initial order of the pages # it should follow the epsg line @@ -1322,33 +1576,32 @@ self.csystemspage.SetPrev(self.startpage) self.csystemspage.SetNext(self.bboxpage) + self.projtypepage.SetPrev(self.projpage) + self.projtypepage.SetNext(self.datumpage) + + self.datumpage.SetPrev(self.projtypepage) + self.datumpage.SetNext(self.bboxpage) + + self.ellipsepage.SetPrev(self.projtypepage) + self.ellipsepage.SetNext(self.bboxpage) + + self.projpage.SetPrev(self.csystemspage) + self.projpage.SetNext(self.projtypepage) + self.epsgpage.SetPrev(self.csystemspage) self.epsgpage.SetNext(self.bboxpage) - self.projpage.SetPrev(self.csystemspage) - self.projpage.SetNext(self.datumpage) - self.filepage.SetPrev(self.csystemspage) self.filepage.SetNext(self.bboxpage) - self.datumpage.SetNext(self.bboxpage) + self.custompage.SetPrev(self.csystemspage) + self.custompage.SetNext(self.bboxpage) - if coordsys == "epsg": - self.bboxpage.SetPrev(self.epsgpage) - elif coordsys == "file": - self.bboxpage.SetPrev(self.filepage) - elif coordsys == "xy": - self.bboxpage.SetPrev(self.startpage) - else: - self.bboxpage.SetPrev(self.csystemspage) - + self.bboxpage.SetPrev(self.csystemspage) self.bboxpage.SetNext(self.sumpage) self.sumpage.SetPrev(self.bboxpage) - self.utmpage.SetPrev(self.csystemspage) - self.utmpage.SetNext(self.datumpage) - self.wizard.FitToPage(self.bboxpage) success = False @@ -1388,8 +1641,8 @@ success = self.LatlongCreate() elif coordsys == "utm": success = self.UTMCreate() - elif coordsys == "custom": - success = self.CustomCreate() + elif coordsys == "proj": + success = self.ProjCreate() elif coordsys == "epsg": success = self.EPSGCreate() elif coordsys == "file": @@ -1423,9 +1676,9 @@ """ Create a new UTM location """ - utm = self.utmpage.utm - zone = self.utmpage.zone - utmhemisphere = self.utmpage.utmhemisphere + utm = self.projtypepage.utm + zone = self.projtypepage.zone + utmhemisphere = self.projtypepage.utmhemisphere datum = self.datumpage.datum datumname = self.datumpage.datumname ellipsoid = self.datumpage.ellipsoid @@ -1438,11 +1691,11 @@ wx.MessageBox('Not implemented: Create input for g.proj from \n%s: %s%s \n%s: %s %s \n%s: %s' % (utm, zone, utmhemisphere, datum, datumname, ellipsoid, transform, transdesc)) - def CustomCreate(self): + def ProjCreate(self): """ - Create a new custom-defined location + Create a new location for selected projection """ - projection = self.projpage.projname + projection = self.projpage.proj projdesc = self.projpage.projdesc datum = self.datumpage.datum datumname = self.datumpage.datumname From barton at grass.itc.it Wed Jul 4 10:39:14 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Jul 4 10:39:15 2007 Subject: [grass-addons] r921 - trunk/grassaddons/gui Message-ID: <200707040839.l648dED3001865@grass.itc.it> Author: barton Date: 2007-07-04 10:39:05 +0200 (Wed, 04 Jul 2007) New Revision: 921 Modified: trunk/grassaddons/gui/location_wizard.py Log: Lists are now sorted and initial PROJ.4 string created. Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-07-04 06:10:53 UTC (rev 920) +++ trunk/grassaddons/gui/location_wizard.py 2007-07-04 08:39:05 UTC (rev 921) @@ -1,7 +1,7 @@ import wx import wx.wizard as wiz -import wx.lib.rcsizer as rcs -from wx.lib.combotreebox import ComboTreeBox +import wx.lib.rcsizer as rcs +import wx.lib.mixins.listctrl as listmix import os import sys @@ -291,6 +291,7 @@ global proj4string proj4string = '+proj=%s' % self.proj + def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.projlist.GetColumn(1) @@ -314,17 +315,16 @@ def _onBrowseProj(self,event,search=None): try: + projlist = self.parent.projections.items() + projlist.sort() self.projlist.DeleteAllItems() - for item in self.parent.projections: - desc = self.parent.projections[item] + for proj,desc in projlist: entry = self.projlist.GetItemCount() - if search and (item.lower().find(search.lower()) > -1 or \ + if search and (proj.lower().find(search.lower()) > -1 or \ desc.lower().find(search.lower()) > -1) or \ not search: - index = self.projlist.InsertStringItem(entry,item) + index = self.projlist.InsertStringItem(entry,proj) self.projlist.SetStringItem(index,1,desc) -# if item.lower() == 'utm': self.projlist.SetItem(item, m_itemId=0) -# if item.lower() == 'll': self.projlist.SetItem(item, m_itemId=1) self.projlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) self.projlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) @@ -376,6 +376,9 @@ if self.parent.projpage.proj == 'utm' and self.utmzone == '': wx.MessageBox('You must set a zone for a UTM projection') event.Veto() + if self.parent.projpage.proj == 'utm': + global proj4string + proj4string = '%s +zone=%s' % (proj4string, self.utmzone) def SetVal(self, event): global coordsys @@ -576,15 +579,17 @@ self.datum = '' self.datumlist.DeleteAllItems() - for item in self.parent.datums: - datumdesc = self.parent.datums[item][0] - ellipse = self.parent.datums[item][1] + datumlist = self.parent.datums.items() + datumlist.sort() + for datum,info in datumlist: + datumdesc = info[0] + ellipse = info[1] entry = self.datumlist.GetItemCount() if search and (datum.lower().find(search.lower()) > -1 or\ datumdesc.lower().find(search.lower()) > -1 or\ ellipse.lower().find(search.lower()) > -1) or\ not search: - index = self.datumlist.InsertStringItem(entry,item) + index = self.datumlist.InsertStringItem(entry,datum) self.datumlist.SetStringItem(index,1,datumdesc) self.datumlist.SetStringItem(index,2,ellipse) @@ -665,8 +670,11 @@ self.GetNext().SetPrev(self) global proj4string + params = '' for item in self.ellipseparams: - proj4string = '%s +%s' % (proj4string,item) + item = '+'+str(item) + params = '%s %s' % (params, item) + proj4string = '%s %s' % (proj4string,params) def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -689,21 +697,23 @@ self.ellipse = item.GetText() self.ellipsedesc = self.parent.ellipsoids[self.ellipse][0] - self.ellipseparam = self.parent.ellipsoids[self.ellipse][1] + self.ellipseparams = self.parent.ellipsoids[self.ellipse][1] self.tellipse.SetValue(self.ellipse) self._onBrowseEllipse(None) def _onBrowseEllipse(self,event,search=None): try: + ellipselist = self.parent.ellipsoids.items() + ellipselist.sort() self.ellipselist.DeleteAllItems() - for item in self.parent.ellipsoids: - desc = self.parent.ellipsoids[item][0] + for ellipsoid,info in ellipselist: + desc = info[0] entry = self.ellipselist.GetItemCount() - if search and (item.lower().find(search.lower()) > -1 or \ + if search and (ellipsoid.lower().find(search.lower()) > -1 or \ desc.lower().find(search.lower()) > -1) or \ not search: - index = self.ellipselist.InsertStringItem(entry,item) + index = self.ellipselist.InsertStringItem(entry,ellipsoid) self.ellipselist.SetStringItem(index,1,desc) self.ellipselist.SetColumnWidth(0, wx.LIST_AUTOSIZE) @@ -1034,11 +1044,11 @@ ellipse = self.parent.ellipsepage.ellipse ellipsedesc = self.parent.ellipsepage.ellipsedesc datum = self.parent.datumpage.datum - datumname = self.parent.datumpage.datumdesc + datumdesc = self.parent.datumpage.datumdesc ellipsoid = self.parent.datumpage.ellipsoid datumparams = self.parent.datumpage.datumparams transform = self.parent.datumpage.transform - transcountry = self.parent.datumpage.transregion + transregion = self.parent.datumpage.transregion transparams = self.parent.datumpage.transparams self.ldatabase.SetLabel(str(database)) @@ -1470,12 +1480,6 @@ projdesc = projdesc.strip() self.projections[proj] = projdesc f.close() - # sort the projections dictionary - templist = self.projections.items() - self.projections = {} - templist.sort() - for item in templist: - self.projections[item[0]]=item[1] f = open(os.path.join(os.getenv("GISBASE"), "etc","datum.table"),"r") self.datums = {} @@ -1495,12 +1499,6 @@ ellipsoid = paramlist.pop(0) self.datums[datum] = (datumdesc,ellipsoid,paramlist) f.close() - # sort datums dictionary - templist = self.datums.items() - self.datums = {} - templist.sort() - for item in templist: - self.datums[item[0]]=item[1] # make datum transforms dictionary f = open(os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table"),"r") @@ -1546,12 +1544,6 @@ paramslist = params.split() self.ellipsoids[ellipse] = (desc,paramslist) f.close() - # sort ellipsoid dictionary - templist = self.ellipsoids.items() - self.ellipsoids = {} - templist.sort() - for item in templist: - self.ellipsoids[item[0]]=item[1] # define wizard pages self.wizard = wiz.Wizard(parent, -1, "Define new Location", @@ -1621,6 +1613,7 @@ database = self.startpage.grassdatabase location = self.startpage.location global coordsys + global proj4string success = '' # wx.MessageBox("finished database: %s, location: %s, coordsys: %s" % (database, location, coordsys)) @@ -1639,8 +1632,6 @@ cols = int(round((float(east)-float(west))/float(resolution))) cells = int(rows*cols) success = self.LatlongCreate() - elif coordsys == "utm": - success = self.UTMCreate() elif coordsys == "proj": success = self.ProjCreate() elif coordsys == "epsg": @@ -1656,41 +1647,7 @@ """ wx.MessageBox('Not implemented: Create xy location') - def LatlongCreate(self): - """ - Create a new Lat/Long location - """ - datum = self.datumpage.datum - datumname = self.datumpage.datumname - ellipsoid = self.datumpage.ellipsoid - datumparams = self.datumpage.datumparams - transform = self.datumpage.transform - transcountry = self.datumpage.transcountry - transdesc = self.datumpage.transdesc - transparams = self.datumpage.transparams - wx.MessageBox('Not implemented: Create input for g.proj from \nlatitude/longitude \n%s: %s %s \n%s: %s' % - (datum, datumname, ellipsoid, transform, transdesc)) - - def UTMCreate(self): - """ - Create a new UTM location - """ - utm = self.projtypepage.utm - zone = self.projtypepage.zone - utmhemisphere = self.projtypepage.utmhemisphere - datum = self.datumpage.datum - datumname = self.datumpage.datumname - ellipsoid = self.datumpage.ellipsoid - datumparams = self.datumpage.datumparams - transform = self.datumpage.transform - transcountry = self.datumpage.transcountry - transdesc = self.datumpage.transdesc - transparams = self.datumpage.transparams - - wx.MessageBox('Not implemented: Create input for g.proj from \n%s: %s%s \n%s: %s %s \n%s: %s' % - (utm, zone, utmhemisphere, datum, datumname, ellipsoid, transform, transdesc)) - def ProjCreate(self): """ Create a new location for selected projection @@ -1698,16 +1655,17 @@ projection = self.projpage.proj projdesc = self.projpage.projdesc datum = self.datumpage.datum - datumname = self.datumpage.datumname - ellipsoid = self.datumpage.ellipsoid + datumdesc = self.datumpage.datumdesc + datumellipse = self.datumpage.ellipsoid datumparams = self.datumpage.datumparams + ellipsoid = self.ellipsepage.ellipse + ellipsedesc = self.ellipsepage.ellipsedesc transform = self.datumpage.transform - transcountry = self.datumpage.transcountry - transdesc = self.datumpage.transdesc + transregion = self.datumpage.transregion transparams = self.datumpage.transparams - wx.MessageBox('Not implemented: Create input for g.proj from \n%s: %s \n%s: %s %s \n%s: %s' % - (projection, projdesc, datum, datumname, ellipsoid, transform, transdesc)) +# wx.MessageBox('Not implemented: Create input for g.proj from \n%s: %s \n%s: %s %s \n%s: %s' % +# (projection, projdesc, datum, datumname, ellipsoid, transform, transdesc)) def EPSGCreate(self): """ From barton at grass.itc.it Wed Jul 4 11:02:41 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Jul 4 11:02:43 2007 Subject: [grass-addons] r922 - trunk/grassaddons/gui/gui_modules Message-ID: <200707040902.l6492fL6002895@grass.itc.it> Author: barton Date: 2007-07-04 11:02:33 +0200 (Wed, 04 Jul 2007) New Revision: 922 Modified: trunk/grassaddons/gui/gui_modules/dbm.py Log: Bug fix. Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-07-04 08:39:05 UTC (rev 921) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-07-04 09:02:33 UTC (rev 922) @@ -6,7 +6,7 @@ * VirtualAttributeList * AttributeManager * DisplayAttributesDialog - + PURPOSE: GRASS attribute table manager This program is based on FileHunter, published in 'The wxPython Linux @@ -99,8 +99,8 @@ "driver=%s" % self.parent.driver, "database=%s" % self.parent.database]) - for line in dbDescribe.module_stdout.readlines()[1:]: - column, type, length = line.strip().split(":") + for line in dbDescribe.module_stdout.readlines()[2:]: + colnum, column, type, length = line.strip().split(":") # FIXME: here will be more types if type.lower().find("integer") > -1: self.columns.append({"name":column,"type":int}) @@ -228,7 +228,7 @@ if self.lastTurnSelectedCats[:] != self.selectedCats[:]: if self.qlayer: self.map.DeleteLayer(self.qlayer) - + cats = self.selectedCats catstr = "" i = 0 @@ -300,16 +300,16 @@ # --------------------------------------------------- # These methods are callbacks for implementing the # "virtualness" of the list... - + # def OnGetItemText(self, item, col): # index=self.itemIndexMap[item] # s = self.itemDataMap[index][col] # return s - + # def OnGetItemImage(self, item): # index=self.itemIndexMap[item] # if ( index % 2) == 0: - + def OnGetItemAttr(self, item): index=self.itemIndexMap[item] @@ -324,7 +324,7 @@ # Here's a better SortItems() method -- # the ColumnSorterMixin.__ColumnSorter() method already handles the ascending/descending, # and it knows to sort on another column if the chosen columns have the same value. - + # def SortItems(self,sorter=cmp): # items = list(self.itemDataMap.keys()) # # for i in range(len(items)): @@ -334,10 +334,10 @@ # # for i in range(len(items)): # # items[i] = str(items[i]) # self.itemIndexMap = items - + # # redraw the list # self.Refresh() - + # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py def GetListCtrl(self): return self @@ -622,7 +622,7 @@ dlg.Destroy() self.mapInfo = None return - + wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title="", style=style, pos=pos) @@ -644,11 +644,11 @@ self.SetTitle(_("Add attributes")) else: self.SetTitle(_("Display attributes")) - + if not found or \ (self.action != "add" and selected == 0): continue - + panel = wx.Panel(parent=notebook, id=wx.ID_ANY) notebook.AddPage(page=panel, text=_(" %s %d ") % (_("Layer"), layer)) @@ -676,11 +676,11 @@ 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) - + flexSizer.Add(colName, proportion=0, flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) flexSizer.Add(colType, proportion=0, @@ -693,7 +693,7 @@ 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) - + # add widget reference to self.columns columns[name].append(colValue.GetId()) @@ -723,14 +723,14 @@ if notebook.GetPageCount() == 0: Debug.msg(4, "DisplayAttributesDialog(): Nothing found!") self.mapInfo = None - + def __SelectAttributes(self, layer): """Select attributes""" - + def OnSQLStatement(self, event): """Update SQL statement""" pass - + def GetSQLString(self): """Create SQL statement string based on self.sqlStatement""" for layer in self.mapInfo.layers.keys(): @@ -759,19 +759,19 @@ 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 + "," else: sqlString += name + "=" + updatedValues[idx] + "," - + sqlString = sqlString[:-1] # remove last comma if self.action == "add": @@ -798,7 +798,7 @@ def OnSubmit(self, event): """Submit record""" - + self.Close() class VectorAttributesInfo: @@ -814,7 +814,7 @@ return self.__DescribeTables() # -> self.tables - + def __CheckDBConnection(self): """Check DB connection""" layerCommand = cmd.Command(cmd=["v.db.connect", @@ -822,14 +822,14 @@ "map=%s" % self.map]) if layerCommand.returncode != 0: return False - + # list of available layers & (table, database, driver) for line in layerCommand.ReadStdOutput(): lineList = line.split(' ') self.layers[int(lineList[0])] = { "table" : lineList[1], "database" : lineList[3], "driver" : lineList[4] } - + if (len(self.layers.keys()) == 0): return False From neteler at grass.itc.it Wed Jul 4 11:19:06 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Wed Jul 4 11:19:07 2007 Subject: [grass-addons] r923 - trunk/grassaddons Message-ID: <200707040919.l649J6IO003033@grass.itc.it> Author: neteler Date: 2007-07-04 11:19:05 +0200 (Wed, 04 Jul 2007) New Revision: 923 Modified: trunk/grassaddons/README Log: explain easy compilation Modified: trunk/grassaddons/README =================================================================== --- trunk/grassaddons/README 2007-07-04 09:02:33 UTC (rev 922) +++ trunk/grassaddons/README 2007-07-04 09:19:05 UTC (rev 923) @@ -16,6 +16,17 @@ Checkout of repository: svn co https://grasssvn.itc.it/svn/grassaddons/trunk/grassaddons grassaddons +############### +Compilation + +The easiest way to compile modules against your GRASS code is +by setting MODULE_TOPDIR on the fly to tell 'make' where to +find the GRASS source code: + + make MODULE_TOPDIR=$HOME/grass63/ + +(adapt to your /path/to/grass6/ ) + ######################################### # To avoid PDF mime-type recognition problems, # each new (!) PDF file has to be modified like this: From neteler at grass.itc.it Wed Jul 4 11:20:25 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Wed Jul 4 11:20:26 2007 Subject: [grass-addons] r924 - trunk/grassaddons/i.landsat.toar Message-ID: <200707040920.l649KPhc003054@grass.itc.it> Author: neteler Date: 2007-07-04 11:20:24 +0200 (Wed, 04 Jul 2007) New Revision: 924 Modified: trunk/grassaddons/i.landsat.toar/description.html trunk/grassaddons/i.landsat.toar/landsat.c trunk/grassaddons/i.landsat.toar/main.c Log: E. Jorge Tizado: fixed satellite selection; using ACA algorithm and the standard is to use Kelvin degrees and not Celsius degrees Modified: trunk/grassaddons/i.landsat.toar/description.html =================================================================== --- trunk/grassaddons/i.landsat.toar/description.html 2007-07-04 09:19:05 UTC (rev 923) +++ trunk/grassaddons/i.landsat.toar/description.html 2007-07-04 09:20:24 UTC (rev 924) @@ -16,15 +16,14 @@ illumination geometry, the DN images are converted first to at-satellite radiance and then to at-satellite reflectance.
The thermal band is first converted from DN to at-satellite radiance, -and then to effective at-satellite temperature in Celsius (O Kelvin = --273.15 Celsius).

+and then to effective at-satellite temperature in Kelvin degrees.

In verbose mode, the program write the parameters used in transformation to at-satellite radiance, to at-satellite reflectance and constant to remove the atmospheric effect using DOS method.

-To remove atmospheric effect, use +To remove atmospheric effect, use

 r.mapcalc 'refc = if(ref < (a*dp+b), b, ref-a*dp)'
@@ -54,11 +53,11 @@
 

EXAMPLES

Transfor digital numbers from band raster 203_30.1, 203_30.2, -... to reflectance at top-of-atmosphere in output files 203_30.1r, -203_30.2r, ...

+... to reflectance at top-of-atmosphere in output files 203_30.toar.1, +203_30.toar.2, ...

-i.landsat.toar band=203_30 met=p203r030_7x20010620.met
+i.landsat.toar -7 band=203_30 met=p203r030_7x20010620.met
 

REFERENCES

Modified: trunk/grassaddons/i.landsat.toar/landsat.c =================================================================== --- trunk/grassaddons/i.landsat.toar/landsat.c 2007-07-04 09:19:05 UTC (rev 923) +++ trunk/grassaddons/i.landsat.toar/landsat.c 2007-07-04 09:20:24 UTC (rev 924) @@ -47,7 +47,7 @@ *****************************************************************************/ double lsat_rad2temp(double rad, double K1, double K2) { - return (double)(K2 / log((K1 / rad) + 1.0) - 273.15); + return (double)(K2 / log((K1 / rad) + 1.0)); } /**************************************************************************** Modified: trunk/grassaddons/i.landsat.toar/main.c =================================================================== --- trunk/grassaddons/i.landsat.toar/main.c 2007-07-04 09:19:05 UTC (rev 923) +++ trunk/grassaddons/i.landsat.toar/main.c 2007-07-04 09:20:24 UTC (rev 924) @@ -54,6 +54,7 @@ double gain, bias, cref, rad, ref; lsat_data lsat; + char command[300]; /* initialize GIS environment */ G_gisinit(argv[0]); @@ -111,13 +112,12 @@ sat7 = G_define_flag(); sat7->key = '7'; - sat7->description = _("Landsat-7 ETM+ (specify either met or date, solar, and gain"); - sat7->answer = 1; + sat7->description = _("Landsat-7 ETM+ (specify either met or date, solar, and gain)"); + sat7->answer = 0; flag = G_define_flag(); flag->key = 'f'; - flag->description = _("LANDSAT-5: product creation after instead of before May 5, 2003. " - "LANDSAT-7: product creation before instead of after July 1, 2000"); + flag->description = _("LANDSAT-5: product creation after instead of before May 5, 2003.\n\n\tLANDSAT-7: product creation before instead of after July 1, 2000"); flag->answer = 0; param = G_define_flag(); @@ -128,13 +128,15 @@ if (G_parser(argc, argv)) exit(EXIT_FAILURE); - // -------------------------------- - // ----- START -------------------- + /* ----- START -------------------- */ /* stores options and flags to variables */ met = metfn->answer; name = input->answer; elevation = 0.; + if( !sat4->answer && !sat5->answer && !sat7->answer) + G_fatal_error(_("Need satellite type")); + if (sat7->answer && met != NULL) { met_ETM(met, &lsat); fprintf(stdout, "Landsat-7 ETM+ with data in met file [%s]\n", met); @@ -166,7 +168,7 @@ } if (param->answer) { - fprintf(stdout, " DATE %s\n", lsat.date); + fprintf(stdout, " ACQUISITION_DATE %s\n", lsat.date); fprintf(stdout, " earth-sun distance = %.8lf\n", lsat.dist_es); fprintf(stdout, " solar elevation angle = %.8lf\n", lsat.sun_elev); for (i = 0; i < lsat.bands; i++) { @@ -202,7 +204,7 @@ for (i = 0; i < lsat.bands; i++) { snprintf(band_in, 127, "%s.%d", name, lsat.band[i].code); - snprintf(band_out, 127, "%s.%dr", name, lsat.band[i].code); + snprintf(band_out, 127, "%s.toar.%d", name, lsat.band[i].code); mapset = G_find_cell2(band_in, ""); if (mapset == NULL) { @@ -277,9 +279,14 @@ G_close_cell(infd); G_close_cell(outfd); - /* TODO: set map color to grey */ + /* set map color to grey */ + sprintf(command, "r.colors map=%s color=grey", band_out); + system(command); - /* TODO: set -1. to null */ + /* set -1. to null */ + G_message("REMEMBER: -1 is a NULL value"); +/* sprintf(command, "r.null map=%s setnull=-1", band_out); */ +/* system(command); */ /* add command line incantation to history file */ G_short_history(band_out, "raster", &history); @@ -287,7 +294,6 @@ G_write_history(band_out, &history); } - G_message("REMEMBER: -1 is a NULL value"); G_set_window(&window); exit(EXIT_SUCCESS); } From neteler at grass.itc.it Wed Jul 4 11:21:42 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Wed Jul 4 11:21:43 2007 Subject: [grass-addons] r925 - trunk/grassaddons Message-ID: <200707040921.l649LgiD003077@grass.itc.it> Author: neteler Date: 2007-07-04 11:21:42 +0200 (Wed, 04 Jul 2007) New Revision: 925 Modified: trunk/grassaddons/contributors.csv Log: E. Jorge Tizado Modified: trunk/grassaddons/contributors.csv =================================================================== --- trunk/grassaddons/contributors.csv 2007-07-04 09:20:24 UTC (rev 924) +++ trunk/grassaddons/contributors.csv 2007-07-04 09:21:42 UTC (rev 925) @@ -10,4 +10,5 @@ landa,Martin Landa maldacker,Maximilian Maldacker neteler,Markus Neteler +-------,E. Jorge Tizado ullah,Isaac Ullah From maldacker at grass.itc.it Wed Jul 4 15:27:00 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Wed Jul 4 15:27:01 2007 Subject: [grass-addons] r926 - trunk/grassaddons/v.path.obstacles Message-ID: <200707041327.l64DR0qJ005650@grass.itc.it> Author: maldacker Date: 2007-07-04 15:26:57 +0200 (Wed, 04 Jul 2007) New Revision: 926 Modified: trunk/grassaddons/v.path.obstacles/geometry.c Log: correction in point_inside function Modified: trunk/grassaddons/v.path.obstacles/geometry.c =================================================================== --- trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-04 09:21:42 UTC (rev 925) +++ trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-04 13:26:57 UTC (rev 926) @@ -58,7 +58,7 @@ double pqy = q->y - p->y; double pq_distance = pqx*pqx + pqy*pqy; - return pq_distance < e_distance ; + return pq_distance <= e_distance ; } @@ -110,7 +110,7 @@ struct Point * n1 = p; struct Point * n2 = other1(p); - while ( n2 != p ) + do { if ( ( ( n2->y <=y && y < n1->y ) || ( n1->y <= y && y< n2->y ) ) && @@ -119,7 +119,8 @@ n1 = other1(n1); n2 = other1(n2); - } + + }while ( n1 != p ); return c; } From barton at grass.itc.it Wed Jul 4 22:58:17 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Jul 4 22:58:19 2007 Subject: [grass-addons] r927 - trunk/grassaddons/gui Message-ID: <200707042058.l64KwHNJ011490@grass.itc.it> Author: barton Date: 2007-07-04 22:58:09 +0200 (Wed, 04 Jul 2007) New Revision: 927 Modified: trunk/grassaddons/gui/location_wizard.py Log: Attempting to create new locations with g.proj and PROJ.4 strings. Not working, but must be close. Committing in case others want to take a look. Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-07-04 13:26:57 UTC (rev 926) +++ trunk/grassaddons/gui/location_wizard.py 2007-07-04 20:58:09 UTC (rev 927) @@ -21,6 +21,7 @@ global west global resolution global wizerror +global proj4string coordsys = '' north = '' @@ -28,6 +29,7 @@ east = '' west = '' resolution = '' +proj4string = '' class TitledPage(wiz.WizardPageSimple): def __init__(self, parent, title): @@ -270,6 +272,7 @@ wx.ALL, 5, row=3, col=1, colspan=4) # events + self.Bind(wx.EVT_TEXT, self.OnText, self.tproj) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.projlist) self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) @@ -289,8 +292,13 @@ self.parent.projtypepage.hemischoices = [] global proj4string - proj4string = '+proj=%s' % self.proj + if self.proj == 'll': + proj4string = '+proj=longlat' + else: + proj4string = '+proj=%s' % self.proj + def OnText(self, event): + self.proj = event.GetString() def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -379,6 +387,8 @@ if self.parent.projpage.proj == 'utm': global proj4string proj4string = '%s +zone=%s' % (proj4string, self.utmzone) + if self.utmhemisphere == 'south': + proj4string = '%s +%s' % (proj4string, self.utmhemisphere) def SetVal(self, event): global coordsys @@ -388,7 +398,7 @@ self.SetNext(self.parent.ellipsepage) def GetUTM(self, event): - self.utmzone = int(event.GetString()) + self.utmzone = event.GetString() def OnHemisphere(self, event): self.utmhemisphere = event.GetString() @@ -407,6 +417,7 @@ self.transregion = '' self.transparams = '' self.hastransform = False + self.proj4params = '' # text input self.tdatum = self.MakeTextCtrl("", size=(200,-1)) @@ -417,8 +428,8 @@ style=wx.TE_PROCESS_ENTER) # button - self.bupdate = self.MakeButton("Update trans. parms.", - size=(-1,-1)) +# self.bupdate = self.MakeButton("Update trans. parms.", +# size=(-1,-1)) # create list control for datum/elipsoid list self.datumlist = wx.ListCtrl(self, id=wx.ID_ANY, @@ -455,10 +466,10 @@ wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.bupdate, 0 , - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=3) +# self.sizer.Add(self.bupdate, 0 , +# wx.ALIGN_LEFT | +# wx.ALIGN_CENTER_VERTICAL | +# wx.ALL, 5, row=1, col=3) self.sizer.Add(self.MakeRLabel("Search in description:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | @@ -491,25 +502,38 @@ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnDatumSelected, self.datumlist) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) - self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams) +# self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams) self.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - self.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) + self.Bind(wx.EVT_TEXT, self.OnDText, self.tdatum) self._onBrowseDatums(None,None) def OnPageChange(self,event): + self.proj4params = '' if not self.datum: wx.MessageBox('You must select a datum') event.Veto() - if self.hastransform == True and self.transform == '': - wx.MessageBox('You must select a datum transform') - event.Veto() +# if self.hastransform == True and self.transform == '': +# wx.MessageBox('You must select a datum transform') +# event.Veto() self.GetNext().SetPrev(self) global proj4string for item in self.datumparams: - proj4string = '%s +%s' % (proj4string,item) + if item[:2] == 'f=': + item = 'r'+item + self.proj4params = '%s +%s' % (self.proj4params,item) + if self.transparams: + self.proj4params = '%s +no_defs +%s' % (self.proj4params,self.transparams) + proj4string = '%s %s' % (proj4string, self.proj4params) + def OnDText(self, event): + self.datum = event.GetString() + self._onBrowseParams(None,self.datum) + + def OnTText(self, event): + self.transform = event.GetString() + def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.datumlist.GetColumn(1) @@ -544,10 +568,10 @@ self.datumparams = self.parent.datums[self.datum][2] self.tdatum.SetValue(self.datum) - self._onBrowseParams() + self._onBrowseParams(None, self.datum) event.Skip() - def _onBrowseParams(self, event=None): + def _onBrowseParams(self, event=None, search=None): search = self.datum.strip() try: self.transform = '' @@ -613,6 +637,7 @@ self.ellipse = '' self.ellipsedesc = '' self.ellipseparams = '' + self.proj4params = '' # text input self.tellipse = self.MakeTextCtrl("", size=(200,-1)) @@ -659,23 +684,30 @@ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnEllipseSelected, self.ellipselist) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - self.Bind(wx.EVT_TEXT_ENTER, self._onBrowseEllipse, self.tellipse) + self.Bind(wx.EVT_TEXT, self.OnText, self.tellipse) self._onBrowseEllipse(None,None) def OnPageChange(self,event): + self.proj4params = '' if not self.ellipse: wx.MessageBox('You must select an ellipse') event.Veto() self.GetNext().SetPrev(self) global proj4string - params = '' for item in self.ellipseparams: - item = '+'+str(item) - params = '%s %s' % (params, item) - proj4string = '%s %s' % (proj4string,params) + if item[:2] == 'f=': + item = '+r'+item + else: + item = '+'+str(item) + self.proj4params = '%s %s' % (params, item) + self.proj4params = '%s +no_defs' % self.proj4params + proj4string = '%s %s' % (proj4string,self.proj4params) + def OnText(self, event): + self.ellipse = event.GetString() + def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.ellipselist.GetColumn(1) @@ -941,6 +973,8 @@ self.text_proj4string = self.MakeTextCtrl(size=(400,100)) self.label_proj4string = self.MakeRLabel("Enter PROJ.4 parameters string: ") + if proj4string: + self.text_proj4string.SetValue(proj4string) self.sizer.Add(self.label_proj4string, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=5,col=1) self.sizer.Add(self.text_proj4string, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=5,col=2) @@ -1067,6 +1101,8 @@ elif coordsys == 'xy': label = ('XY coordinate system. Not projected') self.lprojection.SetLabel(label) + elif coordsys == 'custom': + label = ('Custom PROJ.4 string') self.lprojection.Wrap(500) self.lnorth.SetLabel(str(north)) @@ -1632,8 +1668,8 @@ cols = int(round((float(east)-float(west))/float(resolution))) cells = int(rows*cols) success = self.LatlongCreate() - elif coordsys == "proj": - success = self.ProjCreate() + elif coordsys == "proj" or coordsys == 'custom': + success = self.Proj4Create() elif coordsys == "epsg": success = self.EPSGCreate() elif coordsys == "file": @@ -1648,25 +1684,43 @@ wx.MessageBox('Not implemented: Create xy location') - def ProjCreate(self): + def Proj4Create(self): """ Create a new location for selected projection """ - projection = self.projpage.proj + global proj4string + location = self.startpage.location projdesc = self.projpage.projdesc - datum = self.datumpage.datum - datumdesc = self.datumpage.datumdesc - datumellipse = self.datumpage.ellipsoid - datumparams = self.datumpage.datumparams - ellipsoid = self.ellipsepage.ellipse + if self.datumpage.datumdesc: + datumdesc = self.datumpage.datumdesc+' - '+self.datumpage.ellipsoid + else: datumdesc = '' ellipsedesc = self.ellipsepage.ellipsedesc - transform = self.datumpage.transform - transregion = self.datumpage.transregion - transparams = self.datumpage.transparams -# wx.MessageBox('Not implemented: Create input for g.proj from \n%s: %s \n%s: %s %s \n%s: %s' % -# (projection, projdesc, datum, datumname, ellipsoid, transform, transdesc)) + dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to \ + %s: %s%s" % (location, projdesc, datumdesc, ellipsedesc), + "Create new location?", + wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) + if dlg.ShowModal() == wx.ID_NO: + dlg.Destroy() + return False + else: + dlg.Destroy() + # creating location from PROJ.4 string + try: + cmdlist = ['g.proj','-c','proj4="%s"' % proj4string,'location=%s' % location] + wx.MessageBox('cmdlist: %s' % cmdlist) + cmd.Command(cmdlist) + return True + + except StandardError, e: + dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e), + "Could not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + return False + + def EPSGCreate(self): """ Create a new location from an EPSG code. @@ -1694,8 +1748,6 @@ dlg.Destroy() # creating location - # all credit to Michael Barton and his file_option.tcl and - # Markus Neteler try: cmdlist = ['g.proj','epsg=%s' % epsgcode,'datumtrans=-1'] p = cmd.Command(cmdlist) @@ -1768,8 +1820,6 @@ return False # creating location - # all credit to Michael Barton and his file_option.tcl and - # Markus Neteler try: cmdlist = ['g.proj','-c','georef=%s' % georeffile,'location=%s' % location] cmd.Command(cmdlist) From bundala at grass.itc.it Wed Jul 4 23:29:13 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Wed Jul 4 23:29:14 2007 Subject: [grass-addons] r928 - trunk/grassaddons/v.generalize Message-ID: <200707042129.l64LTD0r012015@grass.itc.it> Author: bundala Date: 2007-07-04 23:29:10 +0200 (Wed, 04 Jul 2007) New Revision: 928 Added: trunk/grassaddons/v.generalize/description.html Modified: trunk/grassaddons/v.generalize/smoothing.c Log: First version of documentation (description.html)) Added: trunk/grassaddons/v.generalize/description.html =================================================================== --- trunk/grassaddons/v.generalize/description.html (rev 0) +++ trunk/grassaddons/v.generalize/description.html 2007-07-04 21:29:10 UTC (rev 928) @@ -0,0 +1,117 @@ +

DESCRIPTION

+ +v.generalize +is module for simplification and smoothing of GRASS vector maps. This module +comprises a bunch of algortihms for both simplification and smoothing. + +

NOTES

+(Line) generalization is a process of reducing the compexity of vector features. +It transforms a line into another line which consists of fewer vertices but +still approximates the original line. In most of the algorithms below, this +process consists of picking subset of points of the original line. + +

+On the other hand, (line) smoothing is a "reverse" process which takes as an +input a line and produces smoother line which approximates the original line. +In some cases, this is achieved by inserting new vertices into the line. +Sometimes, the increase of the number of vertices is dramatical (4000%). +When this situation occurs, it is always a good idea to simplify the line after +smoothing. +

+

+All the algorithms implemented in this module work line by line. i.e simplification/smoothing +of one line does not affect the other lines. The first and the last point of +each line is never translated and/or deleted. +

+

+If the category ranges are provided, this module affects only the lines with (at least) one of the category numbers in (at least) one category range. +

+

SIMPLIFICATION

+

+v.generalize contains following line simplification algorithms +

    +
  • Douglas-Peucker Algorithm
  • +
  • Lang Algorithm
  • +
  • Vertex Reduction
  • +
  • Reumann-Witkam Algorithm
  • +
+

+Reuman-Witkam is the only algorithm which works only with 2D maps and does not +support 3D maps. All other algorithms (including smoothing) work with 3D maps. +

+ +Different algortihms requires different parameters, but all the algorithms have +one parameter in common. It is threshold parameter. In general, the degree +of simplification increases with the increasing value of threshold. + +

DETAIL DESCRIPTION

+ + + +

SMOOTHING

+

+The following smoothing algorithms are implemented in v.generalize +

    +
  • Boyle's Forward-Looking Algorithm - Works by taking the average of + look_ahead consecutive points
  • . Input parameters: input, look_ahead. +
  • McMaster's Distance-Weighting Algorithm - Works by taking the weighted average of look_ahead consecutive points + where the weight is the distance from the point to the currently smoothed point. And parameter threshold is used + for linear interpolation between the original position of the point and newly computed position where value 0 means the original position. + Input parameters: input, threshold, look_ahead. +
  • +
  • Chaiken's Algorithm - "Inscribes" a line touching the original line such that the points on this new line + are at least threshold apart. Input parameters: input, threshold. This algorithms + approximates given line very well.
  • +
  • Hermite Interpolation - This algorithm takes the points of the given line as the control + points of hermite cubic spline and approximates this spline by the points approximatelly threshold apart. + This method has excellent results for the small values of threshold, but in this case it produces + a huge number of new points and some simplification is usually needed. Input parameters: input, threshold.
  • +
  • Snakes is the method of minimization of the "energy" of the line. This method preserves the + general characteristcs of the lines but smooths the "sharp corners" of the line. Input parameters input, alfa, beta. + This algorithm works very well for small values of alfa and beta (between 0 and 5). These + parameters affects the "sharpness" and the curvature of the computed line.
  • +
+

+

+One of the key advantages of Hermite Interpolation is the fact that the computed line +always passes throught the points of the original line whereas the lines produced by the +remaining algorithms never pass through these points. In some sense, this algorihtm outputs +the line which "circumsrcibes" given line. On the other hand, Chaiken's Algorithm outputs +the line which "inscribes" given line. Moreover this line always touches/intersects the centre +of the line segment between two consecutive points. For many iterations, the property above does +not hold, but the computed lines are very similar to the Bezier Splines. The disadvantage of these +two algorithm is that they increase the number of point. +

+

+Note that Boyle's, McMaster's and Snakes algorithm are sometime used in the signal processing to smooth the signals. +More importantly, these algorithms never change the number of points on the lines. i.e they only +translate the points around, they do not insert any new points. +

+ +

SEE ALSO

+ + +v.clean
+

+ + +

AUTHORS

+Daniel Bundala, Google Summer of Code 2007, Student +
+Wolf Bergenheim, Mentor + +

Last changed: $Date: 2007/04/07 23:17:35 $ Property changes on: trunk/grassaddons/v.generalize/description.html ___________________________________________________________________ Name: svn:executable + * Modified: trunk/grassaddons/v.generalize/smoothing.c =================================================================== --- trunk/grassaddons/v.generalize/smoothing.c 2007-07-04 20:58:09 UTC (rev 927) +++ trunk/grassaddons/v.generalize/smoothing.c 2007-07-04 21:29:10 UTC (rev 928) @@ -307,9 +307,8 @@ * alfa, beta are 2 parameters which change the behaviour of the algorithm * * TODO: Add parameter iterations, so the runnining time is O(N^3 * log iterations) - * instead of O(N^3 * itearations) - * TODO: Solve the problems with the first and last few points. Probably, repeat - * the first/last point at the beginning/end of the line + * instead of O(N^3 * itearations). Probably not needed, for many iterations, + * the result is almost straight line */ int snakes(struct line_pnts *Points, double alfa, double beta, int with_z) { From barton at grass.itc.it Wed Jul 4 23:29:19 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Jul 4 23:29:22 2007 Subject: [grass-addons] r929 - trunk/grassaddons/gui/gui_modules Message-ID: <200707042129.l64LTJDX012036@grass.itc.it> Author: barton Date: 2007-07-04 23:29:11 +0200 (Wed, 04 Jul 2007) New Revision: 929 Modified: trunk/grassaddons/gui/gui_modules/cmd.py Log: Bug fix. Underscores ("_") generate an error when used in wx.MessageBox. Modified: trunk/grassaddons/gui/gui_modules/cmd.py =================================================================== --- trunk/grassaddons/gui/gui_modules/cmd.py 2007-07-04 21:29:10 UTC (rev 928) +++ trunk/grassaddons/gui/gui_modules/cmd.py 2007-07-04 21:29:11 UTC (rev 929) @@ -10,7 +10,7 @@ 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 @@ -29,10 +29,10 @@ 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 @@ -42,18 +42,18 @@ """ 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) @@ -74,13 +74,13 @@ # 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: @@ -97,7 +97,7 @@ 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() @@ -121,15 +121,15 @@ 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 = 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)) @@ -157,12 +157,12 @@ 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 = [] @@ -172,18 +172,18 @@ 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: From bundala at grass.itc.it Thu Jul 5 16:58:48 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Thu Jul 5 16:58:50 2007 Subject: [grass-addons] r930 - trunk/grassaddons/v.generalize Message-ID: <200707051458.l65EwmFK024128@grass.itc.it> Author: bundala Date: 2007-07-05 16:58:45 +0200 (Thu, 05 Jul 2007) New Revision: 930 Modified: trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/misc.c trunk/grassaddons/v.generalize/misc.h Log: oversimplified lines are removed; filtering by cats, where, layer and type; copying of attributes; some reorganization of code; bugfix: centroids outside the areas Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-04 21:29:11 UTC (rev 929) +++ trunk/grassaddons/v.generalize/main.c 2007-07-05 14:58:45 UTC (rev 930) @@ -42,14 +42,19 @@ char *mapset; struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out, *thresh_opt, *method_opt, *look_ahead_opt; - struct Option *iterations_opt, *cat_opt, *alfa_opt, *beta_opt; + struct Option *iterations_opt, *cat_opt, *alfa_opt, *beta_opt, *type_opt; + struct Option *field_opt, *where_opt; int with_z; int total_input, total_output; /* Number of points in the input/output map respectively */ double thresh, alfa, beta; int method; int look_ahead, iterations; - RANGE *ranges; - int n_ranges; + int chcat; + int ret, layer; + int n_areas; + double x, y; + int simplification, mask_type; + VARRAY *varray; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */ @@ -63,6 +68,10 @@ map_in = G_define_standard_option(G_OPT_V_INPUT); map_out = G_define_standard_option(G_OPT_V_OUTPUT); + type_opt = G_define_standard_option(G_OPT_V_TYPE); + type_opt->options = "line,boundary"; + type_opt->answer = "line,boundary"; + method_opt = G_define_option(); method_opt->key = "method"; method_opt->type = TYPE_STRING; @@ -118,13 +127,9 @@ iterations_opt->answer = "1"; iterations_opt->description = _("Number of iterations"); - cat_opt = G_define_option(); - cat_opt->key = "category"; - cat_opt->type = TYPE_STRING; - cat_opt->required = NO; - cat_opt->multiple = YES; - cat_opt->key_desc = "range"; - cat_opt->description = _("Category ranges: e.g. 1,3-8,13"); + field_opt = G_define_standard_option(G_OPT_V_FIELD); + cat_opt = G_define_standard_option(G_OPT_V_CATS); + where_opt = G_define_standard_option(G_OPT_WHERE); /* options and flags parser */ if (G_parser(argc, argv)) @@ -136,22 +141,9 @@ beta = atof(beta_opt->answer); iterations = atoi(iterations_opt->answer); + mask_type = type_mask(type_opt); + G_debug(3, "Method: %s", method_opt->answer); - /* check and store category ranges */ - if (cat_opt->answer != NULL) { - for (i = 0; cat_opt->answers[i]; i++) - if (!check_range(cat_opt->answers[i])) { - G_fatal_error(_("Bad category range in (%s)"), - cat_opt->answers[i]); - exit(-1); - }; - get_ranges(cat_opt->answers, &ranges, &n_ranges); - } - else - ranges = NULL; - - G_message(method_opt->answer); - if (method_opt->answer[0] == 'd' && method_opt->answer[1] == 'o') { method = DOUGLASS; } @@ -180,6 +172,20 @@ method = SNAKES; }; + /* simplification or smoothing? */ + switch (method) { + case DOUGLASS: + case LANG: + case VERTEX_REDUCTION: + case REUMANN: + simplification = 1; + break; + default: + simplification = 0; + break; + }; + + Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); @@ -201,53 +207,92 @@ G_fatal_error(_("Could not open output")); } + + /* parse filter option and select appropriate lines */ + layer = atoi(field_opt->answer); + if (where_opt->answer) { + if (layer < 1) + G_fatal_error(_("'layer' must be > 0 for 'where'")); + if (cat_opt->answer) + G_warning(_ + ("'where' and 'cats' parameters were supplied, cat will be ignored")); + chcat = 1; + varray = Vect_new_varray(Vect_get_num_lines(&In)); + if (Vect_set_varray_from_db + (&In, layer, where_opt->answer, mask_type, 1, varray) == -1) { + G_warning(_("Cannot load data from a database")); + }; + } + else if (cat_opt->answer) { + if (layer < 1) + G_fatal_error(_("'layer must be > 0 for 'cats'")); + varray = Vect_new_varray(Vect_get_num_lines(&In)); + chcat = 1; + if (Vect_set_varray_from_cat_string + (&In, layer, cat_opt->answer, mask_type, 1, varray) == -1) { + G_warning(_("Problem loading category values")); + }; + } + else + chcat = 0; + + Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); total_input = total_output = 0; - - i = 1; + i = 0; while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { + i++; + if (type == GV_CENTROID) + continue; /* skip old centroids, + * we calculate new */ total_input += Points->n_points; - if ((type == GV_LINE || 1 == 1) && - (ranges == NULL || cat_test(Cats, ranges, n_ranges))) { + + if ((type & mask_type) && (!chcat || varray->c[i])) { int after = 0; for (iter = 0; iter < iterations; iter++) { - if (method == DOUGLASS) { - after = douglass_peucker(Points, thresh, with_z); - } - else if (method == LANG) { - after = lang(Points, thresh, look_ahead, with_z); - } - else if (method == VERTEX_REDUCTION) { - after = vertex_reduction(Points, thresh, with_z); - } - else if (method == REUMANN) { - after = reumann_witkam(Points, thresh, with_z); - } - else if (method == BOYLE) { - after = boyle(Points, look_ahead, with_z); - } - else if (method == DISTANCE_WEIGHTING) { - after = - distance_weighting(Points, thresh, look_ahead, with_z); - } - else if (method == CHAIKEN) { - after = chaiken(Points, thresh, with_z); - } - else if (method == HERMITE) { - after = hermite(Points, thresh, with_z); - } - else { - after = snakes(Points, alfa, beta, with_z); + switch (method) { + case DOUGLASS: + douglass_peucker(Points, thresh, with_z); + break; + case LANG: + lang(Points, thresh, look_ahead, with_z); + break; + case VERTEX_REDUCTION: + vertex_reduction(Points, thresh, with_z); + break; + case REUMANN: + reumann_witkam(Points, thresh, with_z); + break; + case BOYLE: + boyle(Points, look_ahead, with_z); + break; + case DISTANCE_WEIGHTING: + distance_weighting(Points, thresh, look_ahead, with_z); + break; + case CHAIKEN: + chaiken(Points, thresh, with_z); + break; + case HERMITE: + hermite(Points, thresh, with_z); + break; + case SNAKES: + snakes(Points, alfa, beta, with_z); + break; }; }; + + /* remove "oversimplified" lines */ + if (simplification && type == GV_LINE && + Vect_line_length(Points) < thresh) + continue; + after = Points->n_points; total_output += after; Vect_write_line(&Out, type, Points, Cats); - } else { total_output += Points->n_points; @@ -255,12 +300,30 @@ }; } + + /* calculate new centroids */ + Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); + n_areas = Vect_get_num_areas(&In); + for (i = 1; i <= n_areas; i++) { + Vect_get_area_cats(&In, i, Cats); + ret = Vect_get_point_in_area(&Out, i, &x, &y); + if (ret < 0) { + G_warning(_("Cannot calculate area centroid")); + continue; + }; + Vect_reset_line(Points); + Vect_append_point(Points, x, y, 0.0); + Vect_write_line(&Out, GV_CENTROID, Points, Cats); + }; + + /* finally copy tables */ + Vect_copy_tables(&In, &Out, layer); + + Vect_build(&Out, stdout); + G_message("Number of vertices was reduced from %d to %d[%d%%]", total_input, total_output, (total_output * 100) / total_input); - G_free(ranges); - - Vect_build(&Out, stdout); Vect_close(&In); Vect_close(&Out); Modified: trunk/grassaddons/v.generalize/misc.c =================================================================== --- trunk/grassaddons/v.generalize/misc.c 2007-07-04 21:29:11 UTC (rev 929) +++ trunk/grassaddons/v.generalize/misc.c 2007-07-05 14:58:45 UTC (rev 930) @@ -22,64 +22,19 @@ #include #include "misc.h" -int check_range(char *s) +int type_mask(struct Option *type_opt) { - int from, to; - char dummy[2]; - if (strlen(s) == 0) - return 0; - - dummy[0] = 0; - if (sscanf(s, "%d-%d%1s", &from, &to, dummy) == 2) - return (from <= to) && (dummy[0] == 0); - - if (sscanf(s, "%d%1s", &from, dummy) == 1) - return (dummy[0] == 0); - - return 0; + int res = 0; + int i; + for (i = 0; type_opt->answers[i]; i++) + switch (type_opt->answers[i][0]) { + case 'l': + res |= GV_LINE; + break; + case 'b': + res |= GV_BOUNDARY; + break; + }; + return res; }; -int get_ranges(char **s, RANGE ** out, int *count) -{ - int n, i; - int from, to; - - n = 0; - while (s[n]) - n++; - *count = n; - - *out = (RANGE *) G_malloc(sizeof(RANGE) * n); - - if (!out) { - G_fatal_error(_("Out of memory")); - return 0; - }; - - - for (i = 0; i < n; i++) { - if (strchr(s[i], '-') == NULL) { - sscanf(s[i], "%d", &from); - to = from; - } - else - sscanf(s[i], "%d-%d", &from, &to); - (*out)[i].from = from; - (*out)[i].to = to; - }; - - return 1; -}; - -int cat_test(struct line_cats *Cats, RANGE * r, int n) -{ - int i, j; - - for (i = 0; i < Cats->n_cats; i++) { - for (j = 0; j < n; j++) - if (Cats->cat[i] >= r[j].from && Cats->cat[i] <= r[j].to) - return 1; - }; - - return 0; -}; Modified: trunk/grassaddons/v.generalize/misc.h =================================================================== --- trunk/grassaddons/v.generalize/misc.h 2007-07-04 21:29:11 UTC (rev 929) +++ trunk/grassaddons/v.generalize/misc.h 2007-07-05 14:58:45 UTC (rev 930) @@ -1,27 +1,9 @@ #ifndef MISC_H_ #define MISC_H_ -/* denotes the range [from,to] of integers */ -typedef struct -{ - int from, to; -} RANGE; - -/* verifies whether given string is valid (category) range - * either "number-number" where first <= second or "number" - * return 1 on success, 0 otherwise +/* returns bitmask for all the types specified in type_opt + * e.g GV_LINE | GV_BOUNDARY */ -int check_range(char *s); -/* sets the array of category ranges. Return 1 on success - * this function expects the valid ranges. i.e already checked - * and count is the number of ranges - */ -int get_ranges(char **s, RANGE ** out, int *count); +int type_mask(struct Option *type_opt); -/* tests whether at least one cetagory number lies in at least - * one range. Where n is the number of ranges in r. - * return 1 on success, 0 otherwise - */ -int cat_test(struct line_cats *Cats, RANGE * r, int n); - #endif From barton at grass.itc.it Fri Jul 6 06:01:37 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Jul 6 06:01:39 2007 Subject: [grass-addons] r931 - trunk/grassaddons/gui Message-ID: <200707060401.l6641bZS006375@grass.itc.it> Author: barton Date: 2007-07-06 06:01:29 +0200 (Fri, 06 Jul 2007) New Revision: 931 Modified: trunk/grassaddons/gui/location_wizard.py Log: location wizard working for all location creation types except xy. Extent setting not yet functional. Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-07-05 14:58:45 UTC (rev 930) +++ trunk/grassaddons/gui/location_wizard.py 2007-07-06 04:01:29 UTC (rev 931) @@ -3,6 +3,11 @@ import wx.lib.rcsizer as rcs import wx.lib.mixins.listctrl as listmix +try: + import subprocess +except: + from compat import subprocess + import os import sys import string @@ -291,14 +296,10 @@ self.parent.projtypepage.text_utm.SetEditable(False) self.parent.projtypepage.hemischoices = [] - global proj4string - if self.proj == 'll': - proj4string = '+proj=longlat' - else: - proj4string = '+proj=%s' % self.proj - def OnText(self, event): self.proj = event.GetString() + if self.proj in self.parent.projections: + self.projdesc = self.parent.projections[self.proj] def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -384,11 +385,6 @@ if self.parent.projpage.proj == 'utm' and self.utmzone == '': wx.MessageBox('You must set a zone for a UTM projection') event.Veto() - if self.parent.projpage.proj == 'utm': - global proj4string - proj4string = '%s +zone=%s' % (proj4string, self.utmzone) - if self.utmhemisphere == 'south': - proj4string = '%s +%s' % (proj4string, self.utmhemisphere) def SetVal(self, event): global coordsys @@ -517,22 +513,23 @@ # wx.MessageBox('You must select a datum transform') # event.Veto() self.GetNext().SetPrev(self) + self.parent.ellipsepage.ellipseparams = self.parent.ellipsoids[self.ellipsoid][1] global proj4string - for item in self.datumparams: - if item[:2] == 'f=': - item = 'r'+item - self.proj4params = '%s +%s' % (self.proj4params,item) - if self.transparams: - self.proj4params = '%s +no_defs +%s' % (self.proj4params,self.transparams) - proj4string = '%s %s' % (proj4string, self.proj4params) def OnDText(self, event): self.datum = event.GetString() + self.datumdesc = self.parent.datums[self.datum][0] + self.ellipsoid = self.parent.datums[self.datum][1] + self.datumparams = self.parent.datums[self.datum][2] + self._onBrowseParams(None,self.datum) def OnTText(self, event): self.transform = event.GetString() + self.transdatum = self.parent.transforms[self.transform][0] + self.transregion = self.parent.transforms[self.transform][1] + self.transparams = self.parent.transforms[self.transform][2] def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -694,19 +691,14 @@ wx.MessageBox('You must select an ellipse') event.Veto() self.GetNext().SetPrev(self) + self.parent.datumpage.datumparams = '' + self.parent.datumpage.transparams = '' - global proj4string - for item in self.ellipseparams: - if item[:2] == 'f=': - item = '+r'+item - else: - item = '+'+str(item) - self.proj4params = '%s %s' % (params, item) - self.proj4params = '%s +no_defs' % self.proj4params - proj4string = '%s %s' % (proj4string,self.proj4params) - def OnText(self, event): self.ellipse = event.GetString() + if self.ellipse in self.parent.ellipseoids: + self.ellipsedesc = self.parent.ellipsoids[self.ellipse][0] + self.ellipseparams = self.parent.ellipsoids[self.ellipse][1] def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -878,6 +870,7 @@ # events self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse) self.Bind(wx.EVT_BUTTON, self.OnBrowseCodes, self.bbcodes) + self.Bind(wx.EVT_TEXT, self.OnText, self.tcode) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsglist) self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) @@ -888,6 +881,9 @@ event.Veto() self.GetNext().SetPrev(self) + def OnText(self, event): + self.epsgcode = self.GetString() + def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.epsglist.GetColumn(1) @@ -968,7 +964,7 @@ def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters") global coordsys - global proj4string + self.proj4string = '' self.parent = parent self.text_proj4string = self.MakeTextCtrl(size=(400,100)) @@ -983,15 +979,14 @@ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange) def OnPageChange(self, event): - global proj4string - if not proj4string: + if not self.proj4string: wx.MessageBox('You must enter a PROJ.4 string') event.Veto() self.GetNext().SetPrev(self) def GetProjstring(self, event): - global proj4string - proj4string = event.GetString() + proj4string + self.proj4string = event.GetString() class SummaryPage(TitledPage): @@ -1649,7 +1644,6 @@ database = self.startpage.grassdatabase location = self.startpage.location global coordsys - global proj4string success = '' # wx.MessageBox("finished database: %s, location: %s, coordsys: %s" % (database, location, coordsys)) @@ -1668,8 +1662,10 @@ cols = int(round((float(east)-float(west))/float(resolution))) cells = int(rows*cols) success = self.LatlongCreate() - elif coordsys == "proj" or coordsys == 'custom': + elif coordsys == "proj": success = self.Proj4Create() + elif coordsys == 'custom': + success - self.CustomCreate elif coordsys == "epsg": success = self.EPSGCreate() elif coordsys == "file": @@ -1688,16 +1684,86 @@ """ Create a new location for selected projection """ - global proj4string + location = self.startpage.location + proj = self.projpage.proj projdesc = self.projpage.projdesc + + utmzone = self.projtypepage.utmzone + utmhemisphere = self.projtypepage.utmhemisphere + + datum = self.datumpage.datum if self.datumpage.datumdesc: datumdesc = self.datumpage.datumdesc+' - '+self.datumpage.ellipsoid else: datumdesc = '' + datumparams = self.datumpage.datumparams + transparams = self.datumpage.transparams + + ellipse = self.ellipsepage.ellipse ellipsedesc = self.ellipsepage.ellipsedesc + ellipseparams = self.ellipsepage.ellipseparams - dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to \ - %s: %s%s" % (location, projdesc, datumdesc, ellipsedesc), + # Creating PROJ.4 string + if proj == 'll': + proj = 'longlat' + + if proj == 'utm' and utmhemisphere == 'south': + proj4string = '+proj=%s +zone=%s +south' % (proj, utmzone) + elif proj == 'utm': + proj4string = '+proj=%s +zone=%s' % (proj, utmzone) + else: + proj4string = '+proj=%s ' % (proj) + + proj4params = '' + # set ellipsoid parameters + for item in ellipseparams: + if item[:4] == 'f=1/': + item = '+rf='+item[4:] + else: + item = '+'+item + proj4params = '%s %s' % (proj4params, item) + # set datum and transform parameters if relevant + if datumparams: + for item in datumparams: + proj4params = '%s +%s' % (proj4params,item) + if transparams: + proj4params = '%s +no_defs +%s' % (proj4params,transparams) + else: + proj4params = '%s +no_defs' % proj4params + else: + proj4params = '%s +no_defs' % proj4params + + proj4string = '%s %s' % (proj4string, proj4params) + + dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to \n\ + %s: %s%s\n\ + (PROJ.4 string: %s)" % (location,projdesc,datumdesc,ellipsedesc,proj4string), + "Create new location?", + wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) + if dlg.ShowModal() == wx.ID_NO: + dlg.Destroy() + return False + else: + dlg.Destroy() + + # Creating location from PROJ.4 string passed to g.proj + try: + cmdlist = ['g.proj', '-c', 'proj4=%s' % proj4string, 'location=%s' % location] + cmd.Command(cmdlist) + return True + + except StandardError, e: + dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e), + "Could not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + return False + + def CustomCreate(self): + proj4string = self.custompage.proj4string + + dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created using \ + PROJ.4 string: %s" % (location,proj4string), "Create new location?", wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_NO: @@ -1706,7 +1772,6 @@ else: dlg.Destroy() - # creating location from PROJ.4 string try: cmdlist = ['g.proj','-c','proj4="%s"' % proj4string,'location=%s' % location] wx.MessageBox('cmdlist: %s' % cmdlist) From barton at grass.itc.it Fri Jul 6 08:30:42 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Jul 6 08:30:44 2007 Subject: [grass-addons] r932 - trunk/grassaddons/gui Message-ID: <200707060630.l666Ug4e007850@grass.itc.it> Author: barton Date: 2007-07-06 08:30:34 +0200 (Fri, 06 Jul 2007) New Revision: 932 Modified: trunk/grassaddons/gui/location_wizard.py Log: Bug fix for custom PROJ.4 string location creation. Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-07-06 04:01:29 UTC (rev 931) +++ trunk/grassaddons/gui/location_wizard.py 2007-07-06 06:30:34 UTC (rev 932) @@ -1773,8 +1773,7 @@ dlg.Destroy() try: - cmdlist = ['g.proj','-c','proj4="%s"' % proj4string,'location=%s' % location] - wx.MessageBox('cmdlist: %s' % cmdlist) + cmdlist = ['g.proj','-c','proj4=%s' % proj4string,'location=%s' % location] cmd.Command(cmdlist) return True From barton at grass.itc.it Fri Jul 6 08:52:15 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Jul 6 08:52:17 2007 Subject: [grass-addons] r933 - trunk/grassaddons/gui Message-ID: <200707060652.l666qFKP007874@grass.itc.it> Author: barton Date: 2007-07-06 08:52:07 +0200 (Fri, 06 Jul 2007) New Revision: 933 Modified: trunk/grassaddons/gui/location_wizard.py Log: Added copyright header and docstrings Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-07-06 06:30:34 UTC (rev 932) +++ trunk/grassaddons/gui/location_wizard.py 2007-07-06 06:52:07 UTC (rev 933) @@ -1,23 +1,52 @@ +""" +MODULE: location_wizard.py + +CLASSES: + * TitledPage + * DatabasePage + * CoordinateSystemPage + * ProjectionsPage + * ProjTypePage + * DatumPage + * EllipsePage + * GeoreferencedFilePage + * EPSGPage + * CustomPage + * SummaryPage + * BBoxPage + * GWizard + +PURPOSE: Create a new GRASS location. User can choose from multiple methods + +AUTHORS: The GRASS Development Team + Michael Barton + Jachym Cepicky + +COPYRIGHT: (C) 2006-2007 by the GRASS Development Team + This program is free software under the GNU General Public + License (>=v2). Read the file COPYING that comes with GRASS + for details. +""" +import gui_modules +import gui_modules.cmd as cmd +import os +import re +import string +import sys import wx +import wx.lib.mixins.listctrl as listmix +import wx.lib.rcsizer as rcs import wx.wizard as wiz -import wx.lib.rcsizer as rcs -import wx.lib.mixins.listctrl as listmix try: import subprocess except: from compat import subprocess -import os -import sys -import string -import re -import gui_modules gmpath = gui_modules.__path__[0] sys.path.append(gmpath) -import gui_modules.cmd as cmd global coordsys global north @@ -37,6 +66,10 @@ proj4string = '' class TitledPage(wiz.WizardPageSimple): + """ + Class to make wizard pages. Generic methods to make + labels, text entries, and buttons. + """ def __init__(self, parent, title): wiz.WizardPageSimple.__init__(self, parent) @@ -54,6 +87,7 @@ self.SetAutoLayout(True) def MakeRLabel(self, text=""): + """Make right-aligned label""" try: if text[-1] != " ": text += " " @@ -62,6 +96,7 @@ return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT) def MakeLLabel(self, text=""): + """Make left-aligned label""" try: if text[-1] != " ": text += " " @@ -70,15 +105,20 @@ return wx.StaticText(self, -1, text, style=wx.ALIGN_LEFT) def MakeTextCtrl(self,text='', size=(100,-1)): + """Generic text control""" return wx.TextCtrl(self,-1, text, size=size) def MakeButton(self,text, size=(75,25)): + """Generic button""" return wx.Button(self, -1, text, style=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, size=size) class DatabasePage(TitledPage): + """ + Wizard page for setting GIS data directory and location name + """ def __init__(self, wizard, parent, grassdatabase): TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") @@ -163,8 +203,11 @@ class CoordinateSystemPage(TitledPage): + """ + Wizard page for choosing method for location creation + """ def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose coordinate system for location") + TitledPage.__init__(self, wizard, "Choose method for creating a new location") self.parent = parent global coordsys @@ -228,6 +271,9 @@ class ProjectionsPage(TitledPage): + """ + Wizard page for selecting projection (select coordinate system option) + """ def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose projection") @@ -346,6 +392,11 @@ dlg.Destroy() class ProjTypePage(TitledPage): + """ + Wizard page for selecting method of setting coordinate system parameters + (select coordinate system option) + """ + def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters") global coordsys @@ -401,6 +452,11 @@ class DatumPage(TitledPage): + """ + Wizard page for selecting datum (with associated ellipsoid) + and datum transformation parameters (select coordinate system option) + """ + def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Specify geodetic datum") @@ -627,6 +683,10 @@ class EllipsePage(TitledPage): + """ + Wizard page for selecting ellipsoid (select coordinate system option) + """ + def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Specify ellipsoid") @@ -751,6 +811,11 @@ class GeoreferencedFilePage(TitledPage): + """ + Wizard page for selecting georeferenced file to use + for setting coordinate system parameters + """ + def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Select georeferenced file") @@ -798,6 +863,11 @@ class EPSGPage(TitledPage): + """ + Wizard page for selecting EPSG code for + setting coordinate system parameters + """ + def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose EPSG Code") self.parent = parent @@ -961,6 +1031,11 @@ class CustomPage(TitledPage): + """ + Wizard page for entering custom PROJ.4 string + for setting coordinate system parameters + """ + def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters") global coordsys @@ -990,6 +1065,10 @@ class SummaryPage(TitledPage): + """ + Shows summary result of choosing coordinate system parameters + prior to creating location + """ def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Summary") @@ -1112,6 +1191,10 @@ class BBoxPage(TitledPage): + """ + Wizard page for setting default region extents and resolution + """ + def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Set default region extents and resolution") @@ -1487,6 +1570,10 @@ class GWizard: + """ + Start wizard here and finish wizard here + """ + def __init__(self, parent, grassdatabase): wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","images","wizard.png"), wx.BITMAP_TYPE_PNG) wizbmp.Rescale(250,600) From barton at grass.itc.it Sat Jul 7 00:01:08 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Jul 7 00:01:09 2007 Subject: [grass-addons] r934 - trunk/grassaddons Message-ID: <200707062201.l66M1830020625@grass.itc.it> Author: barton Date: 2007-07-07 00:01:03 +0200 (Sat, 07 Jul 2007) New Revision: 934 Added: trunk/grassaddons/LandDyn/ Log: Renaming landscape_evol to LandDyn. Will house multiple scripts for modeling landscape dynamics. From barton at grass.itc.it Sat Jul 7 00:02:25 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Jul 7 00:02:26 2007 Subject: [grass-addons] r935 - trunk/grassaddons Message-ID: <200707062202.l66M2PYq020653@grass.itc.it> Author: barton Date: 2007-07-07 00:02:21 +0200 (Sat, 07 Jul 2007) New Revision: 935 Added: trunk/grassaddons/r.landscape_evol/ Log: new directory for script From barton at grass.itc.it Sat Jul 7 00:05:56 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Jul 7 00:05:57 2007 Subject: [grass-addons] r936 - in trunk/grassaddons: . LandDyn Message-ID: <200707062205.l66M5uOs020673@grass.itc.it> Author: barton Date: 2007-07-07 00:05:43 +0200 (Sat, 07 Jul 2007) New Revision: 936 Added: trunk/grassaddons/LandDyn/r.landscape_evol/ Removed: trunk/grassaddons/r.landscape_evol/ Log: Moving directory into LandDyn Copied: trunk/grassaddons/LandDyn/r.landscape_evol (from rev 935, trunk/grassaddons/r.landscape_evol) From barton at grass.itc.it Sat Jul 7 00:08:47 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Jul 7 00:08:50 2007 Subject: [grass-addons] r937 - in trunk/grassaddons: LandDyn/r.landscape_evol landscape_evol Message-ID: <200707062208.l66M8lLX020702@grass.itc.it> Author: barton Date: 2007-07-07 00:08:31 +0200 (Sat, 07 Jul 2007) New Revision: 937 Added: trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol Removed: trunk/grassaddons/landscape_evol/r.landscape.evol Log: Moving script to its own directory within LandDyn Copied: trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol (from rev 936, trunk/grassaddons/landscape_evol/r.landscape.evol) =================================================================== --- trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol (rev 0) +++ trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol 2007-07-06 22:08:31 UTC (rev 937) @@ -0,0 +1,1279 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.landscape.evol +# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University +# Helena Mitasova, North Carolina State University +# PURPOSE: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net +# erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil +# depth maps. This module uses appropriate flow on different landforms by default; however, +# singular flow regimes can be chosen instead. +# ACKNOWLEDGEMENTS:National Science Foundation Grant #BCS0410269 +# Based on work of H. Mitasova and C. S. Thaxton, and Heimsath et al, 1997. +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil depth maps. This module uses appropriate flow on different landforms by default; however, singular flow regimes can be chosen instead. THIS SCRIPT WILL PRODUCE MANY TEMPORARY MAPS AND REQUIRES A LOT OF FREE FILE SPACE! +#%End + +#%option +#% key: elev +#% type: string +#% gisprompt: old,cell,raster +#% description: Input elevation map (DEM) +#% required : yes +#% guisection: Input +#%end +#%option +#% key: initbdrk +#% type: string +#% gisprompt: old,cell,raster +#% description: Initial bedrock elevations map (for first iteration only) +#% answer: +#% required : yes +#% guisection: Input +#%end +#%option +#% key: prefx +#% type: string +#% description: Prefix for all output maps +#% answer: usped +#% required : yes +#% 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 +#%end +#%flag +#% key: k +#% description: -k Keep all intermediate files as well +#% guisection: Input +#%end +#%flag +#% key: z +#% description: -z Keep region zoomed to output maps +#% answer: 1 +#% guisection: Input +#%end +#%flag +#% key: b +#% description: -b Use static bedrock elavations (do not create new soil) +#% answer: 1 +#% guisection: Input +#%end + + +#%option +#% key: R +#% type: string +#% description: Rainfall (R factor) constant or map +#% gisprompt: old,cell,raster +#% answer: 5 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: K +#% type: string +#% gisprompt: old,cell,raster +#% description: Soil erodability index (K factor) map or constant +#% answer: 0.32 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: C +#% type: string +#% gisprompt: old,cell,raster +#% description: Landcover index (C factor) map or constant +#% answer: 0.01 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: kappa +#% type: string +#% gisprompt: old,cell,raster +#% description: Hillslope diffusion (Kappa) rate map or constant (meters per kiloyear) +#% answer: 1 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: cutoff +#% type: string +#% description: Flow accumultion breakpoint value for shift from diffusion to overland flow (number of cells) +#% answer: 8 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: number +#% type: integer +#% description: number of iterations to run +#% answer: 1 +#% required : yes +#% guisection: Variables +#%end + + +#these are commented out as we currently utilize the profile curvature method described by Heimsath et al... +# #%option +# #% key: Ba +# #% type: string +# #% description: Rate of average soil production (Ba) +# #% answer: 0.00008 +# #% required : yes +# #% guisection: Variables +# #%end +# #%option +# #% key: Bb +# #% type: string +# #% description: Relationship between soil depth and production rate (Bb) +# #% answer: 0.1 +# #% required : yes +# #% guisection: Variables +# #%end + +#%flag +#% key: y +#% description: -y Don't smooth the map (faster, but spikes in erosion/deposition may result) +#% guisection: Smoothing_Filter +#%end +#%option +#% key: nbhood +#% type: string +#% description: Band-pass filter neighborhood size +#% answer: 3 +#% options: 1,3,5,7,9,11,13,15,17,19,21,23,25 +#% 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 +#% description: Neighborhood smoothing method +#% answer: median +#% options: median,mode,average +#% required : yes +#% guisection: Smoothing_Filter +#%end + +#%flag +#% key: c +#% description: -c Output cumulative erosion/depostition map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: m +#% description: -m Output mean erosion/depostition map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: t +#% description: -t Output standard deviation of erosion/depostition map from data for all iterations +#% 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 +#%end +#%flag +#% key: v +#% description: -v Output standard deviation soil depths map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: a +#% description: -a Output maximum soil depths map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: u +#% description: -u Output minimum soil depths map from data for all iterations +#% guisection: Statistics +#%end + +#%flag +#% key: w +#% description: -w Calcuate for only sheetwash across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: r +#% description: -r Calcuate for only channelized flow across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: d +#% description: -d Calcuate for only diffusive flow (soil creep) across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: f +#% description: -f Use r.terrflow instead of r.flow to calculate flow accumulation (better for massive grids) +#% guisection: Flow_type +#%end + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +prefx=$GIS_OPT_prefx +elev=$GIS_OPT_elev +initbdrk=$GIS_OPT_initbdrk +R=$GIS_OPT_R +K=$GIS_OPT_K +C=$GIS_OPT_C +kappa=$GIS_OPT_kappa +Ba=$GIS_OPT_Ba +Bb=$GIS_OPT_Bb +aplpha=$GIS_OPT_method +sigma=$GIS_OPT_sigma +nbhood=$GIS_OPT_nbhood +cutoff=$GIS_OPT_cutoff +echo "The following temporary files will be created:" +echo "" +neighbors=$prefx".neighbors1" +echo "neighbors=$neighbors" +tempsmoothdz=$prefx".tempsmoothdz1" +echo "tempsmoothdz=$tempsmoothdz" +smoothdz=$prefx"_smoothdz1" +echo "smoothdz=$smoothdz" +tempsmoothdz=$prefx".tempsmoothdz1" +echo "temsmoothpdz=$tempsmoothdz" +flowacc=$prefx".flowacc1" +echo "flowacc=$flowacc" +slope=$prefx".slope1" +echo "slope=$slope" +aspect=$prefx".aspect1" +echo "aspect=$aspect" +pc=$prefx".pc1" +echo "pc=$pc" +tc=$prefx".tc1" +echo "tc=$tc" +meancurv=$prefx".meancurv1" +echo "meancurv=$meancurv" +rate=$prefx".rate1" +echo "rate=$rate" +sflowtopo=$prefx".sflowtopo1" +echo "sflowtopo=$sflowtopo" +qsx=$prefx".qsx1" +echo "qsx=$qsx" +qsy=$prefx".qsy1" +echo "qsy=$qsy" +qsxdx=$prefx".qsx.dx1" +echo "qsxdx=$qsxdx" +qsydy=$prefx".qsy.dy1" +echo "qsydy=$qsydy" +m=$prefx".m1" +echo "m=$m" +n=$prefx".n1" +echo "n=$n" +erdep=$prefx".erosdep1" +echo "erdep=$erdep" +initsoil=$prefx".initsoil" + +echo "" + +new_soil=$prefx"_new_soil1" +new_dem=$prefx"_new_dem1" +initsoil=$prefx"_initsoil" +echo "Initial soil depths calculated will be in $initsoil" +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"_new_bdrk1" +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` + +# we must set the region to the map being used. otherwise r.flow will not work +echo "" +echo "Setting region to $elev" +g.region rast=$elev + +#now lets show before: +echo "" +echo "Original Resolution = $res1" + +#...and after: +res=`eval g.region -p -m | grep "nsres:" | cut -d : -f 2` +echo "" +echo "New Resolution = $res" + + +echo "" +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 "_____________________________________________________________" +# 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 +echo "" +echo "##################################################" +echo "##################################################" +echo "" +echo "ITERATION 1" +echo "" +echo "##################################################" +echo "" +echo "*************************" +echo "step 1 of 8: calculating slope and aspect (if initial aspect not specified)" +echo "*************************" +echo "" + + +r.slope.aspect --q $elev 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" + +r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp + +r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" + +g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" +rm -f /var/tmp/STREAM* + +else + +echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + +tmpflacc=$prefx".tmpflacc" + +r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc + +r.mapcalc "$flowacc=$tmpflacc*$res" + +g.remove --quiet rast=$tmpflacc + +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.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` + +echo "" +echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +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)))" + +report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` +report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` + +echo "" +echo "(for diagnostics only) max m = $report1, min m = $report2" + + +r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff, 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 fully 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 "$initsoil=$elev - $initbdrk" + +echo "" +echo "*************************" +echo "step 7 of 8: running band-pass filter" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_y" -eq 1 ]; then + +echo ""echo "You have selected not to smooth your files... Oh Well!" +echo "" + +r.mapcalc "$smoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" + +else + + +r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood +r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" +r.mapcalc "$smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" + +fi + +# create temporary file to code colors for $smoothdz +TMP1=`g.tempfile pid=$$` + +if [ $? -ne 0 ] || [ -z "$TMP1" ]; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +else + + echo "creating temporary file to code colors" + +fi + + +echo "0% 255 000 255" > $TMP1 +echo "-5 255 000 255" >> $TMP1 +echo "-3 red" >> $TMP1 +echo "-1 orange" >> $TMP1 +echo "-0.5 yellow" >> $TMP1 +echo "0 white" >> $TMP1 +echo "0.5 green" >> $TMP1 +echo "1 cyan" >> $TMP1 +echo "3 aqua" >> $TMP1 +echo "5 violet" $TMP1 +echo "100% 104 034 139" >> $TMP1 +echo "end" >> $TMP1 + + +cat $TMP1 | r.colors --q map=$smoothdz color=rules + +echo "" +echo "*************************" +echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" +echo "*************************" +echo "" + +r.mapcalc "$new_dem=$smoothdz + $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" + + +new_bdrk=$initbdrk +r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" + +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))" + +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))" + +#grabsomestats +tmperosion=$prfx"_tmperosion1" +tmpdep=$prfx"_tmpdep1" + +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 + +txtout=$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 "*************************" + + + +echo "" +echo "Raster map $smoothdz shows filtered net erosion/deposition" +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 "" +# echo "Done" +# echo "" +#else +# echo "" +# echo "Cleaning up..." +# g.remove rast=$flowacc,$slope,$aspect,$sflowtopo,$qsx,$qsy,$qsxdx,$qsydy,$erdep,$neighbors +# echo "" +# echo "Done" +#fi + + +#remove the temp files to avoid confusion...\rm -f $TMP1 $TMP1.sort + + +number=$GIS_OPT_number +echo "total number of iterations to be run= $number" +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"_new_dem"$laststep + +echo "The following temporary files will be created:" +echo "" +neighbors=$prefx".neighbors"$step +echo "neighbors=$neighbors" +tempsmoothdz=$prefx".tempsmoothdz"$step +echo "tempsmoothdz=$tempsmoothdz" +temp2smoothdz=$prefx".temp2smoothdz"$step +echo "temp2smoothdz=$temp2smoothdz" +smoothdz=$prefx"_smoothdz"$step +echo "smoothdz=$smoothdz" +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".m"$step +echo "m=$m" +n=$prefx".n"$step +echo "n=$n" +erdep=$prefx".erosdep"$step +echo "erdep=$erdep" +old_bdrk=$prefx"_new_bdrk"$laststep +echo "old_bdrk=$old_bdrk" +old_soil=$prefx"_new_soil"$laststep +echo "old_soil=$old_soil" +echo "" + +new_soil=$prefx"_new_soil"$step +new_dem=$prefx"_new_dem"$step +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"_new_bdrk"$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" + +r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp + +r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" + +g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" +rm -f /var/tmp/STREAM* + +else + +echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + +tmpflacc=$prefx".tmpflacc" +r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc + +r.mapcalc "$flowacc=$tmpflacc*$res" + +g.remove --quiet rast=$tmpflacc + +fi + + + +echo "" +echo "*************************" +echo "step 3 of 8: calculating basic sediment transport rates" +echo "*************************" +echo "" + + +initbdrk + +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),$m) * exp(sin($slope),$n)" + + +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.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` + + +echo "" +echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +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 "$sflowtopo=if ($flowacc >= $cutoff, 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 band-pass 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 + +r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood +r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $old_soil, (-1 * $old_soil), $erdep)" +r.mapcalc "$temp2smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" + +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 + + +# create temporary file to code colors for $smoothdz +TMP1=`g.tempfile pid=$$` + +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +else + echo "creating temporary file to code colors" + +fi + +echo "0% 255 000 255" > $TMP1 +echo "-5 255 000 255" >> $TMP1 +echo "-3 red" >> $TMP1 +echo "-1 orange" >> $TMP1 +echo "-0.5 yellow" >> $TMP1 +echo "0 white" >> $TMP1 +echo "0.5 green" >> $TMP1 +echo "1 cyan" >> $TMP1 +echo "3 aqua" >> $TMP1 +echo "5 violet" $TMP1 +echo "100% 104 034 139" >> $TMP1 +echo "end" >> $TMP1 + + +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" +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" + + +new_bdrk=$old_bdrk +r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" + +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))" + +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))" + + +#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 "Raster map $smoothdz shows filtered net erosion/deposition" +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 + + +# 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 + exit 1 +fi + + +g.mlist type=rast sep=, pattern=$prefx"_smoothdz*" > $TMP2 +liststring=`cat $TMP2` + +echo "Any selected statistics will be performed using the following smoothdz files: $liststring" + +if [ "$GIS_FLAG_c" -eq 1 ]; then + +r.series --q input=$liststring output=$prefx"_cum_erdep" method=sum +fi + +if [ "$GIS_FLAG_m" -eq 1 ]; then + +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 + +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 + + + +# 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 +fi + +g.mlist type=rast sep=, pattern=$prefx"_new_soil*" > $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_soil" method=average +fi + +if [ "$GIS_FLAG_v" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_sdev_soil" method=stddev +fi + +if [ "$GIS_FLAG_a" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_max_soil" method=maximum +fi + + +if [ "$GIS_FLAG_u" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_min_soil" method=minimum +fi +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort + + +echo "************************" + +if [ "$GIS_FLAG_k" -eq 1 ]; then + +echo "" +echo "Done" +echo "" + +else + +echo "" +echo "Cleaning up..." + +g.mremove -f --q rast=$prefx".neighbors*" +g.mremove -f --q rast=$prefx".smoothdz*" +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".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".m*" +g.mremove -f --q rast=$prefx".n*" + + echo "" + echo "Done" + +fi + +if [ "$GIS_FLAG_n" -eq 1 ]; then + + g.mremove --q rast=$prefx"_smoothdz*" +fi + +if [ "$GIS_FLAG_l" -eq 1 ]; then + + g.mremove --q rast=$prefx"_new_soil*" +fi + +if [ "$GIS_FLAG_z" -eq 1 ]; then +echo "" +echo "Iterations complete, keeping region set to output maps" +echo "" +else +echo "" +echo "Iterations complete, restoring default region settings" +echo "" + +g.region -d -g + +echo "" +fi +echo "###################################################" +echo "###################################################" +echo "___________________________________________________" +echo "" +echo " DONE WITH EVERYHTING" +echo "" +echo "___________________________________________________" + + + + Deleted: trunk/grassaddons/landscape_evol/r.landscape.evol =================================================================== --- trunk/grassaddons/landscape_evol/r.landscape.evol 2007-07-06 22:05:43 UTC (rev 936) +++ trunk/grassaddons/landscape_evol/r.landscape.evol 2007-07-06 22:08:31 UTC (rev 937) @@ -1,1279 +0,0 @@ -#!/bin/sh -# -############################################################################ -# -# MODULE: r.landscape.evol -# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University -# Helena Mitasova, North Carolina State University -# PURPOSE: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net -# erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil -# depth maps. This module uses appropriate flow on different landforms by default; however, -# singular flow regimes can be chosen instead. -# ACKNOWLEDGEMENTS:National Science Foundation Grant #BCS0410269 -# Based on work of H. Mitasova and C. S. Thaxton, and Heimsath et al, 1997. -# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University -# This program is free software under the GNU General Public -# License (>=v2). Read the file COPYING that comes with GRASS -# for details. -# -############################################################################# - - -#%Module -#% description: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil depth maps. This module uses appropriate flow on different landforms by default; however, singular flow regimes can be chosen instead. THIS SCRIPT WILL PRODUCE MANY TEMPORARY MAPS AND REQUIRES A LOT OF FREE FILE SPACE! -#%End - -#%option -#% key: elev -#% type: string -#% gisprompt: old,cell,raster -#% description: Input elevation map (DEM) -#% required : yes -#% guisection: Input -#%end -#%option -#% key: initbdrk -#% type: string -#% gisprompt: old,cell,raster -#% description: Initial bedrock elevations map (for first iteration only) -#% answer: -#% required : yes -#% guisection: Input -#%end -#%option -#% key: prefx -#% type: string -#% description: Prefix for all output maps -#% answer: usped -#% required : yes -#% 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 -#%end -#%flag -#% key: k -#% description: -k Keep all intermediate files as well -#% guisection: Input -#%end -#%flag -#% key: z -#% description: -z Keep region zoomed to output maps -#% answer: 1 -#% guisection: Input -#%end -#%flag -#% key: b -#% description: -b Use static bedrock elavations (do not create new soil) -#% answer: 1 -#% guisection: Input -#%end - - -#%option -#% key: R -#% type: string -#% description: Rainfall (R factor) constant or map -#% gisprompt: old,cell,raster -#% answer: 5 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: K -#% type: string -#% gisprompt: old,cell,raster -#% description: Soil erodability index (K factor) map or constant -#% answer: 0.32 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: C -#% type: string -#% gisprompt: old,cell,raster -#% description: Landcover index (C factor) map or constant -#% answer: 0.01 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: kappa -#% type: string -#% gisprompt: old,cell,raster -#% description: Hillslope diffusion (Kappa) rate map or constant (meters per kiloyear) -#% answer: 1 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: cutoff -#% type: string -#% description: Flow accumultion breakpoint value for shift from diffusion to overland flow (number of cells) -#% answer: 8 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: number -#% type: integer -#% description: number of iterations to run -#% answer: 1 -#% required : yes -#% guisection: Variables -#%end - - -#these are commented out as we currently utilize the profile curvature method described by Heimsath et al... -# #%option -# #% key: Ba -# #% type: string -# #% description: Rate of average soil production (Ba) -# #% answer: 0.00008 -# #% required : yes -# #% guisection: Variables -# #%end -# #%option -# #% key: Bb -# #% type: string -# #% description: Relationship between soil depth and production rate (Bb) -# #% answer: 0.1 -# #% required : yes -# #% guisection: Variables -# #%end - -#%flag -#% key: y -#% description: -y Don't smooth the map (faster, but spikes in erosion/deposition may result) -#% guisection: Smoothing_Filter -#%end -#%option -#% key: nbhood -#% type: string -#% description: Band-pass filter neighborhood size -#% answer: 3 -#% options: 1,3,5,7,9,11,13,15,17,19,21,23,25 -#% 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 -#% description: Neighborhood smoothing method -#% answer: median -#% options: median,mode,average -#% required : yes -#% guisection: Smoothing_Filter -#%end - -#%flag -#% key: c -#% description: -c Output cumulative erosion/depostition map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: m -#% description: -m Output mean erosion/depostition map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: t -#% description: -t Output standard deviation of erosion/depostition map from data for all iterations -#% 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 -#%end -#%flag -#% key: v -#% description: -v Output standard deviation soil depths map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: a -#% description: -a Output maximum soil depths map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: u -#% description: -u Output minimum soil depths map from data for all iterations -#% guisection: Statistics -#%end - -#%flag -#% key: w -#% description: -w Calcuate for only sheetwash across entire map -#% guisection: Flow_type -#%end -#%flag -#% key: r -#% description: -r Calcuate for only channelized flow across entire map -#% guisection: Flow_type -#%end -#%flag -#% key: d -#% description: -d Calcuate for only diffusive flow (soil creep) across entire map -#% guisection: Flow_type -#%end -#%flag -#% key: f -#% description: -f Use r.terrflow instead of r.flow to calculate flow accumulation (better for massive grids) -#% guisection: Flow_type -#%end - - - -if [ -z "$GISBASE" ] ; then - echo "You must be in GRASS GIS to run this program." >&2 - exit 1 -fi - -if [ "$1" != "@ARGS_PARSED@" ] ; then - exec g.parser "$0" "$@" -fi - -prefx=$GIS_OPT_prefx -elev=$GIS_OPT_elev -initbdrk=$GIS_OPT_initbdrk -R=$GIS_OPT_R -K=$GIS_OPT_K -C=$GIS_OPT_C -kappa=$GIS_OPT_kappa -Ba=$GIS_OPT_Ba -Bb=$GIS_OPT_Bb -aplpha=$GIS_OPT_method -sigma=$GIS_OPT_sigma -nbhood=$GIS_OPT_nbhood -cutoff=$GIS_OPT_cutoff -echo "The following temporary files will be created:" -echo "" -neighbors=$prefx".neighbors1" -echo "neighbors=$neighbors" -tempsmoothdz=$prefx".tempsmoothdz1" -echo "tempsmoothdz=$tempsmoothdz" -smoothdz=$prefx"_smoothdz1" -echo "smoothdz=$smoothdz" -tempsmoothdz=$prefx".tempsmoothdz1" -echo "temsmoothpdz=$tempsmoothdz" -flowacc=$prefx".flowacc1" -echo "flowacc=$flowacc" -slope=$prefx".slope1" -echo "slope=$slope" -aspect=$prefx".aspect1" -echo "aspect=$aspect" -pc=$prefx".pc1" -echo "pc=$pc" -tc=$prefx".tc1" -echo "tc=$tc" -meancurv=$prefx".meancurv1" -echo "meancurv=$meancurv" -rate=$prefx".rate1" -echo "rate=$rate" -sflowtopo=$prefx".sflowtopo1" -echo "sflowtopo=$sflowtopo" -qsx=$prefx".qsx1" -echo "qsx=$qsx" -qsy=$prefx".qsy1" -echo "qsy=$qsy" -qsxdx=$prefx".qsx.dx1" -echo "qsxdx=$qsxdx" -qsydy=$prefx".qsy.dy1" -echo "qsydy=$qsydy" -m=$prefx".m1" -echo "m=$m" -n=$prefx".n1" -echo "n=$n" -erdep=$prefx".erosdep1" -echo "erdep=$erdep" -initsoil=$prefx".initsoil" - -echo "" - -new_soil=$prefx"_new_soil1" -new_dem=$prefx"_new_dem1" -initsoil=$prefx"_initsoil" -echo "Initial soil depths calculated will be in $initsoil" -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"_new_bdrk1" -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` - -# we must set the region to the map being used. otherwise r.flow will not work -echo "" -echo "Setting region to $elev" -g.region rast=$elev - -#now lets show before: -echo "" -echo "Original Resolution = $res1" - -#...and after: -res=`eval g.region -p -m | grep "nsres:" | cut -d : -f 2` -echo "" -echo "New Resolution = $res" - - -echo "" -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 "_____________________________________________________________" -# 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 -echo "" -echo "##################################################" -echo "##################################################" -echo "" -echo "ITERATION 1" -echo "" -echo "##################################################" -echo "" -echo "*************************" -echo "step 1 of 8: calculating slope and aspect (if initial aspect not specified)" -echo "*************************" -echo "" - - -r.slope.aspect --q $elev 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" - -r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp - -r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" - -g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" -rm -f /var/tmp/STREAM* - -else - -echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" - -tmpflacc=$prefx".tmpflacc" - -r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc - -r.mapcalc "$flowacc=$tmpflacc*$res" - -g.remove --quiet rast=$tmpflacc - -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.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` - -echo "" -echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " -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)))" - -report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` -report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` - -echo "" -echo "(for diagnostics only) max m = $report1, min m = $report2" - - -r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff, 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 fully 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 "$initsoil=$elev - $initbdrk" - -echo "" -echo "*************************" -echo "step 7 of 8: running band-pass filter" -echo "*************************" -echo "" - -if [ "$GIS_FLAG_y" -eq 1 ]; then - -echo ""echo "You have selected not to smooth your files... Oh Well!" -echo "" - -r.mapcalc "$smoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" - -else - - -r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood -r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" -r.mapcalc "$smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" - -fi - -# create temporary file to code colors for $smoothdz -TMP1=`g.tempfile pid=$$` - -if [ $? -ne 0 ] || [ -z "$TMP1" ]; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -else - - echo "creating temporary file to code colors" - -fi - - -echo "0% 255 000 255" > $TMP1 -echo "-5 255 000 255" >> $TMP1 -echo "-3 red" >> $TMP1 -echo "-1 orange" >> $TMP1 -echo "-0.5 yellow" >> $TMP1 -echo "0 white" >> $TMP1 -echo "0.5 green" >> $TMP1 -echo "1 cyan" >> $TMP1 -echo "3 aqua" >> $TMP1 -echo "5 violet" $TMP1 -echo "100% 104 034 139" >> $TMP1 -echo "end" >> $TMP1 - - -cat $TMP1 | r.colors --q map=$smoothdz color=rules - -echo "" -echo "*************************" -echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" -echo "*************************" -echo "" - -r.mapcalc "$new_dem=$smoothdz + $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" - - -new_bdrk=$initbdrk -r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" - -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))" - -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))" - -#grabsomestats -tmperosion=$prfx"_tmperosion1" -tmpdep=$prfx"_tmpdep1" - -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 - -txtout=$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 "*************************" - - - -echo "" -echo "Raster map $smoothdz shows filtered net erosion/deposition" -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 "" -# echo "Done" -# echo "" -#else -# echo "" -# echo "Cleaning up..." -# g.remove rast=$flowacc,$slope,$aspect,$sflowtopo,$qsx,$qsy,$qsxdx,$qsydy,$erdep,$neighbors -# echo "" -# echo "Done" -#fi - - -#remove the temp files to avoid confusion...\rm -f $TMP1 $TMP1.sort - - -number=$GIS_OPT_number -echo "total number of iterations to be run= $number" -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"_new_dem"$laststep - -echo "The following temporary files will be created:" -echo "" -neighbors=$prefx".neighbors"$step -echo "neighbors=$neighbors" -tempsmoothdz=$prefx".tempsmoothdz"$step -echo "tempsmoothdz=$tempsmoothdz" -temp2smoothdz=$prefx".temp2smoothdz"$step -echo "temp2smoothdz=$temp2smoothdz" -smoothdz=$prefx"_smoothdz"$step -echo "smoothdz=$smoothdz" -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".m"$step -echo "m=$m" -n=$prefx".n"$step -echo "n=$n" -erdep=$prefx".erosdep"$step -echo "erdep=$erdep" -old_bdrk=$prefx"_new_bdrk"$laststep -echo "old_bdrk=$old_bdrk" -old_soil=$prefx"_new_soil"$laststep -echo "old_soil=$old_soil" -echo "" - -new_soil=$prefx"_new_soil"$step -new_dem=$prefx"_new_dem"$step -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"_new_bdrk"$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" - -r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp - -r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" - -g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" -rm -f /var/tmp/STREAM* - -else - -echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" - -tmpflacc=$prefx".tmpflacc" -r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc - -r.mapcalc "$flowacc=$tmpflacc*$res" - -g.remove --quiet rast=$tmpflacc - -fi - - - -echo "" -echo "*************************" -echo "step 3 of 8: calculating basic sediment transport rates" -echo "*************************" -echo "" - - -initbdrk - -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),$m) * exp(sin($slope),$n)" - - -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.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` - - -echo "" -echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " -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 "$sflowtopo=if ($flowacc >= $cutoff, 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 band-pass 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 - -r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood -r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $old_soil, (-1 * $old_soil), $erdep)" -r.mapcalc "$temp2smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" - -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 - - -# create temporary file to code colors for $smoothdz -TMP1=`g.tempfile pid=$$` - -if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -else - echo "creating temporary file to code colors" - -fi - -echo "0% 255 000 255" > $TMP1 -echo "-5 255 000 255" >> $TMP1 -echo "-3 red" >> $TMP1 -echo "-1 orange" >> $TMP1 -echo "-0.5 yellow" >> $TMP1 -echo "0 white" >> $TMP1 -echo "0.5 green" >> $TMP1 -echo "1 cyan" >> $TMP1 -echo "3 aqua" >> $TMP1 -echo "5 violet" $TMP1 -echo "100% 104 034 139" >> $TMP1 -echo "end" >> $TMP1 - - -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" -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" - - -new_bdrk=$old_bdrk -r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" - -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))" - -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))" - - -#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 "Raster map $smoothdz shows filtered net erosion/deposition" -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 - - -# 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 - exit 1 -fi - - -g.mlist type=rast sep=, pattern=$prefx"_smoothdz*" > $TMP2 -liststring=`cat $TMP2` - -echo "Any selected statistics will be performed using the following smoothdz files: $liststring" - -if [ "$GIS_FLAG_c" -eq 1 ]; then - -r.series --q input=$liststring output=$prefx"_cum_erdep" method=sum -fi - -if [ "$GIS_FLAG_m" -eq 1 ]; then - -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 - -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 - - - -# 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 -fi - -g.mlist type=rast sep=, pattern=$prefx"_new_soil*" > $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_soil" method=average -fi - -if [ "$GIS_FLAG_v" -eq 1 ]; then - -r.series --q input=$liststring2 output=$prefx"_sdev_soil" method=stddev -fi - -if [ "$GIS_FLAG_a" -eq 1 ]; then - -r.series --q input=$liststring2 output=$prefx"_max_soil" method=maximum -fi - - -if [ "$GIS_FLAG_u" -eq 1 ]; then - -r.series --q input=$liststring2 output=$prefx"_min_soil" method=minimum -fi -\rm -f $TMP2 $TMP2.sort -\rm -f $TMP3 $TMP3.sort - - -echo "************************" - -if [ "$GIS_FLAG_k" -eq 1 ]; then - -echo "" -echo "Done" -echo "" - -else - -echo "" -echo "Cleaning up..." - -g.mremove -f --q rast=$prefx".neighbors*" -g.mremove -f --q rast=$prefx".smoothdz*" -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".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".m*" -g.mremove -f --q rast=$prefx".n*" - - echo "" - echo "Done" - -fi - -if [ "$GIS_FLAG_n" -eq 1 ]; then - - g.mremove --q rast=$prefx"_smoothdz*" -fi - -if [ "$GIS_FLAG_l" -eq 1 ]; then - - g.mremove --q rast=$prefx"_new_soil*" -fi - -if [ "$GIS_FLAG_z" -eq 1 ]; then -echo "" -echo "Iterations complete, keeping region set to output maps" -echo "" -else -echo "" -echo "Iterations complete, restoring default region settings" -echo "" - -g.region -d -g - -echo "" -fi -echo "###################################################" -echo "###################################################" -echo "___________________________________________________" -echo "" -echo " DONE WITH EVERYHTING" -echo "" -echo "___________________________________________________" - - - - From barton at grass.itc.it Sat Jul 7 00:10:22 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Jul 7 00:10:24 2007 Subject: [grass-addons] r938 - trunk/grassaddons Message-ID: <200707062210.l66MAMGt020732@grass.itc.it> Author: barton Date: 2007-07-07 00:10:14 +0200 (Sat, 07 Jul 2007) New Revision: 938 Removed: trunk/grassaddons/landscape_evol/ Log: Replaced by more general LandDyn From ullah at grass.itc.it Sat Jul 7 00:27:16 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Sat Jul 7 00:27:17 2007 Subject: [grass-addons] r939 - in trunk/grassaddons/LandDyn: . r.landscape_evol Message-ID: <200707062227.l66MRGuZ020788@grass.itc.it> Author: ullah Date: 2007-07-07 00:27:00 +0200 (Sat, 07 Jul 2007) New Revision: 939 Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/ trunk/grassaddons/LandDyn/r.aggregate.stats/ trunk/grassaddons/LandDyn/r.agropast.extensive/ trunk/grassaddons/LandDyn/r.agropast.intensive/ trunk/grassaddons/LandDyn/r.agropast/ trunk/grassaddons/LandDyn/r.catchment/ trunk/grassaddons/LandDyn/r.iterate/ trunk/grassaddons/LandDyn/r.landscape.evol.itr/ trunk/grassaddons/LandDyn/r.landscape.evol/ trunk/grassaddons/LandDyn/r.nompast.area/ trunk/grassaddons/LandDyn/r.nompast.num/ trunk/grassaddons/LandDyn/r.pastoral.simple/ trunk/grassaddons/LandDyn/r.rfactor.iterate/ trunk/grassaddons/LandDyn/r.rfactor/ trunk/grassaddons/LandDyn/r.shift.cult/ trunk/grassaddons/LandDyn/r.soildepth/ Modified: trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol Log: Modified: trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol 2007-07-06 22:10:14 UTC (rev 938) +++ trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol 2007-07-06 22:27:00 UTC (rev 939) @@ -64,6 +64,11 @@ #% guisection: Input #%end #%flag +#% key: e +#% description: -e Keep initial soil depths map +#% guisection: Input +#%end +#%flag #% key: z #% description: -z Keep region zoomed to output maps #% answer: 1 @@ -158,7 +163,7 @@ #% key: nbhood #% type: string #% description: Band-pass filter neighborhood size -#% answer: 3 +#% answer: 7 #% options: 1,3,5,7,9,11,13,15,17,19,21,23,25 #% required : yes #% guisection: Smoothing_Filter @@ -272,54 +277,71 @@ sigma=$GIS_OPT_sigma nbhood=$GIS_OPT_nbhood cutoff=$GIS_OPT_cutoff +number=$GIS_OPT_number +echo "total number of iterations to be run= $number" +echo "" + +if [ $number -eq 1 ] ; then + +num="" + +else + +num="1" + +fi + echo "The following temporary files will be created:" echo "" -neighbors=$prefx".neighbors1" +neighbors=$prefx".neighbors"$num echo "neighbors=$neighbors" -tempsmoothdz=$prefx".tempsmoothdz1" +tempsmoothdz=$prefx".tempsmoothdz"$num echo "tempsmoothdz=$tempsmoothdz" -smoothdz=$prefx"_smoothdz1" +smoothdz=$prefx"_smoothdz"$num echo "smoothdz=$smoothdz" -tempsmoothdz=$prefx".tempsmoothdz1" +tempsmoothdz=$prefx".tempsmoothdz"$num echo "temsmoothpdz=$tempsmoothdz" -flowacc=$prefx".flowacc1" +flowacc=$prefx".flowacc"$num echo "flowacc=$flowacc" -slope=$prefx".slope1" +slope=$prefx".slope"$num echo "slope=$slope" -aspect=$prefx".aspect1" +aspect=$prefx".aspect"$num echo "aspect=$aspect" pc=$prefx".pc1" echo "pc=$pc" tc=$prefx".tc1" echo "tc=$tc" -meancurv=$prefx".meancurv1" +meancurv=$prefx".meancurv"$num echo "meancurv=$meancurv" -rate=$prefx".rate1" +rate=$prefx".rate"$num echo "rate=$rate" -sflowtopo=$prefx".sflowtopo1" +sflowtopo=$prefx".sflowtopo"$num echo "sflowtopo=$sflowtopo" -qsx=$prefx".qsx1" +qsx=$prefx".qsx"$num echo "qsx=$qsx" -qsy=$prefx".qsy1" +qsy=$prefx".qsy"$num echo "qsy=$qsy" -qsxdx=$prefx".qsx.dx1" +qsxdx=$prefx".qsx.dx"$num echo "qsxdx=$qsxdx" -qsydy=$prefx".qsy.dy1" +qsydy=$prefx".qsy.dy"$num echo "qsydy=$qsydy" -m=$prefx".m1" +m=$prefx".m"$num echo "m=$m" -n=$prefx".n1" +n=$prefx".n"$num echo "n=$n" -erdep=$prefx".erosdep1" +erdep=$prefx".erosdep"$num echo "erdep=$erdep" -initsoil=$prefx".initsoil" + + echo "" -new_soil=$prefx"_new_soil1" -new_dem=$prefx"_new_dem1" +new_soil=$prefx"_new_soil"$num +new_dem=$prefx"_new_dem"$num + initsoil=$prefx"_initsoil" -echo "Initial soil depths calculated will be in $initsoil" + + 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" @@ -329,7 +351,7 @@ else -new_bdrk=$prefx"_new_bdrk1" +new_bdrk=$prefx"_new_bdrk"$num echo "The new bedrock elevation map for this iteration will be called $new_bdrk" fi @@ -353,17 +375,31 @@ 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 +echo "" +echo "##################################################" +echo "##################################################" +echo "" + +if [ $number -eq 1 ] ; then + +echo "STARTING SIMULATION" +echo "" +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 "_____________________________________________________________" -# 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 echo "" -echo "##################################################" -echo "##################################################" -echo "" echo "ITERATION 1" + +fi + echo "" echo "##################################################" echo "" @@ -375,6 +411,7 @@ r.slope.aspect --q $elev slope=$slope aspect=$aspect pcurv=$pc tcurv=$tc + echo "" echo "*************************" echo "step 2 of 8: calculating upslope accumulated flow" @@ -405,11 +442,12 @@ echo "Amount of free RAM being allocated for this step: $mem Megabites" -r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp +r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=temp.flowacc tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp -r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" +r.mapcalc "$flowacc=temp.flowacc/$res" -g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" + +g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",temp.flowacc rm -f /var/tmp/STREAM* else @@ -507,8 +545,8 @@ 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=1+($flowacc * (0.3/($maxflow - $minflow)))" +r.mapcalc "$n=1+($flowacc * (0.15/($maxflow - $minflow)))" report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` @@ -581,9 +619,15 @@ fi +#checking to see if we should keep the initial soil depths map + + + + # create temporary file to code colors for $smoothdz TMP1=`g.tempfile pid=$$` + if [ $? -ne 0 ] || [ -z "$TMP1" ]; then echo "ERROR: unable to create temporary file for colors" 1>&2 exit 1 @@ -594,17 +638,17 @@ fi -echo "0% 255 000 255" > $TMP1 -echo "-5 255 000 255" >> $TMP1 -echo "-3 red" >> $TMP1 -echo "-1 orange" >> $TMP1 -echo "-0.5 yellow" >> $TMP1 +echo "0% 104 034 139" > $TMP1 +echo "-5 violet" >> $TMP1 +echo "-3 aqua" >> $TMP1 +echo "-1 cyan" >> $TMP1 +echo "-0.5 green" >> $TMP1 echo "0 white" >> $TMP1 -echo "0.5 green" >> $TMP1 -echo "1 cyan" >> $TMP1 -echo "3 aqua" >> $TMP1 -echo "5 violet" $TMP1 -echo "100% 104 034 139" >> $TMP1 +echo "0.5 yellow" >> $TMP1 +echo "1 orange" >> $TMP1 +echo "3 red" >> $TMP1 +echo "5 255 000 255" $TMP1 +echo "100% 255 000 255" >> $TMP1 echo "end" >> $TMP1 @@ -687,8 +731,18 @@ 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 "Raster map $smoothdz shows filtered net erosion/deposition" echo "" @@ -714,8 +768,7 @@ #remove the temp files to avoid confusion...\rm -f $TMP1 $TMP1.sort -number=$GIS_OPT_number -echo "total number of iterations to be run= $number" + step=1 # now we must go into a loop to get the rest of the dem's @@ -1020,17 +1073,17 @@ fi -echo "0% 255 000 255" > $TMP1 -echo "-5 255 000 255" >> $TMP1 -echo "-3 red" >> $TMP1 -echo "-1 orange" >> $TMP1 -echo "-0.5 yellow" >> $TMP1 +echo "0% 104 034 139" > $TMP1 +echo "-5 violet" >> $TMP1 +echo "-3 aqua" >> $TMP1 +echo "-1 cyan" >> $TMP1 +echo "-0.5 green" >> $TMP1 echo "0 white" >> $TMP1 -echo "0.5 green" >> $TMP1 -echo "1 cyan" >> $TMP1 -echo "3 aqua" >> $TMP1 -echo "5 violet" $TMP1 -echo "100% 104 034 139" >> $TMP1 +echo "0.5 yellow" >> $TMP1 +echo "1 orange" >> $TMP1 +echo "3 red" >> $TMP1 +echo "5 255 000 255" $TMP1 +echo "100% 255 000 255" >> $TMP1 echo "end" >> $TMP1 From ullah at grass.itc.it Sat Jul 7 00:35:07 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Sat Jul 7 00:35:09 2007 Subject: [grass-addons] r940 - in trunk/grassaddons/LandDyn/devs_landcover_scripts: . r.cfactor r.landcover.update r.villages rules Message-ID: <200707062235.l66MZ7Du020881@grass.itc.it> Author: ullah Date: 2007-07-07 00:34:55 +0200 (Sat, 07 Jul 2007) New Revision: 940 Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/ trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_colors.txt trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_reclass_rules.txt Log: new scripts added for landscape dynamics modeling Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor (rev 0) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor 2007-07-06 22:34:55 UTC (rev 940) @@ -0,0 +1,113 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.cfactor +# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University +# PURPOSE: Converts a map of landcover values to a c-factor map based +# on a set of reclass rules +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Converts a map of landcover values to a c-factor map based on a set of reclass rules +#%END + +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: input landcover map (integer values aligned with reclass rules) +#% required : yes +#%END + +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% answer: year1 +#% required : yes +#%END + +#%option +#% key: cfact_rules +#% type: string +#% gisprompt: string +#% description: path to recode rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_recode_rules.txt +#% required : yes +#%END + +#%option +#% key: cfact_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_colors.txt +#% required : yes +#%END + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + + + +#setting up variables for use later on + +inmap=$GIS_OPT_inmap + +prfx=$GIS_OPT_prfx + +cfact_rules=$GIS_OPT_cfact_rules + +cfact_color=$GIS_OPT_cfact_color + + +outcfact=$prfx"cfactor" + +#setting initial conditions of map area + +g.region rast=$inmap + +r.mask --quiet input=$inmap maskcats=* + +#creating c-factor map and setting colors + + cat $cfact_rules | r.recode input=$inmap output=$outcfact + + r.colors map=$outcfact rules=$cfact_color + + + + +echo "" +echo "*************************" +echo " Cleaning up" +echo "*************************" +echo "" + + +g.remove --quiet rast=MASK + + + +echo "" +echo "DONE!" +echo "" +echo "" + Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update (rev 0) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update 2007-07-06 22:34:55 UTC (rev 940) @@ -0,0 +1,174 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.landcover.update +# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University +# PURPOSE: Updates a map of landcover by the amounts specified in an impacts +# map +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: CUpdates a map of landcover by the amounts specified in an impacts map +#%END + +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: input landcover map (values coded 0-max) +#% required : yes +#%END + +#%option +#% key: impacts +#% type: string +#% gisprompt: old,cell,raster +#% description: map of impacts on landcover values +#% required : yes +#%END + +#%option +#% key: max +#% type: string +#% gisprompt: string +#% description: maximum value for landcover maps (number for climax veg) +#% answer: 50 +#% required : yes +#%END + +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% answer: year1 +#% required : yes +#%END + +#%option +#% key: lc_rules +#% type: string +#% gisprompt: string +#% description: path to reclass rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_reclass_rules.txt +#% required : yes +#%END + +#%option +#% key: lc_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_colors.txt +#% required : yes +#%END + +#%flag +#% key: s +#% description: -s Output text file of land-use stats from the simulation (will be named "prefix"_luse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) +#%END + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + + + +#setting up variables for use later on + +inmap=$GIS_OPT_inmap + +impacts=$GIS_OPT_impacts + +prfx=$GIS_OPT_prfx + +max=$GIS_OPT_max + +lc_rules=$GIS_OPT_lc_rules + +lc_color=$GIS_OPT_lc_color + + +txtout=$prfx"luse_stats.txt" + +temp_lc=$prfx"temp_landcover" + +temp_reclass=$prfx"temp_landcover_reclass" + +outlc=$prfx"landcover" + + +#setting initial conditions of map area + +g.region rast=$inmap + +r.mask --quiet input=$inmap maskcats=* + +#updating raw landscape category numbers + +#r.mapcalc "$temp_lc = if ($inmap == $max && isnull($impacts), $max, (if ($inmap < $max && isnull($impacts), ($inmap + 1), ($inmap - $impacts))))" + +r.mapcalc "$temp_lc = if ($inmap == $max && isnull($impacts), $max, (if ($inmap < $max && isnull($impacts), ($inmap + 1), if ($inmap > $max, ($max - $impacts), if ($inmap < 0, 0, ($inmap - $impacts))))))" + +#adding text descriptions to raw landscape categories and setting colors + + cat $lc_rules | r.reclass input=$temp_lc output=$temp_reclass + + r.mapcalc "$outlc = $temp_reclass" + + r.colors map=$outlc rules=$lc_color + + +#checking total area of updated cells + + temparea=`eval r.stats -n -a fs=- input=$impacts | cut -d'-' -f2` + echo "***********************" + echo "Total area of impacted zones = $temparea square meters" + echo "***********************" + +#creating optional output text file of stats + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "Stats for $prfx'_landcover' " > $txtout +echo "" >> $txtout +echo "Total area of impacted zones = $temparea square meters" >> $txtout +echo "" >> $txtout +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$prfx"_landuse1" fs=, nv=* nsteps=255 >> $txtout + +fi + + + +echo "" +echo "*************************" +echo " Cleaning up" +echo "*************************" +echo "" + + +g.remove --quiet rast=MASK,$temp_reclass,$temp_lc + + + +echo "" +echo "DONE!" +echo "" +echo "" + Property changes on: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages (rev 0) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages 2007-07-06 22:34:55 UTC (rev 940) @@ -0,0 +1,127 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.villages +# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University +# PURPOSE: patches a map of village locations on a landcover landcover map +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: patches a map of village locations on a landcover landcover map +#%END + +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: input landcover map (integer values aligned with reclass rules) +#% required : yes +#%END + +#%option +#% key: villages +#% type: string +#% gisprompt: old,cell,raster +#% description: input map of village locations (coded as all one integer value) +#% required : yes +#%END + +#%option +#% key: val +#% type: integer +#% answer: 40 +#% description: value for villages to be coded onto output map +#% required : yes +#%END + +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for output map (will be put before 'final_landcover') +#% answer: year1 +#% required : yes +#%END + + + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + + + +#setting up variables for use later on + +inmap=$GIS_OPT_inmap + +villages=$GIS_OPT_villages + +val=$GIS_OPT_val + +prfx=$GIS_OPT_prfx + +outmap=$prfx"final_landcover" + + +temp_villages=$prfx"_temporary_village_reclass" + + +#setting initial conditions of map area + +g.region rast=$inmap + +r.mask --quiet input=$inmap maskcats=* + +#discovering the value of the input villages map + +inval=`eval r.cats map=$villages` + +#setting up color and reclass rules + +colors="$val red" + +reclass="$inval = $val Village" + +#doing reclass and recolor + + cat $reclass | r.reclass input=$villages output=$temp_villages + + cat $colors | r.colors map=$temp_villages color=rules + +#patching maps together + +r.patch -q input=$temp_villages,$inmap output=$outmap + + +echo "" +echo "*************************" +echo " Cleaning up" +echo "*************************" +echo "" + + +g.remove --quiet rast=MASK,$temp_villages + + + +echo "" +echo "DONE!" +echo "" +echo "" + Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt (rev 0) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt 2007-07-06 22:34:55 UTC (rev 940) @@ -0,0 +1,6 @@ +0.8 grey +0.5 red +0.3 orange +0.1 brown +0.08 yellow +0.05 green Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt (rev 0) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt 2007-07-06 22:34:55 UTC (rev 940) @@ -0,0 +1,7 @@ +0:2:0.8:0.6 +3:7:0.6:0.3 +8:12:0.3:0.1 +13:18:0.1:0.08 +19:37:0.08:0.06 +38:50:0.06:0.05 +end Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_colors.txt =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_colors.txt (rev 0) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_colors.txt 2007-07-06 22:34:55 UTC (rev 940) @@ -0,0 +1,6 @@ +0 grey +10 red +20 orange +30 brown +40 yellow +50 green Added: trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_reclass_rules.txt =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_reclass_rules.txt (rev 0) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/luse_reclass_rules.txt 2007-07-06 22:34:55 UTC (rev 940) @@ -0,0 +1,52 @@ +0 = 0 bare land +1 = 1 very sparse grassland +2 = 2 sparse grassland +3 = 3 moderately sparse grassland +4 = 4 moderate grassland +5 = 5 grassland +6 = 6 grassland with very sparse shrubs +7 = 7 grass and sparse shrubs +8 = 8 grass and moderately sparse shrubs +9 = 9 grass and shrubs +10 = 10 shrubs and grass +11 = 11 shrubs and moderately sparse grass +12 = 12 shrubs and sparse grass +13 = 13 shrubs and very sparse grass +14 = 14 shrubs +15 = 15 shrubs and developing maquis +16 = 16 developing maquis +17 = 17 developing maquis +18 = 18 maquis +19 = 19 maquis +20 = 20 moderately dense maquis +21 = 21 moderately dense maquis +22 = 22 dense maquis +23 = 23 dense maquis +24 = 24 dense maquis and sparse small trees +25 = 25 dense maquis and small trees +26 = 26 moderately dense maquis and small trees +27 = 27 maquis and small trees +28 = 28 sparse young woodland and maquis +29 = 29 moderately sparse young woodland and maquis +30 = 30 young woodland and maquis +31 = 31 young open woodland and sparse maquis +32 = 32 mostly young open woodland and very sparse maquis +33 = 33 mostly young open woodland +34 = 34 young open woodland +35 = 35 young open woodland +36 = 36 young open woodland +37 = 37 moderate open woodland +38 = 38 moderate open woodland +39 = 39 moderate open woodland +40 = 40 maturing and moderate open woodland +41 = 41 maturing and moderate open woodland +42 = 42 maturing and moderate open woodland +43 = 43 maturing open woodland +44 = 44 maturing open woodland +45 = 45 maturing open woodland +46 = 46 mostly matured open woodland +47 = 47 mostly matured open woodland +48 = 48 mostly matured open woodland +49 = 49 mostly matured open woodland +50 = 50 fully matured woodland +end \ No newline at end of file From ullah at grass.itc.it Sat Jul 7 00:38:40 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Sat Jul 7 00:38:43 2007 Subject: [grass-addons] r941 - in trunk/grassaddons/LandDyn: r.aggregate.stats r.agropast r.agropast.extensive r.agropast.intensive r.catchment r.iterate r.landscape.evol r.landscape.evol.itr r.landscape_evol r.nompast.area r.nompast.num r.pastoral.simple r.rfactor r.rfactor.iterate r.shift.cult r.soildepth Message-ID: <200707062238.l66McebH020902@grass.itc.it> Author: ullah Date: 2007-07-07 00:37:37 +0200 (Sat, 07 Jul 2007) New Revision: 941 Added: trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive trunk/grassaddons/LandDyn/r.agropast/r.agropast trunk/grassaddons/LandDyn/r.catchment/r.catchment trunk/grassaddons/LandDyn/r.iterate/r.iterate trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol trunk/grassaddons/LandDyn/r.nompast.area/r.nompast.area trunk/grassaddons/LandDyn/r.nompast.num/r.nompast.num trunk/grassaddons/LandDyn/r.pastoral.simple/r.pastoral.simple trunk/grassaddons/LandDyn/r.rfactor.iterate/r.rfactor.iterate trunk/grassaddons/LandDyn/r.rfactor/r.rfactor trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult trunk/grassaddons/LandDyn/r.soildepth/r.soildepth Removed: trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol Log: more new scripts added for landscape dynamics modeling Added: trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats =================================================================== --- trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats (rev 0) +++ trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,114 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.aggregate.stats +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Aggregates a series of maps (based on a shared prefix) using r.series, then calculates summary +# statistics for the aggragate map. +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Aggregates a series of maps (based on a shared prefix) using r.series, then calculates summary statistics for the aggragate map. + +#%END +#%option +#% key: prefix +#% type: string +#% gisprompt: old,cell,raster +#% description: prefix of series +#% required : yes +#%END + +#%option +#% key: method +#% type: string +#% answer: average +#% options: average,count,median,mode,minimum,min_raster,maximum,max_raster,stddev,sum,variance,diversity,slope,offset,quart1,quart3,perc90 +#% required : yes +#% description: method of aggregating map series (see r.series help for option descriptions) +#% required : yes +#%END + +#%flag +#% key: s +#% description: -s Only calculate sum of aggregate map +#%END + +#%flag +#% key: k +#% description: -k Keep aggregate map (will be called "'prefix'_'method'") +#%END + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + + + prefix=$GIS_OPT_prefix + method=$GIS_OPT_method + string=$prefix"_temp_list.txt" + +g.mlist --quiet type=rast sep=, pattern=$prefix"*" > $string + + + tempmap=$prefix"_temp_aggregate" + +r.series input=`cat $string` output=$tempmap method=$method + +if [ "$GIS_FLAG_s" -eq 1 ]; then + + number=`eval r.sum --quiet rast=$tempmap | cut -d'=' -f2` + +echo "" +echo "" +echo "The sum of the $method aggregate map is: $number" +echo "" +echo "" + + +else + +echo "" +echo "" +echo "Sumary statistics for the $method aggregate map:" +echo "" +r.univar -e map=$tempmap percentile=90 --quiet +echo "" +echo "" + +fi + + + +if [ "$GIS_FLAG_k" -eq 1 ]; then + + output=$prefix"_"$method + +g.rename --quiet rast=$tempmap,$output + +echo "Aggregate map '$output' kept" + +else + +g.remove --quiet rast=$tempmap + +fi + +rm -f $string + + Property changes on: trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.agropast/r.agropast =================================================================== --- trunk/grassaddons/LandDyn/r.agropast/r.agropast (rev 0) +++ trunk/grassaddons/LandDyn/r.agropast/r.agropast 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,814 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.agropast +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: simulates the landuse activities of agropastoralists around sites (vector +# points) using cost distances. Module requires r.walk. +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: simulates the landuse activities of agropastoralists around sites (vector points) using cost distances. Module requires r.walk. +#%END +#%option +#% key: elev +#% type: string +#% gisprompt: old,cell,raster +#% description: Input elevation map (DEM) +#% required : yes +#%END +#%option +#% key: vect +#% type: string +#% gisprompt: old,vector,vector +#% description: Name of input vector site points map +#% required : yes +#%END +#%option +#% key: frict +#% type: string +#% gisprompt: old,cell,raster +#% description: Optional map of friction costs. If no map selected, default friction=1 making output reflect time costs only +#% answer: +#% required : no +#%END +#%option +#% key: a +#% type: double +#% description: Coefficients for walking energy formula parameters a,b,c,d +#% answer: 0.72 +#% required : no +#%END +#%option +#% key: b +#% type: double +#% description: +#% answer: 6.0 +#% required : no +#%END +#%option +#% key: c +#% type: double +#% description: +#% answer: 1.9998 +#% required : no +#%END +#%option +#% key: d +#% type: double +#% description: +#% answer: -1.9998 +#% required : no +#%END +#%option +#% key: lambda +#% type: double +#% description: Lambda value for cost distance calculation +#% answer: 0 +#% required : yes +#%END +#%option +#% key: slope_factor +#% type: double +#% description: Slope factor determines travel energy cost per height step +#% answer: -0.2125 +#% required : no +#%END + +#%option +#% key: step_size +#% type: integer +#% description: Integer length of the catchment size step. (smaller values will yield more accurate results, but will take significantly longer. ie. there will be more iteration steps) +#% answer: 10 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% answer: agropast +#% required : yes +#%END + +#%option +#% key: inituse +#% type: string +#% gisprompt: old,cell,raster +#% description: Optional initial landscape (Coded 0-21. If no map specified, an initial landscape of value 21 (mature woodland) is used) +#% required : no +#% guisection: model_parameters +#%END +#%option +#% key: fbmas +#% type: integer +#% description: Average mature woodland edible biomass (kg/ha/year) +#% answer: 350 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: sbmas +#% type: integer +#% description: Average shrubland edible biomass (kg/ha/year) +#% answer: 200 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: gbmas +#% type: integer +#% description: Average grassland edible biomass (kg/ha/year) +#% answer: 100 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: gweight +#% type: integer +#% description: Average weight of forage one goat for one year (kg) +#% answer: 584 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: sweight +#% type: integer +#% description: Average weight of forage for one sheep for year (kg) +#% answer: 894 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: number +#% type: integer +#% description: Number of herd animals you wish to have graze +#% answer: 30 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: gratio +#% type: integer +#% description: ratio of goats to sheep (ie. enter 1 for 1 goat to n sheep) +#% answer: 1 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: sratio +#% type: integer +#% description: ratio of sheep to goats (ie. enter 1 for n goats to 1 sheep) +#% answer: 1 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: effect +#% type: integer +#% description: Intensity of grazing (amount by which landcover is decreased after grazing) +#% answer: 1 +#% options: 1,2,3,4,5 +#% required : yes +#% guisection: model_parameters +#%END +#%option +#% key: dist +#% type: integer +#% description: Optional straight-line maximum distance for one-way flock movements away from the starting point (integer meters) (simulation will end when catchment exceeds this value in all four cardinal directions) +#% required : no +#% guisection: model_parameters +#%END +#%option +#% key: loop +#% type: integer +#% description: number of iterations ("years") to run +#% answer: 20 +#% required : yes +#% guisection: model_parameters +#%END + +#%flag +#% key: k +#% description: -k Use knight's move for calculating cost surface (slower but more accurate) +#%END +#%flag +#% key: c +#% description: -c Keep output cost surface +#%END +#%flag +#% key: f +#% description: -f Create C-factor maps (for RUSLE and USPED) from output landcover maps as well +#%END +#%flag +#% key: s +#% description: -s Output stats to comma delimited text files (two files will be created in the home directory with the prefix entered below. They will be over written if you run the module again with the same prefix) +#%END +#%flag +#% key: t +#% description: -t Keep timer map which is coded 0-21 for the various landcover types. Will only reflect cumulative landuse for entire run. Useful for input into another land-use simulation. +#%END + + + +if [ -z "$GISBASE" ] ; then + g.message -e message="You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +#these are the variables for the cost surface model needed by r.walk +prfx=$GIS_OPT_prfx +elev=$GIS_OPT_elev +vect=$GIS_OPT_vect +input_frict=$GIS_OPT_frict +lmbda=$GIS_OPT_lambda +slpfct=$GIS_OPT_slope_factor +a=$GIS_OPT_a +b=$GIS_OPT_b +c=$GIS_OPT_c +d=$GIS_OPT_d +sigma=$GIS_OPT_sigma +cost=$prfx"_cost_surface" +frict=$prfx"_friction_in" + +#these are variables needed for our purpose +inituse=$GIS_OPT_inituse +dist=$GIS_OPT_dist + +effect=$GIS_OPT_effect +stepsize=$GIS_OPT_step_size + +gweight=$GIS_OPT_gweight +sweight=$GIS_OPT_sweight +gratio=$GIS_OPT_gratio +sratio=$GIS_OPT_sratio + +number=$GIS_OPT_number +loop=$GIS_OPT_loop + +txtout=$prfx"_landcover_stats.txt" +txtout2=$prfx"_landuse_stats.txt" + + +g.region -g rast=$elev + +TMP5=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then + g.message -e message="ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + +TMP2=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then + g.message -e message="ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + +TMP3=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then + g.message -e message="ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + g.message -e message="ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + +echo "" +echo "*************************" +echo "step 1 : Calculating cost surface" +echo "*************************" +echo "" +echo "sigma=$sigma" +echo "a,b,c,d=$a,$b,$c,$d" +echo "slope_factor=$slpfct" +echo "lambda=$lmbda" + +if [ -n "$GIS_OPT_frict" ]; then + +r.mapcalc "$frict=$input_frict" + +echo "Calculating costs using input friction map" + +else + + +r.mapcalc "$frict=if(isnull($elev), null(), 1)" + +echo "Calculating for time costs only" + +fi + + +if [ "$GIS_FLAG_k" -eq 1 ]; then + +echo "Using Knight's move" + +r.walk --q elevation=$elev friction=$frict output=$cost start_points=$vect lambda=$lmbda percent_memory=100 nseg=4 walk_coeff=$a,$b,$c,$d slope_factor=$slpfct -k + +else + +r.walk --q elevation=$elev friction=$frict output=$cost start_points=$vect lambda=$lmbda percent_memory=100 nseg=4 walk_coeff=$a,$b,$c,$d slope_factor=$slpfct + +fi + +if [ -n "$GIS_OPT_frict" ]; then + +echo "" + +else + +echo "" +g.remove --q rast=$frict + +fi + + + +echo "" +echo "*************************" +echo "step 2: Modeling agro-pastoral land-use over $loop years. This will start a loop and may take some time. Please do not interrupt the process until it has finished" +echo "*************************" +echo "" +echo "iteration step size=$stepsize" +echo "" + +fbmas=$GIS_OPT_fbmas +sbmas=$GIS_OPT_sbmas +gbmas=$GIS_OPT_gbmas + +#below we are setting up our succession sequence for a mediterranean environment... The absolute richness of the environment is controlled by the "biomass" input values for the three main stages of floristic growth (grassland, shrubland, and woodland), the values of which can be found in the ecological or rangeland science literature for specific mediterranean landscapes. All other stages are interpolated between the main three via linear regression. The number of main stages of a twenty year succession will need to be modified for other environments (and perhaps the twenty year time-limit should be expanded or contracted as well), as opposed to just changing the starting biomass values if one really wishes to model accurate succession in a non-mediterranean environment +: $(( a = ( $gbmas / 3 ) )) +: $(( b = ( 2 * ( $gbmas / 3 ) ) )) +: $(( c = ( 3 * ( $gbmas / 3 ) ) )) +d=$gbmas +: $(( e = ( $gbmas + ( ( $sbmas - $gbmas ) / 5 ) ) )) +: $(( f = ( $gbmas + ( 2 * ( ( $sbmas -$gbmas ) / 5 ) ) ) )) +: $(( g = ( $gbmas + ( 3 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +: $(( h = ( $gbmas + ( 4 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +: $(( i = ( $gbmas + ( 5 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +j=$sbmas +: $(( k = ( $sbmas + ( ( $fbmas - $sbmas ) / 11 ) ) )) +: $(( l = ( $sbmas + (2 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( m = ( $sbmas + (3 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( n = ( $sbmas + (4 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( o = ( $sbmas + (5 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( p = ( $sbmas + (6 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( q = ( $sbmas + (7 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( r = ( $sbmas + (8 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( s = ( $sbmas + (9 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( t = ( $sbmas + (10 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +u=$fbmas + + +# now we take our biomass numbers calculated above and shove them into a temp file that we will use to reclass our timer maps into landcover maps later on +echo "0 = 0 badly overgrazed" > $TMP3 +echo "1 = $a overgrazed" >> $TMP3 +echo "2 = $b sparse grassland" >> $TMP3 +echo "3 = $c moderate grassland" >> $TMP3 +echo "4 = $d grassland" >> $TMP3 +echo "5 = $e grass and sparse shrubs" >> $TMP3 +echo "6 = $f grass and shrubs" >> $TMP3 +echo "7 = $g mainly shrubs" >> $TMP3 +echo "8 = $h developing maquis" >> $TMP3 +echo "9 = $i moderate maquis" >> $TMP3 +echo "10 = $j maquis" >> $TMP3 +echo "11 = $k moderately dense maquis" >> $TMP3 +echo "12 = $l dense maquis" >> $TMP3 +echo "13 = $m maquis and small trees" >> $TMP3 +echo "14 = $n young woodland and maquis" >> $TMP3 +echo "15 = $o mostly young open woodland" >> $TMP3 +echo "16 = $p young open woodland" >> $TMP3 +echo "17 = $q moderate open woodland" >> $TMP3 +echo "18 = $r maturing and moderate open woodland" >> $TMP3 +echo "19 = $s maturing open woodland" >> $TMP3 +echo "20 = $t mostly matured open woodland" >> $TMP3 +echo "21 = $u fully matured woodland" >> $TMP3 +echo "end" >> $TMP3 + + +# this creates a tempfile with color values for the output landcover maps +echo "0 grey" > $TMP2 +echo "$gbmas brown" >> $TMP2 +echo "$sbmas yellow" >> $TMP2 +echo "$fbmas green" >> $TMP2 +echo "end" >> $TMP2 + + +# this creates a tempfile to recode our timer maps into c-factor maps later on +echo "0:1:0.5:0.5" > $TMP4 +echo "2:5:0.10:0.10" >> $TMP4 +echo "6:9:0.15:0.15" >> $TMP4 +echo "10:13:0.18:0.18" >> $TMP4 +echo "13:16:0.08:0.08" >> $TMP4 +echo "17:20:0.06:0.06" >> $TMP4 +echo "21:21:0.05:0.05" >> $TMP4 +echo "end" >> $TMP4 + +# this creates a tempfile to color our c-factor maps later on + +echo "0.5 grey" > $TMP5 +echo "0.6 grey" >> $TMP5 +echo "0.19 brown" >> $TMP5 +echo "0.17 brown" >> $TMP5 +echo "0.10 yellow" >> $TMP5 +echo "0.05 green" >> $TMP5 +echo "end" >> $TMP5 + +timer=$prfx"_timer" +#creating initial conditions map: +r.mapcalc "$timer=if(isnull ($elev),null(),21)" + +#setting up distance info to be used with optional max distance cutoff + +: $(( prof_dist = ( $dist - 10 ) )) + +easting=`eval v.info --q map=$vect layer=1 | grep E: | cut -d":" -f2 | cut -c"2-7"` +northing=`eval v.info --q map=$vect layer=1 | grep N: | cut -d":" -f2 | cut -c"2-8" +` + + +#here we determine the max cost on the map to keep our loops from running infinately +max=`eval r.info -r map=$cost | grep "max=" | cut -d"=" -f2 | cut -d'.' -f1` +echo "" +echo "max travel cost across the landscape from originating point = $max" + +#here we determine the average amount of forage consumed by one animal in our herd as determined by our herd structure and herd animal ecology +: $(( efkg = ( ( ($sratio * $sweight) + ( $gratio * $gweight) ) / 2 ) )) + + +#we need one loop for the first year to get things going before we start the nested loop routine to do the rest of the years +echo "" +echo "Model year 1" +echo "" +step=0 #set up for loop + +while [ "$step" -le "$max" ] +do + + + step=$(($step+$stepsize)) #controlling loop + + tmplanduse="temp_use_1" + cost_reclass="temp_class_1" + tmpbiomas="temp_mass_1" + +lastarea=$temparea + + echo "0 thru $step = $effect" | r.reclass --q input=$cost output=$cost_reclass --o + +#creating a test landcover map from reclassed cost surface map + r.mapcalc "$tmplanduse=if(isnull($cost_reclass), null(), $timer)" + + cat $TMP3 | r.reclass --q --o input=$tmplanduse output=$tmpbiomas + + tempbmas=`eval r.sum --q rast=$tmpbiomas | cut -d'.' -f1` + + temparea=`eval r.stats -n -a fs=- input=$cost_reclass | cut -d'-' -f2 | cut -d'.' -f1` + + +#now we run through some equations to discover the affects of this year's simulation on our landscape and our herd population + + +: $(( bmas = ( ( ( $temparea / 100000000 ) * $tempbmas ) / 34 ) )) +# in above equation, .34 is an "efficiency factor" that is used to modify the total standing biomass to consumable biomass for mixed browse/graze rangelands (averaged from the values for each of those types), and is derived from field sudies done by rangeland scientists (because we can't use decimles in BASH math, I divide by 34 instead of multiplying by .34) + +#here we detrermine exactly whats available for our herd to forage based on the intensity of their grazing in each pixel +: $(( ebmas = ($bmas / ( 5 + ( $effect + ( 9 / 4 ) ) ) ) )) + +#here we find out exactly how many herd animals can be supported given the above conditions +: $(( num = ( $ebmas / $efkg ) )) + + +echo "current integer area = $temparea sq m, with $bmas kg of available forage, of which $ebmas kg can be consumed and which will support $num herd animals " + +#-o "$temparea" -eq "$lastarea" + if [ "$num" -ge "$number" ] + then + break # Skip entire rest of loop. + fi + + +done + +tempfirst="temp_1_"$prfx +firstyear=$prfx"_landcover_1" + +if [ -n "$GIS_OPT_inituse" ]; then + +r.mapcalc "$timer=if(isnull($tmplanduse) && $inituse < 21, ($inituse + 1), if(isnull($tmplanduse), 21, if ($inituse < $effect, 0, ($inituse - $effect) ) ) )" + +else + +r.mapcalc "$timer=if(isnull($tmplanduse), 21, 21 - $effect)" + +fi + +cat $TMP3 | r.reclass --q --o input=$timer output=$tempfirst + +r.mapcalc "$firstyear=$tempfirst" + +cat $TMP2 | r.colors --q map=$firstyear color=rules + +if [ "$GIS_FLAG_f" -eq 1 ]; then + + outcfactor=$prfx"_cfactor_1" + + cat $TMP4 | r.recode --q input=$timer output=$outcfactor + + cat $TMP5 | r.colors --q map=$outcfactor color=rules + +fi + +#below is output for text files of stats from this model run + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "General landcover stats for $loop years of grazing $num herd animals on the landscape in $size meter square patches" > $txtout +echo "" >> $txtout +echo "Year 1:" >> $txtout +echo "" >> $txtout +echo "Average biomass production (kg/ha/year),Landcover description,Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$firstyear fs=, nv=* nsteps=255 >> $txtout + +echo "Landuse stats for $loop years of grazing a target herd size of $number herd animals on the landscape with a $gratio to $sratio goat/sheep ratio where goats need $gweight kg/year of fodder and sheep need $sweight kg/year of fodder with an average of $efkg kg/year per herd animal. " > $txtout2 +echo "" >> $txtout2 +echo "Year,Total area grazed (sq. m),Total available fodder,Total fodder actually grazed,Actual number of herd animals,Difference from last year's grazing extent (sq m)" >> $txtout2 +echo "" >> $txtout2 +echo "1,$temparea,$bmas,$ebmas,$num,0" >> $txtout2 +fi + +#Clean up all the temp maps created above +echo "" +g.mremove -f --q rast="temp_*" + +echo "" +echo "__________________________________________________________________" +echo -n "Final area used this year in the pastoral catchment = $temparea which produced $ebmas kg's of consumable forage that supported $num herd animals" +echo "__________________________________________________________________" +echo "" + +year=2 #set up for outer loop + + +while [ "$year" -le "$loop" ] +do + echo "" + echo "Model Year $year" + echo "" + lastyear=$(($year-1)) #control for some comparisons with output from last iteration + lastarea=$temparea + +step=0 #setup for inner loop + +# Here is the inner loop to calculate the size of the catchment for this year in the outer loop +while [ "$step" -le "$max" ] +do + + step=$(($step+$stepsize)) #controlling loop + + tmplanduse="temp_use_"$year + cost_reclass="temp_class_"$year + tmpbiomas="temp_mass_"$year + + + + echo "0 thru $step = $effect" | r.reclass --q input=$cost output=$cost_reclass --o + +#creating a test landcover map from reclassed cost surface map + r.mapcalc "$tmplanduse=if($cost_reclass == $effect, $timer, null())" + + cat $TMP3 | r.reclass --q --o input=$tmplanduse output=$tmpbiomas + + tempbmas=`eval r.sum --q rast=$tmpbiomas | cut -d'.' -f1` + + temparea=`eval r.stats -n -a fs=- input=$cost_reclass | cut -d'-' -f2 | cut -d'.' -f1` + + +#now we run through some equations to discover the affects of this year's simulation on our landscape and our herd population + + +: $(( bmas = ( ( ( $temparea / 100000000 ) * $tempbmas ) / 34 ) )) +# in above equation, .34 is an "efficiency factor" that is used to modify the total standing biomass to consumable biomass for mixed browse/graze rangelands (averaged from the values for each of those types), and is derived from field sudies done by rangeland scientists (because we can't use decimles in BASH math, I divide by 34 instead of multiplying by .34) + +#here we detrermine exactly whats available for our herd to forage based on the intensity of their grazing in each pixel +: $(( ebmas = ($bmas / ( 5 + ( $effect + ( 9 / 4 ) ) ) ) )) + +#here we find out exactly how many herd animals can be supported given the above conditions +: $(( num = ( $ebmas / $efkg ) )) + +echo "current integer area = $temparea sq m, with $bmas kg of available forage, of which $ebmas kg can be consumed and which will support $num herd animals " + +#-o "$temparea" -eq "$lastarea" + if [ "$num" -ge "$number" ] + then + break # Skip entire rest of loop. + fi + + +done + +: $(( dif = ($temparea - $lastarea) )) + +tempyear="temp_"$year"_"$prfx +thisyear=$prfx"_landcover_"$year +lastluse="temp_lastyear" + +r.mapcalc "$lastluse=$timer" + +#here is the mapcalc statement we are using to control damage by grazing and yearly regeneration of ungrazed areas +r.mapcalc "$timer=if(isnull($tmplanduse) && $lastluse < 21, ($lastluse + 1), if(isnull($tmplanduse), 21, if ($lastluse < $effect, 0, ($lastluse - $effect) ) ) )" + +cat $TMP3 | r.reclass --q --o input=$timer output=$tempyear + +r.mapcalc "$thisyear=$tempyear" + +cat $TMP2 | r.colors --q map=$thisyear color=rules + +if [ "$GIS_FLAG_f" -eq 1 ]; then + + outcfactor=$prfx"_cfactor_"$year + + cat $TMP4 | r.recode --q input=$timer output=$outcfactor + + cat $TMP5 | r.colors --q map=$outcfactor color=rules + +fi + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "Year $year:" >> $txtout +echo "" >> $txtout +echo "Average biomass production (kg/ha/year),Landcover description,Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$thisyear fs=, nv=* nsteps=255 >> $txtout + +#echo "Year,Total area grazed (sq. m),Total available fodder,Total fodder actually grazed,Actual number of herd animals,Difference from last year's grazing extent (sq m)" >> $txtout2 +#echo "" >> $txtout2 +echo "$year,$temparea,$bmas,$ebmas,$num,$dif" >> $txtout2 +fi + +#Clean up all temp maps +echo "" +g.mremove -f --q rast="temp_*" + + +if [ "$num" -lt "$number" ]; then + +echo "************************************************************************" +echo "" +echo "Herd size not supported by total use of the provided landscape!!!!!!" +echo "Ending simulation with total herd size of $num herd animals at year $step" +echo "Try again with lower number of herd animals" + + +if [ "$GIS_FLAG_s" -eq 1 ]; then + echo "" >> $txtout + echo "Year $step: herd number not supported! Ending simulation" >> $txtout + echo "" >> $txtout2 + echo "Herd number not supported by Year $step! Ending simulation" >> $txtout2 +fi + +break + +fi + +#Discovering if forest still exists at the four points in each of the cardinal directions that are "max distance" away from the originating point (site) +eastpoint=`eval r.transect --q map=$thisyear line=$easting,$northing,0,$dist | grep $prof_dist | cut -d" " -f2` + +southpoint=`eval r.transect --q map=$thisyear line=$easting,$northing,90,$dist | grep $prof_dist | cut -d" " -f2` + +westpoint=`eval r.transect --q map=$thisyear line=$easting,$northing,180,$dist | grep $prof_dist | cut -d" " -f2` + +northpoint=`eval r.transect --q map=$thisyear line=$easting,$northing,270,$dist | grep $prof_dist | cut -d" " -f2` + +#if forest no longer exists ineach of the four points, then the grazing catchment has exceeded the size limit and we will break out of the loop and end the simulation +if [ "$eastpoint" -ne "$fbmas" -a "$southpoint" -ne "$fbmas" -a "$westpoint" -ne "$fbmas" -a "$northpoint" -ne "$fbmas" ]; then + + +echo "************************************************************************" +echo "" +echo "Maximum (straight line) grazing distance reached in each of the four cardinal directions!!!!!!" +echo "Ending simulation with total herd size of $num herd animals at year $step" + +if [ "$GIS_FLAG_s" -eq 1 ]; then + echo "" >> $txtout + echo "Year $step: Maximum (straight line) grazing distance reached in each of the four cardinal directions! Ending simulation" >> $txtout + echo "" >> $txtout2 + echo "Maximum (straight line) grazing distance reached in each of the four cardinal directions by Year $step! Ending simulation" >> $txtout2 + +fi + +break + +fi + + +echo "" +echo "__________________________________________________________________" +echo -n "Final area used this year in the pastoral catchment = $temparea which produced $ebmas kg's of consumable forage that supported $num herd animals" +echo "__________________________________________________________________" +echo "" + + + year=$(($year+1)) #controlling outer loop + +done + + + +if [ "$GIS_FLAG_c" -eq 1 -a "$GIS_FLAG_t" -eq 0 ]; then + + +echo "" +echo "Cleaning up..." +echo "" + +g.remove --q rast=$timer + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort + +echo "" +echo "DONE!" +echo "" +echo "cost surface kept:" +echo "" +echo "cost surface = $cost" +echo "" + + +elif [ "$GIS_FLAG_c" -eq 1 -a "$GIS_FLAG_t" -eq 1 ]; then + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort + +echo "" +echo "DONE!" +echo "" +echo "cost surface and timer map kept:" +echo "" +echo "cost surface = $cost" +echo "timer = $timer" +echo "" + +elif [ "$GIS_FLAG_c" -eq 0 -a "$GIS_FLAG_t" -eq 1 ]; then + +echo "" +echo "Cleaning up..." +echo "" + +g.remove --q rast=$cost + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort + +echo "" +echo "DONE!" +echo "" +echo "timer map kept:" +echo "" +echo "timer = $timer" +echo "" + +else + +echo "" +echo "Cleaning up..." +echo "" + +g.remove --q rast=$cost,$timer + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort + +echo "" +echo "DONE!" +echo "" + +fi + + Property changes on: trunk/grassaddons/LandDyn/r.agropast/r.agropast ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive =================================================================== --- trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive (rev 0) +++ trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,709 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.agropast.extensive +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a series of iterative landuse maps from a pastoral catchment and an +# extensive (swiddening) agricultural catchment (both need to be created by +# r.catchment), and outputs c factor as well +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a series of iterative landuse maps from a pastoral catchment and an extensive (swiddening) agricultural catchment (both need to be created by r.catchment), and outputs c factor as well. +#%END + +#%option +#% key: inmapa +#% type: string +#% gisprompt: old,cell,raster +#% description: Input extensive agricultural catchment map (will be modeled as swidden ag, from r.catchment or r.buffer) +#% required : yes +#%END +#%option +#% key: randa +#% type: integer +#% description: percent of area to be fields (to be used in r.random) +#% answer: 20 +#% required : yes +#%END +#%option +#% key: sizea +#% type: integer +#% description: size of fields (set as resolution in g.region) +#% answer: 45 +#% required : yes +#%END +#%option +#% key: inmapg +#% type: string +#% gisprompt: old,cell,raster +#% description: Input grazing catchment map (from r.catchment or r.buffer) +#% required : yes +#%END +#%option +#% key: randg +#% type: integer +#% description: percent of area to be grazed in any year (to be used in r.random) +#% answer: 50 +#% required : yes +#%END +#%option +#% key: sizeg +#% type: integer +#% description: size of grazing patches (set as resolution in g.region) +#% answer: 15 +#% required : yes +#%END +#%option +#% key: effect +#% type: integer +#% description: Intensity of grazing (amount by which landcover is decreased after grazing) +#% answer: 1 +#% options: 1,2,3,4,5 +#% required : yes +#%END +#%option +#% key: loop +#% type: integer +#% description: number of iterations ("years") to run +#% answer: 50 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% required : yes +#%END +#%flag +#% key: l +#% description: -l Suppress output of C factor map (output landuse map only) +#%END +#%flag +#% key: g +#% description: -g Output maps of random grazing patches and of random fields at each iteration as well +#%END +#%flag +#% key: s +#% description: -s Output text file of pastoral land-use stats from the simulation (will be named "prefix"_pastoraluse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) +#% answer: 1 +#%END +#%flag +#% key: m +#% description: -m Output text file of agricultural land-use stats (same deal as above, will be called "prefix"_aguse_stats.txt +#% answer: 1 +#%END +#%flag +#% key: p +#% description: -p Output text file of combined agricultural and pastoral land-use stats (same deal as above, will be called "prefix"_ag_and_past_use_stats.txt +#% answer: 1 +#%END + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +inmapa=$GIS_OPT_inmapa +randa=$GIS_OPT_randa +sizea=$GIS_OPT_sizea +inmapg=$GIS_OPT_inmapg +randg=$GIS_OPT_randg +sizeg=$GIS_OPT_sizeg + + +loop=$GIS_OPT_loop +effect=$GIS_OPT_effect +prfx=$GIS_OPT_prfx +timer=$prfx".timer1" +txtout=$prfx"_ag_use_stats.txt" +txtout2=$prfx"_pastoral_use_stats.txt" +txtout3=$prfx"_ag_plus_past_use_stats.txt" + + + +#first make some tempfiles to hold various reclass and color rules +TMP1=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + + +echo "0 = 0 bare land" > $TMP1 +echo "1 = 1 sparsely covered land" >> $TMP1 +echo "2 = 2 actively cultivated field" >> $TMP1 +echo "3 = 3 moderate grassland" >> $TMP1 +echo "4 = 4 grassland" >> $TMP1 +echo "5 = 5 grass and sparse shrubs" >> $TMP1 +echo "6 = 6 grass and shrubs" >> $TMP1 +echo "7 = 7 mainly shrubs" >> $TMP1 +echo "8 = 8 developing maquis" >> $TMP1 +echo "9 = 9 moderate maquis" >> $TMP1 +echo "10 = 10 maquis" >> $TMP1 +echo "11 = 11 moderately dense maquis" >> $TMP1 +echo "12 = 12 dense maquis" >> $TMP1 +echo "13 = 13 maquis and small trees" >> $TMP1 +echo "14 = 14 young woodland and maquis" >> $TMP1 +echo "15 = 15 mostly young open woodland" >> $TMP1 +echo "16 = 16 young open woodland" >> $TMP1 +echo "17 = 17 moderate open woodland" >> $TMP1 +echo "18 = 18 maturing and moderate open woodland" >> $TMP1 +echo "19 = 19 maturing open woodland" >> $TMP1 +echo "20 = 20 mostly matured open woodland" >> $TMP1 +echo "21 = 21 fully matured woodland" >> $TMP1 +echo "end" >> $TMP1 + + +TMP6=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP6" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0 brown" > $TMP6 +echo "1 brown" >> $TMP6 +echo "2 red" >> $TMP6 +echo "3 orange" >> $TMP6 +echo "7 orange" >> $TMP6 +echo "14 yellow" >> $TMP6 +echo "21 green" >> $TMP6 +echo "end" >> $TMP6 + +TMP2=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0 brown" > $TMP2 +echo "7 orange" >> $TMP2 +echo "14 yellow" >> $TMP2 +echo "21 green" >> $TMP2 +echo "end" >> $TMP2 + +TMP3=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0 = 0 badly overgrazed" > $TMP3 +echo "1 = 1 overgrazed" >> $TMP3 +echo "2 = 2 sparse grassland" >> $TMP3 +echo "3 = 3 moderate grassland" >> $TMP3 +echo "4 = 4 grassland" >> $TMP3 +echo "5 = 5 grass and sparse shrubs" >> $TMP3 +echo "6 = 6 grass and shrubs" >> $TMP3 +echo "7 = 7 mainly shrubs" >> $TMP3 +echo "8 = 8 developing maquis" >> $TMP3 +echo "9 = 9 moderate maquis" >> $TMP3 +echo "10 = 10 maquis" >> $TMP3 +echo "11 = 11 moderately dense maquis" >> $TMP3 +echo "12 = 12 dense maquis" >> $TMP3 +echo "13 = 13 maquis and small trees" >> $TMP3 +echo "14 = 14 young woodland and maquis" >> $TMP3 +echo "15 = 15 mostly young open woodland" >> $TMP3 +echo "16 = 16 young open woodland" >> $TMP3 +echo "17 = 17 moderate open woodland" >> $TMP3 +echo "18 = 18 maturing and moderate open woodland" >> $TMP3 +echo "19 = 19 maturing open woodland" >> $TMP3 +echo "20 = 20 mostly matured open woodland" >> $TMP3 +echo "21 = 21 fully matured woodland" >> $TMP3 +echo "50 = 3 actively cultivated wheat field" >> $TMP3 +echo "end" >> $TMP3 + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0:1:0.5:0.5" > $TMP4 +echo "2:21:0.10:0.05" >> $TMP4 +echo "end" >> $TMP4 + +TMP5=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0.4 red" > $TMP5 +echo "0.6 black" >> $TMP5 +echo "0.19 grey" >> $TMP5 +echo "0.17 brown" >> $TMP5 +echo "0.1 orange" >> $TMP5 +echo "0.07 yellow" >> $TMP5 +echo "0.05 green" >> $TMP5 +echo "end" >> $TMP5 + + + + + +g.region --quiet save=temp_region + + + + + +echo "" +echo "*************************" +echo "Sarting land use evolution calculation. This will start a loop and may take some time. Please do not interrupt the process until it has finished. If interrupted, all temporary files created thus far will not be deleted. Plese be sure to check that all temporary files are deleted from your mapset before restarting the simulation" +echo "*************************" +echo "" + + +echo "YEAR 1" + +echo "" +echo "Part 1: agricultural simulation" +echo "" + +r.mapcalc "temp_background_1=if(isnull($inmapg), 21)" + cat $TMP3 | r.reclass --quiet input=temp_background_1 output=temp_background_2 +r.mapcalc "temp_background=if(isnull(temp_background_2), null(), temp_background_2)" +g.remove --quiet rast=temp_background_2,temp_background_1 + + cat $TMP2 | r.colors --quiet map=temp_background color=rules + + cat $TMP4 | r.recode --quiet input=temp_background output=temp_background_cfactor + + cat $TMP5 | r.colors --quiet map=temp_background_cfactor color=rules + +r.mask --quiet input=$inmapa maskcats=* + +g.region --quiet res=$sizea + +r.mapcalc "tmpinreclassa = if ($inmapa, 2, null())" + +fields1=$prfx"_fields1" + +r.random input=tmpinreclassa n=$randa"%" raster_output=$fields1 + +if [ "$GIS_FLAG_g" -eq 1 ]; then + + echo "fields map = $fields1" + + fi + + + temparea=`eval r.stats -n --quiet -a fs=- input=$fields1 | cut -d'-' -f2` + echo "" + echo "Area of randomized fields = $temparea square meters" + + + g.remove --quiet rast=MASK + +echo "***********************" +echo "" +echo "Part 2: grazing simulation" +echo "" + + + +r.mapcalc "MASK=if( if(isnull($prfx"_fields1") && ($inmapg <= 0 || $inmapg >= 0), 1, null()))" + +timer=$prfx".timer1" + +g.region --quiet res=$sizeg + +r.mapcalc "tmpinreclassg = if ($inmapg, 1, null())" + +patches=$prfx"_patches1" + + +r.random --quiet input=tmpinreclassg n=$randg"%" raster_output=$patches + +if [ "$GIS_FLAG_g" -eq 1 ]; then + + echo "grazing patches map = $patches" + + fi + +r.mapcalc "$timer = if (isnull($patches), 21, 21-$effect)" + + + cat $TMP3 | r.reclass --quiet input=$timer output=temp_pastuse1 + + r.mapcalc "$prfx"_past_luse1" = temp_pastuse1" + + cat $TMP2 | r.colors --quiet map=$prfx"_past_luse1" color=rules + + cat $TMP4 | r.recode --quiet input=$prfx"_past_luse1" output=$prfx"_past_cfactor_1" + + cat $TMP5 | r.colors --quiet map=$prfx"_past_cfactor_1" color=rules + + + temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2` + echo "" + echo "Area of new randomized grazing patches = $temparea square meters" + + + +#here we grab some pastoral stats, if asked for... + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "Stats for $loop years of grazing at $randg% grazing of the catchment $inmapg in $sizeg square meter patches" > $txtout2 +echo "" >> $txtout2 +echo "Year 1:" >> $txtout2 +echo "" >> $txtout2 +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout2 +echo "" >> $txtout2 +r.stats -a -l -n input=$prfx"_past_luse1" fs=, nv=* nsteps=255 >> $txtout2 + +fi + +g.remove --quiet rast=MASK + +#here we actually make the ag maps + +g.region --quiet res=$sizea + +r.mask --quiet input=$inmapa maskcats=* + +r.patch --quiet input=$fields1,$timer output=temp_landuse1_1 + + + + cat $TMP1 | r.reclass --quiet input=temp_landuse1_1 output=temp_landuse1 + + r.mapcalc "$prfx"_ag_luse1" = temp_landuse1" + + cat $TMP6 | r.colors --quiet map=$prfx"_ag_luse1" color=rules + + cat $TMP4 | r.recode --quiet input=$prfx"_ag_luse1" output=$prfx"_ag_cfactor_1" + + cat $TMP5 | r.colors --quiet map=$prfx"_ag_cfactor_1" color=rules + + + +#here we grab some ag stats, if asked for... + + if [ "$GIS_FLAG_m" -eq 1 ]; then + + r.mapcalc "tempmap_arable=if($prfx"_ag_luse1" >= 12, 1, null())" + + arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` + + r.mapcalc "tempmap_fallow=if($prfx"_ag_luse1" > 0 && $prfx"_ag_luse1" < 12, 1, null())" + + fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` + + g.remove --quiet rast=tempmap_arable,tempmap_fallow + + +echo "Stats for $randa"%" in $sizea patches (for a total of $temparea sq.m) agricultural use of input catchment $inmapa" > $txtout +echo "" >> $txtout +echo "Year,Area of potentially arable land (sq.m), Area of non arable fallow land (sq.m)" >> $txtout +echo "1,$arablearea,$fallowarea" >> $txtout + fi + + + +g.remove --quiet rast=MASK + +g.region --quiet -g region=temp_region + +echo "***********************" +echo "" +echo "Creating combined landcover and C-factor maps" +echo "" + + r.patch --quiet input=$prfx"_ag_luse1",$prfx"_past_luse1",temp_background output=$prfx"_agropast_luse1" + + r.patch --quiet input=$prfx"_ag_cfactor_1",$prfx"_past_cfactor_1",temp_background_cfactor output=$prfx"_agropast_cfactor_1" + + +#here we grab some combined pastoral and ag stats, if asked for... + +if [ "$GIS_FLAG_p" -eq 1 ]; then + +echo "Stats for $loop years of grazing at $randg% grazing of the catchment $inmapg in $sizeg square meter patches and $randa% farming of the ag catchment in $sizea square meter patches of the catchment $inmapa. " > $txtout3 +echo "" >> $txtout3 +echo "Year 1:" >> $txtout3 +echo "" >> $txtout3 +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout3 +echo "" >> $txtout3 +r.stats -a -l -n input=$prfx"_agropast_luse1" fs=, nv=* nsteps=255 >> $txtout3 + +fi + + +echo "************************" +echo "" + +step=1 + + +while [ "$step" -lt "$loop" ] +do + step=$(($step+1)) + echo "YEAR $step" + laststep=$(($step-1)) + + +echo "" +echo "Part 1: agricultural simulation" +echo "" + + + outfields=$prfx"_fields"$step + + + +r.mask --quiet input=$inmapa maskcats=* + +g.region --quiet res=$sizea + + + r.random --quiet input=tmpinreclassa n=$randa"%" raster_output=$outfields + + if [ "$GIS_FLAG_g" -eq 1 ]; then + + echo "fields map = $outfields" + + fi + + +g.remove --quiet rast=MASK + + +echo "**************************" +echo "" +echo "Part 2: grazing simulation" +echo "" + +r.mapcalc "MASK=if( if(isnull($outfields) && ($inmapg <= 0 || $inmapg >= 0), 1, null()))" + +g.region --quiet res=$sizeg + + outcfactor=$prfx"_past_cfactor_"$step + tmplanduse="temp_pastuse"$step + outlanduse=$prfx"_past_luse"$step + outpatches=$prfx"_patches"$step + newtimer=$prfx".timer"$step + oldtimer=$prfx"_agropast_luse"$laststep + + + r.random --quiet input=tmpinreclassg n=$randg"%" raster_output=$outpatches + + if [ "$GIS_FLAG_g" -eq 1 ]; then + + echo "grazing patches map = $outpatches" + + fi + +r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 20, $oldtimer + 1, (if(isnull($outpatches), 21, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" + + + cat $TMP3 | r.reclass --quiet input=$newtimer output=$tmplanduse + + r.mapcalc "$outlanduse = $tmplanduse" + + cat $TMP2 | r.colors --quiet map=$outlanduse color=rules + + cat $TMP4 | r.recode --quiet input=$outlanduse output=$outcfactor + + cat $TMP5 | r.colors --quiet map=$outcfactor color=rules + + + temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2` + + echo "" + echo "Area of new randomized grazing patches = $temparea square meters" +echo "" +echo "" +echo "************************" +echo "" + +#here we grab some pastoral stats, if asked for... + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "" >> $txtout2 +echo "Year $step:" >> $txtout2 +echo "" >> $txtout2 +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout2 +echo "" >> $txtout2 +r.stats -a -l -n input=$outlanduse fs=, nv=* nsteps=255 >> $txtout2 + +fi + +g.remove --quiet rast=MASK + +#here we actually make the ag maps + tmpcfactor="temp_ag_cfactor"$step + outagcfactor=$prfx"_ag_cfactor"$step + tmplanduse="temp_aguse"$step + tmp2landuse="temp_aguse"$step"_$step" + outaglanduse=$prfx"_ag_luse"$step + tcs="temp_class"$step + tcls=$prfx"agropast_luse"$laststep + +g.region --quiet res=$sizea + +r.mask --quiet input=$inmapa maskcats=* + +r.patch --quiet input=$outfields,$newtimer output=$tmp2landuse + + + + cat $TMP1 | r.reclass --quiet input=$tmp2landuse output=$tmplanduse + + r.mapcalc "$outaglanduse = $tmplanduse" + + cat $TMP6 | r.colors --quiet map=$outaglanduse color=rules + + cat $TMP4 | r.recode --quiet input=$outaglanduse output=$outagcfactor + + cat $TMP5 | r.colors --quiet map=$outagcfactor color=rules + + + temparea=`eval r.stats -n --quiet -a fs=- input=$outfields | cut -d'-' -f2` + echo "" + echo "Field placement re-randomized. Still cultivating $temparea square meters" + +#here we grab some ag stats, if asked for... + + if [ "$GIS_FLAG_m" -eq 1 ]; then + + r.mapcalc "tempmap_arable=if($outaglanduse >= 12, 1, null())" + + arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` + + r.mapcalc "tempmap_fallow=if($outaglanduse > 0 && $outaglanduse < 12, 1, null())" + + fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` + + g.remove --quiet rast=tempmap_arable,tempmap_fallow + + +echo "$step,$arablearea,$fallowarea" >> $txtout + + fi + + + +g.remove --quiet rast=MASK + +g.region --quiet -g region=temp_region + +echo "***********************" +echo "" +echo "Creating combined landcover and C-factor maps" +echo "" + +outcombluse=$prfx"_agropast_luse"$step +outcombcfactor=$prfx"_agropast_cfactor_"$step + + + r.patch --quiet input=$outaglanduse,$outlanduse,temp_background output=$outcombluse + + r.patch --quiet input=$outagcfactor,$outcfactor,temp_background_cfactor output=$outcombcfactor + + +#here we grab some combined pastoral and ag stats, if asked for... + +if [ "$GIS_FLAG_p" -eq 1 ]; then + +echo "" >> $txtout3 +echo "Year $step:" >> $txtout3 +echo "" >> $txtout3 +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout3 +echo "" >> $txtout3 +r.stats -a -l -n input=$outcombluse fs=, nv=* nsteps=255 >> $txtout3 + +fi + + +echo "************************" +echo "" + + + + + + + + + +done + + + + + +echo "" +echo "*************************" +echo "step 4 of 4: Cleaning up" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_g" -eq 1 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --quiet rast=temp* +g.mremove -f --quiet rast=$prfx"_*_cfactor*" +g.mremove -f --quiet rast=$prfx".timer*" +g.remove --quiet rast=tmpinreclassa,tmpinreclassg,MASK + +elif [ "$GIS_FLAG_g" -eq 0 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --quiet rast=$prfx"_patches*" +g.mremove --quiet -f rast=$prfx"_fields*" +g.mremove -f --quiet rast=temp* +g.mremove -f --quiet rast=$prfx"_*_cfactor*" +g.mremove -f --quiet rast=$prfx".timer*" +g.remove --quiet rast=tmpinreclassa,tmpinreclassg,MASK + +elif [ "$GIS_FLAG_g" -eq 1 -a "$GIS_FLAG_l" -eq 0 ] ; then + +g.remove --quiet rast=tmpinreclassa,tmpinreclassg,MASK +g.mremove -f --quiet rast=temp_landuse* +g.mremove -f --quiet rast=$prfx".timer*" +else + + +g.mremove -f --quiet rast=$prfx"_patches*" +g.mremove --quiet -f rast=$prfx"_fields*" +g.mremove -f --quiet rast=temp* +g.remove --quiet rast=tmpinreclassa,tmpinreclassg,MASK +g.mremove -f --quiet rast=$prfx".timer*" + +fi + + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort +\rm -f $TMP5 $TMP5.sort +\rm -f $TMP6 $TMP6.sort + + +g.remove --quiet region=temp_region + + +echo "" +echo "DONE!" +echo "" +echo "" + Property changes on: trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive =================================================================== --- trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive (rev 0) +++ trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,409 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.agropast.intensive +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a series of iterative landuse maps from a pastoral catchment and an +# intensive agricultural catchment (both need to be created by +# r.catchment), and outputs c factor as well +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a series of iterative landuse maps from a pastoral catchment and an intensive agricultural catchment (both need to be created by r.catchment), and outputs c factor as well. +#%END +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: Input pastoral catchment map (from r.catchment or r.buffer) +#% required : yes +#%END +#%option +#% key: inmapa +#% type: string +#% gisprompt: old,cell,raster +#% description: Input agricultural catchment map (to be modelled as wheat agriculture with no grazing, from r.catchment or r.buffer) +#% required : yes +#%END +#%option +#% key: rand +#% type: integer +#% description: percent of area to be grazed in any year (to be used in r.random) +#% answer: 50 +#% required : yes +#%END +#%option +#% key: size +#% type: integer +#% description: size of grazing patches (set as resolution in g.region) +#% answer: 15 +#% required : yes +#%END +#%option +#% key: effect +#% type: integer +#% description: Intensity of grazing (amount by which landcover is decreased after grazing) +#% answer: 1 +#% options: 1,2,3,4,5 +#% required : yes +#%END +#%option +#% key: loop +#% type: integer +#% description: number of iterations ("years") to run +#% answer: 50 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% required : yes +#%END +#%flag +#% key: l +#% description: -l Suppress output of C factor map (output landuse map only) +#%END +#%flag +#% key: f +#% description: -f Output maps of random grazing patches at each iteration as well +#%END +#%flag +#% key: s +#% description: -s Output text file of land-use stats from the simulation (will be named "prefix"_luse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) +#% answer: 1 +#%END + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +inmap=$GIS_OPT_inmap +inmapa=$GIS_OPT_inmapa +rand=$GIS_OPT_rand +size=$GIS_OPT_size +loop=$GIS_OPT_loop +effect=$GIS_OPT_effect +prfx=$GIS_OPT_prfx +timer=$prfx".timer1" +txtout=$prfx"_luse_stats.txt" + +TMP1=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + +echo "2 = 2 actively cultivated field" > $TMP1 + +TMP2=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0 grey" > $TMP2 +echo "5 brown" >> $TMP2 +echo "10 orange" >> $TMP2 +echo "15 yellow" >> $TMP2 +echo "21 green" >> $TMP2 +echo "end" >> $TMP2 + +TMP3=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0 = 0 badly overgrazed" > $TMP3 +echo "1 = 1 overgrazed" >> $TMP3 +echo "2 = 2 sparse grassland" >> $TMP3 +echo "3 = 3 moderate grassland" >> $TMP3 +echo "4 = 4 grassland" >> $TMP3 +echo "5 = 5 grass and sparse shrubs" >> $TMP3 +echo "6 = 6 grass and shrubs" >> $TMP3 +echo "7 = 7 mainly shrubs" >> $TMP3 +echo "8 = 8 developing maquis" >> $TMP3 +echo "9 = 9 moderate maquis" >> $TMP3 +echo "10 = 10 maquis" >> $TMP3 +echo "11 = 11 moderately dense maquis" >> $TMP3 +echo "12 = 12 dense maquis" >> $TMP3 +echo "13 = 13 maquis and small trees" >> $TMP3 +echo "14 = 14 young woodland and maquis" >> $TMP3 +echo "15 = 15 mostly young open woodland" >> $TMP3 +echo "16 = 16 young open woodland" >> $TMP3 +echo "17 = 17 moderate open woodland" >> $TMP3 +echo "18 = 18 maturing and moderate open woodland" >> $TMP3 +echo "19 = 19 maturing open woodland" >> $TMP3 +echo "20 = 20 mostly matured open woodland" >> $TMP3 +echo "21 = 21 fully matured woodland" >> $TMP3 +echo "end" >> $TMP3 + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0:1:0.5:0.5" > $TMP4 +echo "2:5:0.10:0.10" >> $TMP4 +echo "6:9:0.15:0.15" >> $TMP4 +echo "10:13:0.18:0.18" >> $TMP4 +echo "13:16:0.08:0.08" >> $TMP4 +echo "17:20:0.06:0.06" >> $TMP4 +echo "21:21:0.05:0.05" >> $TMP4 +echo "end" >> $TMP4 + +TMP5=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0.5 grey" > $TMP5 +echo "0.6 grey" >> $TMP5 +echo "0.19 brown" >> $TMP5 +echo "0.17 brown" >> $TMP5 +echo "0.10 yellow" >> $TMP5 +echo "0.05 green" >> $TMP5 +echo "end" >> $TMP5 + + + +echo "" +echo "*************************" +echo "step 1 of 4: Calculating MASK and background files" +echo "*************************" +echo "" + +r.mapcalc "temp_cat_1=if(isnull($inmapa), null(), 2)" +cat $TMP1 | r.reclass --quiet input=temp_cat_1 output=temp_cat_2 +r.mapcalc "temp_agricultral_luse=if(isnull(temp_cat_2), null(), temp_cat_2)" +g.remove --quiet rast=temp_cat_2,temp_cat_1 + +r.mapcalc "temp_background_1=if(isnull($inmap), 21)" +cat $TMP3 | r.reclass --quiet input=temp_background_1 output=temp_background_2 +r.mapcalc "temp_background=if(isnull(temp_background_2), null(), temp_background_2)" +g.remove --quiet rast=temp_background_2,temp_background_1 + +g.remove --quiet rast=MASK +r.mapcalc "MASK=if(isnull($inmapa), $inmap, null())" + + + +echo "" +echo "*************************" +echo "step 2 of 4: Changing resolution to field size (will be reset)" +echo "*************************" +echo "" + +g.region save=temp_region + +g.region res=$size + + + +echo "" +echo "*************************" +echo "step 3 of 4: Sarting land use evolution calculation. This will start a loop and may take some time. Please do not interrupt the process until it has finished" +echo "*************************" +echo "" + + +echo "iteration 1" + +r.mapcalc "tmpinreclass = if ($inmap, 1, null())" + +patches=$prfx"_patches1" + + +r.random --q input=tmpinreclass n=$rand"%" raster_output=$patches + +if [ "$GIS_FLAG_f" -eq 1 ]; then + + echo "grazing patches map = $patches" + + fi + +r.mapcalc "$timer = if (isnull($patches), 21, 21-$effect)" + + + cat $TMP3 | r.reclass --q input=$timer output=temp_landuse1 + +g.rename --quiet rast=MASK,$prfx"mask" + + r.mapcalc "$prfx"_landuse1" = if(isnull($inmapa) && isnull($inmap), temp_background, if(isnull($inmapa) && ($inmap >= 0), temp_landuse1, temp_agricultral_luse))" + + cat $TMP2 | r.colors --q map=$prfx"_landuse1" color=rules + + cat $TMP4 | r.recode --q input=$prfx"_landuse1" output=$prfx"_cfactor_1" + + cat $TMP5 | r.colors --q map=$prfx"_cfactor_1" color=rules + + + temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2` + echo "" + echo "Area of new randomized grazing patches = $temparea square meters" + + + + + +echo "***********************" + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "Stats for $loop years of grazing at $rand% grazing of the landscape in $size square meter patches" > $txtout +echo "" >> $txtout +echo "Year 1:" >> $txtout +echo "" >> $txtout +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$prfx"_landuse1" fs=, nv=* nsteps=255 >> $txtout + +fi + +step=1 + + +while [ "$step" -lt "$loop" ] +do + step=$(($step+1)) + echo "iteration $step" + laststep=$(($step-1)) + + + + outcfactor=$prfx"_cfactor_"$step + tmplanduse="temp_landuse"$step + outlanduse=$prfx"_landuse"$step + outpatches=$prfx"_patches"$step + newtimer=$prfx".timer"$step + oldtimer=$prfx".timer"$laststep + +g.rename --quiet rast=$prfx"mask",MASK + + r.random --q input=tmpinreclass n=$rand"%" raster_output=$outpatches + + if [ "$GIS_FLAG_f" -eq 1 ]; then + + echo "grazing patches map = $outpatches" + + fi + +r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 20, $oldtimer + 1, (if(isnull($outpatches), 21, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" + + + + cat $TMP3 | r.reclass --q input=$newtimer output=$tmplanduse + +g.rename --quiet rast=MASK,$prfx"mask" + + r.mapcalc "$outlanduse =if(isnull($inmapa) && isnull($inmap), temp_background, if(isnull($inmapa) && ($inmap >= 0), $tmplanduse, temp_agricultral_luse))" + + cat $TMP2 | r.colors --q map=$outlanduse color=rules + + cat $TMP4 | r.recode --q input=$outlanduse output=$outcfactor + + cat $TMP5 | r.colors --q map=$outcfactor color=rules + + temparea=`eval r.stats -n -a fs=- input=$outpatches | cut -d'-' -f2` + echo "" + echo "Area of new randomized grazing patches = $temparea square meters" +echo "" +echo "" +echo "************************" +echo "" + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "" >> $txtout +echo "Year $step:" >> $txtout +echo "" >> $txtout +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$outlanduse fs=, nv=* nsteps=255 >> $txtout + +fi + +done + + +echo "" +echo "*************************" +echo "step 4 of 4: Cleaning up" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --q rast=temp* +g.mremove -f --q rast=*mask +g.mremove -f --q rast=$prfx"_cfactor*" +g.mremove -f --q rast=$prfx".timer*" +g.remove --q rast=tmpinreclass,MASK + +elif [ "$GIS_FLAG_f" -eq 0 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --q rast=$prfx"_patches*" +g.mremove -f --q rast=temp* +g.mremove -f --q rast=*mask +g.mremove -f --q rast=$prfx"_cfactor*" +g.mremove -f --q rast=$prfx".timer*" +g.remove --q rast=tmpinreclass,MASK + +elif [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 0 ] ; then + +g.remove --q rast=tmpinreclass,MASK +g.mremove -f --q rast=temp* +g.mremove -f --q rast=*mask +g.mremove -f --q rast=$prfx".timer*" +else + + +g.mremove -f --q rast=$prfx"_patches*" +g.mremove -f --q rast=temp* +g.mremove -f --q rast=*mask +g.remove --q rast=tmpinreclass,MASK +g.mremove -f --q rast=$prfx".timer*" + +fi + + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort +\rm -f $TMP5 $TMP5.sort + + +echo "" +echo "Resetting region" +echo "" + +g.region -g region=temp_region +g.remove --q region=temp_region + + +echo "" +echo "DONE!" +echo "" +echo "" + Property changes on: trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.catchment/r.catchment =================================================================== --- trunk/grassaddons/LandDyn/r.catchment/r.catchment (rev 0) +++ trunk/grassaddons/LandDyn/r.catchment/r.catchment 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,398 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.catchment +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a raster buffer of specified area around vector points +# using cost distances. Module requires r.walk. +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a raster buffer of specified area around vector points using cost distances. Requires r.walk. +#%END + +#%option +#% key: incost +#% type: string +#% gisprompt: old,cell,raster +#% description: Input cost map (if none specified, one will be created with r.walk) +#% required : no +#%END +#%option +#% key: elev +#% type: string +#% gisprompt: old,cell,raster +#% description: Input elevation map (DEM) +#% required : no +#%END +#%option +#% key: vect +#% type: string +#% gisprompt: old,vector,vector +#% description: Name of input vector site points map +#% required : yes +#%END +#%option +#% key: frict +#% type: string +#% gisprompt: old,cell,raster +#% description: Optional map of friction costs. If no map selected, default friction=1 making output reflect time costs only +#% answer: +#% required : no +#%END +#%option +#% key: a +#% type: double +#% description: Coefficients for walking energy formula parameters a,b,c,d +#% answer: 0.72 +#% required : no +#%END +#%option +#% key: b +#% type: double +#% description: +#% answer: 6.0 +#% required : no +#%END +#%option +#% key: c +#% type: double +#% description: +#% answer: 1.9998 +#% required : no +#%END +#%option +#% key: d +#% type: double +#% description: +#% answer: -1.9998 +#% required : no +#%END +#%option +#% key: lambda +#% type: double +#% description: Lambda value for cost distance calculation +#% answer: 0 +#% required : no +#%END +#%option +#% key: slope_factor +#% type: double +#% description: Slope factor determines travel energy cost per height step +#% answer: -0.2125 +#% required : no +#%END +#%option +#% key: buffer +#% type: string +#% gisprompt: old,cell,raster +#% description: Output buffer map +#% required : yes +#%END +#%option +#% key: sigma +#% type: double +#% description: Slope threshold for mask +#% answer: +#% required : no +#%END +#%option +#% key: area +#% type: integer +#% description: Area of buffer (Integer value to nearest 100 square map units) +#% answer: 5000000 +#% required : yes +#%END +#%option +#% key: start_step +#% type: integer +#% description: Optional starting cost distance value (if none entered, starting step willbe 1) +#% answer: 1 +#% required : no +#%END +#%option +#% key: step_size +#% type: integer +#% description: Integer length of iteration step. (smaller values will create buffers closer to actual specified area, but will take significantly longer. ie. there will be more iteration steps) +#% answer: 10 +#% required : yes +#%END +#%option +#% key: mapval +#% type: integer +#% description: Integer vlaue for out put catchment area (all other areas will be Null) +#% answer: 1 +#% required : yes +#%END +#%flag +#% key: k +#% description: -k Use knight's move for calculating cost surface (slower but more accurate) +#%END +#%flag +#% key: o +#% description: -o Overwrite existing output buffer map +#%END +#%flag +#% key: c +#% description: -c Keep output cost surface +#%END + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +incost=$GIS_OPT_incost +elev=$GIS_OPT_elev +vect=$GIS_OPT_vect +input_frict=$GIS_OPT_frict +lmbda=$GIS_OPT_lambda +echo "lambda=$lmbda" +slpfct=$GIS_OPT_slope_factor +echo "slope_factor=$slpfct" +a=$GIS_OPT_a +b=$GIS_OPT_b +c=$GIS_OPT_c +d=$GIS_OPT_d +echo "a,b,c,d=$a,$b,$c,$d" +sigma=$GIS_OPT_sigma +echo "sigma=$sigma" +area=$GIS_OPT_area +echo "Wanted buffer area=$area" +stepsize=$GIS_OPT_step_size +echo "iteration step size=$stepsize" +buffer=$GIS_OPT_buffer +echo "Output buffer=$buffer" +cost="temporary.cost" +slope="temporary.slope" +frict="temporary.friction" +mapval=$GIS_OPT_mapval + + + + +g.region -g rast=$elev + +echo "" +echo "Checking for the existance of an input cost surface" +echo "" + +if [ -n "$GIS_OPT_incost" ]; then + +echo "" +echo "*************************" +echo "step 1 of 4: Using input cost surface" +echo "*************************" +echo "" + +cost=$incost + +else + +echo "" +echo "*************************" +echo "step 1 of 4: Calculating cost surface" +echo "*************************" +echo "" + +if [ -n "$GIS_OPT_frict" ]; then + +r.mapcalc "$frict=$input_frict" + +echo "Calculating costs using input friction map" + +else + + +r.mapcalc "$frict=if(isnull($elev), null(), 1)" + +echo "Calculating for time costs only" + +fi + + +if [ "$GIS_FLAG_k" -eq 1 ]; then + +echo "Using Knight's move" + +r.walk --q elevation=$elev friction=$frict output=$cost start_points=$vect lambda=$lmbda percent_memory=100 nseg=4 walk_coeff=$a,$b,$c,$d slope_factor=$slpfct -k + +else + +r.walk --q elevation=$elev friction=$frict output=$cost start_points=$vect lambda=$lmbda percent_memory=100 nseg=4 walk_coeff=$a,$b,$c,$d slope_factor=$slpfct + +fi + +fi + +echo "" +echo "*************************" +echo "step 2 of 4: Creating optionalslope mask" +echo "*************************" +echo "" + + + +if [ -n "$GIS_OPT_sigma" ]; then + +r.slope.aspect --q elevation=$elev slope=$slope + +r.mapcalc "MASK=if ($slope <= $sigma, 1, null())" +else +echo "No slope mask created" +fi + +echo "" +echo "*************************" +echo "step 3 of 4: Calculating buffer. This will start a loop and may take some time. Please do not interrupt the process until it has finished" +echo "*************************" +echo "" + + +#r.info -r input=$cost > $TMP2 +#r.describe map=$cost > $TMP2 +#cut -d'-' -f2 $TMP2 > $TMP4 + +max=`eval r.info -r map=$cost | grep "max=" | cut -d"=" -f2 | cut -d'.' -f1` + +echo "max travel cost across the landscape from originating point = $max" + + +if [ -n "$GIS_OPT_start_step" ]; then + +step=$GIS_OPT_start_step + +else + +step=1 + +fi + +tmparea=0 + + +while [ "$step" -le "$max" ] +do + step=$(($step+$stepsize)) + +oldarea=$(echo "scale=0; $tmparea/2" | bc) + + echo "current cost distance from originating point = $step" + + echo "0 thru $step = $mapval" | r.reclass --q input=$cost output=cost.reclass --o + + tmparea=`eval r.stats -n -a fs=- input=cost.reclass | cut -d'-' -f2 | cut -d'.' -f1` + + echo "current integer area = $tmparea" + + if [ $tmparea -ge $area ] + then + break # Skip entire rest of loop. + fi + +stepsize=$(echo "scale=0; 1 + ( 100 * ( $tmparea - $oldarea ) / $tmparea)" | bc) + + + +done + +echo "" +echo "" +echo "*************************" +echo "" +echo "" +echo -n "Final area of modeled catchment = $tmparea" +echo "" +echo "" +echo "*************************" +echo "step 4 of 4: Creating output map" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_o" -eq 0 ]; then + +r.mapcalc "$buffer= if (cost.reclass, cost.reclass)" + +else + +outfile=`echo $buffer | cut -d'@' -f1` + +r.mapcalculator amap=cost.reclass formula='if (A, A, null())' outfile=$outfile --overwrite + +fi + + + + + +if [ "$GIS_FLAG_c" -eq 1 ]; then + +g.remove rast=MASK + +cost_surf=$GIS_OPT_buffer"_cost_surface" + +r.mapcalc "$cost_surf=temporary.cost" + +echo "" +echo "Cleaning up..." +echo "" + +if [ -n "$GIS_OPT_incost" ]; then + +g.remove rast=cost.reclass,$slope,$frict + +else + +g.remove rast=cost.reclass,$slope,$frict,$cost + +fi + +echo "" +echo "DONE!" +echo "" +echo "final buffer map = $buffer" +echo "" +echo "cost surface kept:" +echo "" +echo "cost surface = $cost_surf" +echo "" + +else + +echo "" +echo "Cleaning up..." +echo "" + +if [ -n "$GIS_OPT_incost" ]; then + +g.remove rast=cost.reclass,$slope,$frict,MASK + +else + +g.remove rast=cost.reclass,$slope,$frict,MASK,$cost + +fi + +echo "" +echo "DONE!" +echo "" +echo "final buffer map = $buffer" +echo "" + +fi + + Property changes on: trunk/grassaddons/LandDyn/r.catchment/r.catchment ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.iterate/r.iterate =================================================================== --- trunk/grassaddons/LandDyn/r.iterate/r.iterate (rev 0) +++ trunk/grassaddons/LandDyn/r.iterate/r.iterate 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,87 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.iterate +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a numerically ordered series of copies of a map +# for input into r.landscape.evol.itr +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a numerically ordered series of copies of a map for input into r.landscape.evol.itr +#%END +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: Map to make sequentially numbered copies of +#% required : yes +#%END +#%option +#% key: loop +#% type: integer +#% description: number of copies to make +#% answer: 50 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output copies +#% required : yes +#%END + + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +inmap=$GIS_OPT_inmap + +loop=$GIS_OPT_loop + +prfx=$GIS_OPT_prfx + +step=1 + +newmap=$prfx"_"$step + +g.copy rast=$inmap,$newmap + + echo "Making map: $newmap" + echo "" + +while [ "$step" -lt "$loop" ] +do + step=$(($step+1)) + +newmap=$prfx"_"$step + +g.copy rast=$inmap,$newmap + + echo "Making map: $newmap" + echo "" +done + + +echo "" +echo "DONE!" +echo "" +echo "" + Property changes on: trunk/grassaddons/LandDyn/r.iterate/r.iterate ___________________________________________________________________ Name: svn:executable + * Copied: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol (from rev 939, trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol) =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol (rev 0) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,1332 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.landscape.evol +# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University +# Helena Mitasova, North Carolina State University +# PURPOSE: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net +# erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil +# depth maps. This module uses appropriate flow on different landforms by default; however, +# singular flow regimes can be chosen instead. +# ACKNOWLEDGEMENTS:National Science Foundation Grant #BCS0410269 +# Based on work of H. Mitasova and C. S. Thaxton, and Heimsath et al, 1997. +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil depth maps. This module uses appropriate flow on different landforms by default; however, singular flow regimes can be chosen instead. THIS SCRIPT WILL PRODUCE MANY TEMPORARY MAPS AND REQUIRES A LOT OF FREE FILE SPACE! +#%End + +#%option +#% key: elev +#% type: string +#% gisprompt: old,cell,raster +#% description: Input elevation map (DEM) +#% required : yes +#% guisection: Input +#%end +#%option +#% key: initbdrk +#% type: string +#% gisprompt: old,cell,raster +#% description: Initial bedrock elevations map (for first iteration only) +#% answer: +#% required : yes +#% guisection: Input +#%end +#%option +#% key: prefx +#% type: string +#% description: Prefix for all output maps +#% answer: usped +#% required : yes +#% 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 +#%end +#%flag +#% key: k +#% description: -k Keep all intermediate files as well +#% guisection: Input +#%end +#%flag +#% key: e +#% description: -e Keep initial soil depths map +#% guisection: Input +#%end +#%flag +#% key: z +#% description: -z Keep region zoomed to output maps +#% answer: 1 +#% guisection: Input +#%end +#%flag +#% key: b +#% description: -b Use static bedrock elavations (do not create new soil) +#% answer: 1 +#% guisection: Input +#%end + + +#%option +#% key: R +#% type: string +#% description: Rainfall (R factor) constant or map +#% gisprompt: old,cell,raster +#% answer: 5 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: K +#% type: string +#% gisprompt: old,cell,raster +#% description: Soil erodability index (K factor) map or constant +#% answer: 0.32 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: C +#% type: string +#% gisprompt: old,cell,raster +#% description: Landcover index (C factor) map or constant +#% answer: 0.01 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: kappa +#% type: string +#% gisprompt: old,cell,raster +#% description: Hillslope diffusion (Kappa) rate map or constant (meters per kiloyear) +#% answer: 1 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: cutoff +#% type: string +#% description: Flow accumultion breakpoint value for shift from diffusion to overland flow (number of cells) +#% answer: 8 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: number +#% type: integer +#% description: number of iterations to run +#% answer: 1 +#% required : yes +#% guisection: Variables +#%end + + +#these are commented out as we currently utilize the profile curvature method described by Heimsath et al... +# #%option +# #% key: Ba +# #% type: string +# #% description: Rate of average soil production (Ba) +# #% answer: 0.00008 +# #% required : yes +# #% guisection: Variables +# #%end +# #%option +# #% key: Bb +# #% type: string +# #% description: Relationship between soil depth and production rate (Bb) +# #% answer: 0.1 +# #% required : yes +# #% guisection: Variables +# #%end + +#%flag +#% key: y +#% description: -y Don't smooth the map (faster, but spikes in erosion/deposition may result) +#% guisection: Smoothing_Filter +#%end +#%option +#% key: nbhood +#% type: string +#% description: Band-pass filter neighborhood size +#% answer: 7 +#% options: 1,3,5,7,9,11,13,15,17,19,21,23,25 +#% 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 +#% description: Neighborhood smoothing method +#% answer: median +#% options: median,mode,average +#% required : yes +#% guisection: Smoothing_Filter +#%end + +#%flag +#% key: c +#% description: -c Output cumulative erosion/depostition map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: m +#% description: -m Output mean erosion/depostition map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: t +#% description: -t Output standard deviation of erosion/depostition map from data for all iterations +#% 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 +#%end +#%flag +#% key: v +#% description: -v Output standard deviation soil depths map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: a +#% description: -a Output maximum soil depths map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: u +#% description: -u Output minimum soil depths map from data for all iterations +#% guisection: Statistics +#%end + +#%flag +#% key: w +#% description: -w Calcuate for only sheetwash across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: r +#% description: -r Calcuate for only channelized flow across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: d +#% description: -d Calcuate for only diffusive flow (soil creep) across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: f +#% description: -f Use r.terrflow instead of r.flow to calculate flow accumulation (better for massive grids) +#% guisection: Flow_type +#%end + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +prefx=$GIS_OPT_prefx +elev=$GIS_OPT_elev +initbdrk=$GIS_OPT_initbdrk +R=$GIS_OPT_R +K=$GIS_OPT_K +C=$GIS_OPT_C +kappa=$GIS_OPT_kappa +Ba=$GIS_OPT_Ba +Bb=$GIS_OPT_Bb +aplpha=$GIS_OPT_method +sigma=$GIS_OPT_sigma +nbhood=$GIS_OPT_nbhood +cutoff=$GIS_OPT_cutoff +number=$GIS_OPT_number +echo "total number of iterations to be run= $number" +echo "" + +if [ $number -eq 1 ] ; then + +num="" + +else + +num="1" + +fi + +echo "The following temporary files will be created:" +echo "" +neighbors=$prefx".neighbors"$num +echo "neighbors=$neighbors" +tempsmoothdz=$prefx".tempsmoothdz"$num +echo "tempsmoothdz=$tempsmoothdz" +smoothdz=$prefx"_smoothdz"$num +echo "smoothdz=$smoothdz" +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".m"$num +echo "m=$m" +n=$prefx".n"$num +echo "n=$n" +erdep=$prefx".erosdep"$num +echo "erdep=$erdep" + + + +echo "" + +new_soil=$prefx"_new_soil"$num +new_dem=$prefx"_new_dem"$num + +initsoil=$prefx"_initsoil" + + +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"_new_bdrk"$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` + +# we must set the region to the map being used. otherwise r.flow will not work +echo "" +echo "Setting region to $elev" +g.region rast=$elev + +#now lets show before: +echo "" +echo "Original Resolution = $res1" + +#...and after: +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 +echo "" +echo "##################################################" +echo "##################################################" +echo "" + +if [ $number -eq 1 ] ; then + +echo "STARTING SIMULATION" +echo "" +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 + +echo "" +echo "##################################################" +echo "" +echo "*************************" +echo "step 1 of 8: calculating slope and aspect (if initial aspect not specified)" +echo "*************************" +echo "" + + +r.slope.aspect --q $elev 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" + +r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=temp.flowacc tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp + +r.mapcalc "$flowacc=temp.flowacc/$res" + + +g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",temp.flowacc +rm -f /var/tmp/STREAM* + +else + +echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + +tmpflacc=$prefx".tmpflacc" + +r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc + +r.mapcalc "$flowacc=$tmpflacc*$res" + +g.remove --quiet rast=$tmpflacc + +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.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` + +echo "" +echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +echo "" + +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)))" + +report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` +report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` + +echo "" +echo "(for diagnostics only) max m = $report1, min m = $report2" + + +r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff, 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 fully 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 "$initsoil=$elev - $initbdrk" + +echo "" +echo "*************************" +echo "step 7 of 8: running band-pass filter" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_y" -eq 1 ]; then + +echo ""echo "You have selected not to smooth your files... Oh Well!" +echo "" + +r.mapcalc "$smoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" + +else + + +r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood +r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" +r.mapcalc "$smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" + +fi + +#checking to see if we should keep the initial soil depths map + + + + +# create temporary file to code colors for $smoothdz +TMP1=`g.tempfile pid=$$` + + +if [ $? -ne 0 ] || [ -z "$TMP1" ]; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +else + + echo "creating temporary file to code colors" + +fi + + +echo "0% 104 034 139" > $TMP1 +echo "-5 violet" >> $TMP1 +echo "-3 aqua" >> $TMP1 +echo "-1 cyan" >> $TMP1 +echo "-0.5 green" >> $TMP1 +echo "0 white" >> $TMP1 +echo "0.5 yellow" >> $TMP1 +echo "1 orange" >> $TMP1 +echo "3 red" >> $TMP1 +echo "5 255 000 255" $TMP1 +echo "100% 255 000 255" >> $TMP1 +echo "end" >> $TMP1 + + +cat $TMP1 | r.colors --q map=$smoothdz color=rules + +echo "" +echo "*************************" +echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" +echo "*************************" +echo "" + +r.mapcalc "$new_dem=$smoothdz + $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" + + +new_bdrk=$initbdrk +r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" + +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))" + +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))" + +#grabsomestats +tmperosion=$prfx"_tmperosion1" +tmpdep=$prfx"_tmpdep1" + +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 + +txtout=$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 "Raster map $smoothdz shows filtered net erosion/deposition" +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 "" +# echo "Done" +# echo "" +#else +# echo "" +# echo "Cleaning up..." +# g.remove rast=$flowacc,$slope,$aspect,$sflowtopo,$qsx,$qsy,$qsxdx,$qsydy,$erdep,$neighbors +# echo "" +# echo "Done" +#fi + + +#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"_new_dem"$laststep + +echo "The following temporary files will be created:" +echo "" +neighbors=$prefx".neighbors"$step +echo "neighbors=$neighbors" +tempsmoothdz=$prefx".tempsmoothdz"$step +echo "tempsmoothdz=$tempsmoothdz" +temp2smoothdz=$prefx".temp2smoothdz"$step +echo "temp2smoothdz=$temp2smoothdz" +smoothdz=$prefx"_smoothdz"$step +echo "smoothdz=$smoothdz" +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".m"$step +echo "m=$m" +n=$prefx".n"$step +echo "n=$n" +erdep=$prefx".erosdep"$step +echo "erdep=$erdep" +old_bdrk=$prefx"_new_bdrk"$laststep +echo "old_bdrk=$old_bdrk" +old_soil=$prefx"_new_soil"$laststep +echo "old_soil=$old_soil" +echo "" + +new_soil=$prefx"_new_soil"$step +new_dem=$prefx"_new_dem"$step +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"_new_bdrk"$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" + +r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp + +r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" + +g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" +rm -f /var/tmp/STREAM* + +else + +echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + +tmpflacc=$prefx".tmpflacc" +r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc + +r.mapcalc "$flowacc=$tmpflacc*$res" + +g.remove --quiet rast=$tmpflacc + +fi + + + +echo "" +echo "*************************" +echo "step 3 of 8: calculating basic sediment transport rates" +echo "*************************" +echo "" + + +initbdrk + +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),$m) * exp(sin($slope),$n)" + + +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.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` + + +echo "" +echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +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 "$sflowtopo=if ($flowacc >= $cutoff, 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 band-pass 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 + +r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood +r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $old_soil, (-1 * $old_soil), $erdep)" +r.mapcalc "$temp2smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" + +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 + + +# create temporary file to code colors for $smoothdz +TMP1=`g.tempfile pid=$$` + +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +else + echo "creating temporary file to code colors" + +fi + +echo "0% 104 034 139" > $TMP1 +echo "-5 violet" >> $TMP1 +echo "-3 aqua" >> $TMP1 +echo "-1 cyan" >> $TMP1 +echo "-0.5 green" >> $TMP1 +echo "0 white" >> $TMP1 +echo "0.5 yellow" >> $TMP1 +echo "1 orange" >> $TMP1 +echo "3 red" >> $TMP1 +echo "5 255 000 255" $TMP1 +echo "100% 255 000 255" >> $TMP1 +echo "end" >> $TMP1 + + +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" +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" + + +new_bdrk=$old_bdrk +r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" + +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))" + +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))" + + +#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 "Raster map $smoothdz shows filtered net erosion/deposition" +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 + + +# 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 + exit 1 +fi + + +g.mlist type=rast sep=, pattern=$prefx"_smoothdz*" > $TMP2 +liststring=`cat $TMP2` + +echo "Any selected statistics will be performed using the following smoothdz files: $liststring" + +if [ "$GIS_FLAG_c" -eq 1 ]; then + +r.series --q input=$liststring output=$prefx"_cum_erdep" method=sum +fi + +if [ "$GIS_FLAG_m" -eq 1 ]; then + +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 + +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 + + + +# 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 +fi + +g.mlist type=rast sep=, pattern=$prefx"_new_soil*" > $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_soil" method=average +fi + +if [ "$GIS_FLAG_v" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_sdev_soil" method=stddev +fi + +if [ "$GIS_FLAG_a" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_max_soil" method=maximum +fi + + +if [ "$GIS_FLAG_u" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_min_soil" method=minimum +fi +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort + + +echo "************************" + +if [ "$GIS_FLAG_k" -eq 1 ]; then + +echo "" +echo "Done" +echo "" + +else + +echo "" +echo "Cleaning up..." + +g.mremove -f --q rast=$prefx".neighbors*" +g.mremove -f --q rast=$prefx".smoothdz*" +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".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".m*" +g.mremove -f --q rast=$prefx".n*" + + echo "" + echo "Done" + +fi + +if [ "$GIS_FLAG_n" -eq 1 ]; then + + g.mremove --q rast=$prefx"_smoothdz*" +fi + +if [ "$GIS_FLAG_l" -eq 1 ]; then + + g.mremove --q rast=$prefx"_new_soil*" +fi + +if [ "$GIS_FLAG_z" -eq 1 ]; then +echo "" +echo "Iterations complete, keeping region set to output maps" +echo "" +else +echo "" +echo "Iterations complete, restoring default region settings" +echo "" + +g.region -d -g + +echo "" +fi +echo "###################################################" +echo "###################################################" +echo "___________________________________________________" +echo "" +echo " DONE WITH EVERYHTING" +echo "" +echo "___________________________________________________" + + + + Added: trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr (rev 0) +++ trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,1259 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.landscape.evol.itr +# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University +# Helena Mitasova, North Carolina State University +# PURPOSE: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net +# erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil +# depth maps. This module uses appropriate flow on different landforms by default; however, +# singular flow regimes can be chosen instead. This model is coded to accept a list of sequentially +# ordered input maps (sequential suffixes can be added by r.iterate) +# ACKNOWLEDGEMENTS:National Science Foundation Grant #BCS0410269 +# Based on work of H. Mitasova and C. S. Thaxton, and Heimsath et al, 1997. +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil depth maps for a given chronological sequence of enumerated R and C value input maps. This module uses appropriate flow on different landforms by default; however, singular flow regimes can be chosen instead. This model is coded to accept a list of sequentially ordered input maps (sequential suffixes can be added by r.iterate) THIS SCRIPT WILL PRODUCE MANY TEMPORARY MAPS AND REQUIRES A LOT OF FREE FILE SPACE! +#%End + +#%option +#% key: elev +#% type: string +#% gisprompt: old,cell,raster +#% description: Input elevation map (DEM) +#% required : yes +#% guisection: Input +#%end +#%option +#% key: initbdrk +#% type: string +#% gisprompt: old,cell,raster +#% description: Initial bedrock elevations map (for first iteration only) +#% answer: +#% required : yes +#% guisection: Input +#%end +#%option +#% key: prefx +#% type: string +#% description: Prefix for all output maps +#% answer: usped +#% required : yes +#% 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 +#%end +#%flag +#% key: k +#% description: -k Keep all intermediate files as well +#% guisection: Input +#%end +#%flag +#% key: z +#% description: -z Keep region zoomed to output maps +#% guisection: Input +#%end + +#%option +#% key: R +#% type: string +#% description: Rainfall (R factor) map prefixes (leave off years) +#% gisprompt: old,cell,raster +#% answer: rfactor +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: K +#% type: string +#% gisprompt: old,cell,raster +#% description: Soil erodability index (K factor) map or constant +#% answer: 0.32 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: C +#% type: string +#% gisprompt: old,cell,raster +#% description: Landcover index (C factor) map prefixes (leave off years) +#% answer: landcover_cfactor +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: kappa +#% type: string +#% gisprompt: old,cell,raster +#% description: Hillslope diffusion (Kappa) rate map or constant (meters per kiloyear) +#% answer: 1 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: cutoff +#% type: string +#% description: Flow accumultion breakpoint value for shift from diffusion to overland flow (number of cells) +#% answer: 8 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: number +#% type: integer +#% description: Iteration Time Step (integer years) +#% answer: 1 +#% required : yes +#% guisection: Variables +#%end +#%option +#% key: maxyrs +#% type: integer +#% description: Maximum Time Step (end year) +#% answer: 50 +#% required : yes +#% guisection: Variables +#%END +#%option +#% key: minyrs +#% type: integer +#% description: Minimum Time Step (start year) +#% answer: 1 +#% required : yes +#% guisection: Variables +#%END + +#these are commented out as we currently utilize the profile curvature method described by Heimsath et al... +# #%option +# #% key: Ba +# #% type: string +# #% description: Rate of average soil production (Ba) +# #% answer: 0.00008 +# #% required : yes +# #% guisection: Variables +# #%end +# #%option +# #% key: Bb +# #% type: string +# #% description: Relationship between soil depth and production rate (Bb) +# #% answer: 0.1 +# #% required : yes +# #% guisection: Variables +# #%end + +#%flag +#% key: y +#% description: -y Don't smooth the map (faster, but spikes in erosion/deposition may result) +#% guisection: Smoothing_Filter +#%end +#%option +#% key: nbhood +#% type: string +#% description: Band-pass filter neighborhood size +#% answer: 3 +#% options: 1,3,5,7,9,11,13,15,17,19,21,23,25 +#% 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 +#% description: Neighborhood smoothing method +#% answer: median +#% options: median,mode,average +#% required : yes +#% guisection: Smoothing_Filter +#%end + +#%flag +#% key: c +#% description: -c Output cumulative erosion/depostition map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: m +#% description: -m Output mean erosion/depostition map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: t +#% description: -t Output standard deviation of erosion/depostition map from data for all iterations +#% 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 +#%end +#%flag +#% key: v +#% description: -v Output standard deviation soil depths map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: a +#% description: -a Output maximum soil depths map from data for all iterations +#% guisection: Statistics +#%end +#%flag +#% key: u +#% description: -u Output minimum soil depths map from data for all iterations +#% guisection: Statistics +#%end + +#%flag +#% key: w +#% description: -w Calcuate for only sheetwash across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: r +#% description: -r Calcuate for only channelized flow across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: d +#% description: -d Calcuate for only diffusive flow (soil creep) across entire map +#% guisection: Flow_type +#%end +#%flag +#% key: f +#% description: -f Use r.terrflow instead of r.flow to calculate flow accumulation (better for massive grids) +#% guisection: Flow_type +#%end + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +prefx=$GIS_OPT_prefx +elev=$GIS_OPT_elev +initbdrk=$GIS_OPT_initbdrk +Rprfx=$GIS_OPT_R +echo "R prefix = $Rprfx" +K=$GIS_OPT_K +Cprfx=$GIS_OPT_C +echo "C prefix = $Cprfx" +kappa=$GIS_OPT_kappa +Ba=$GIS_OPT_Ba +Bb=$GIS_OPT_Bb +aplpha=$GIS_OPT_method +sigma=$GIS_OPT_sigma +nbhood=$GIS_OPT_nbhood +cutoff=$GIS_OPT_cutoff +echo "The following temporary files will be created:" +echo "" +neighbors=$prefx".neighbors1" +echo "neighbors=$neighbors" +tempsmoothdz=$prefx".tempsmoothdz1" +echo "tempsmoothdz=$tempsmoothdz" +smoothdz=$prefx"_smoothdz1" +echo "smoothdz=$smoothdz" +tempsmoothdz=$prefx".tempsmoothdz1" +echo "temsmoothpdz=$tempsmoothdz" +flowacc=$prefx".flowacc1" +echo "flowacc=$flowacc" +slope=$prefx".slope1" +echo "slope=$slope" +aspect=$prefx".aspect1" +echo "aspect=$aspect" +pc=$prefx".pc1" +echo "pc=$pc" +tc=$prefx".tc1" +echo "tc=$tc" +meancurv=$prefx".meancurv1" +echo "meancurv=$meancurv" +rate=$prefx".rate1" +echo "rate=$rate" +sflowtopo=$prefx".sflowtopo1" +echo "sflowtopo=$sflowtopo" +qsx=$prefx".qsx1" +echo "qsx=$qsx" +qsy=$prefx".qsy1" +echo "qsy=$qsy" +qsxdx=$prefx".qsx.dx1" +echo "qsxdx=$qsxdx" +qsydy=$prefx".qsy.dy1" +echo "qsydy=$qsydy" +m=$prefx".m1" +echo "m=$m" +n=$prefx".n1" +echo "n=$n" +erdep=$prefx".erosdep1" +echo "erdep=$erdep" +initsoil=$prefx".initsoil" + +echo "" +new_bdrk=$prefx"_new_bdrk1" +new_soil=$prefx"_new_soil1" +new_dem=$prefx"_new_dem1" +initsoil=$prefx"_initsoil" +echo "Initial soil depths calculated will be in $initsoil" +echo "The new dem for this iteration will be called $new_dem" +echo "The new bedrock elevation map for this iteration will be called $new_bdrk" +echo "The new soil depth map for this iteration will be called $new_soil" + +#let's grab the current resolution +res1=`eval g.region -p -m | grep "nsres:" | cut -d : -f 2` + +# we must set the region to the map being used. otherwise r.flow will not work +echo "" +echo "Setting region to $elev" +g.region rast=$elev + +#now lets show before: +echo "" +echo "Original Resolution = $res1" + +#...and after: +res=`eval g.region -p -m | grep "nsres:" | cut -d : -f 2` +echo "" +echo "New Resolution = $res" + +echo "" +step=$GIS_OPT_minyrs +maxyrs=$GIS_OPT_maxyrs +timestep=$GIS_OPT_number +echo "Iteration time step = $timestep years" +echo "Start year = $step BP" +echo "End year = $maxyrs BP" + +R=$Rprfx"_$step" +Cinit=$Cprfx"_$step" + +echo "" +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 "_____________________________________________________________" +# 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 +echo "" +echo "##################################################" +echo "##################################################" +echo "" +echo "TIME STEP $step YBP" +echo "" +echo "##################################################" +echo "" +echo "*************************" +echo "step 1 of 8: calculating slope and aspect (if initial aspect not specified)" +echo "*************************" +echo "" + + +r.slope.aspect --q $elev 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" + +r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp + +r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" + +g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" +rm -f /var/tmp/STREAM* + +else + +echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + +tmpflacc=$prefx".tmpflacc" + +r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc + +r.mapcalc "$flowacc=$tmpflacc*$res" + +g.remove --quiet rast=$tmpflacc + +fi + +echo "" +echo "*************************" +echo "step 3 of 8: calculating basic sediment transport rates"in +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 in0 ] +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.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` + + +echo "" +echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +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)))" + +report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` +report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` + +echo "" +echo "(for diagnostics only) max m = $report1, min m = $report2" + + +r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff, 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 * $Cinit * $sflowtopo * cos($aspect)))" +r.mapcalc "$qsy=if ("$initbdrk" >= "$elev", 0, ($R * $K * $Cinit * $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 fully 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 "$initsoil=$elev - $initbdrk" + +echo "" +echo "*************************" +echo "step 7 of 8: running band-pass filter" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_y" -eq 1 ]; then + +echo ""echo "You have selected not to smooth your files... Oh Well!" +echo "" + +r.mapcalc "$smoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" + +else + + +r.neighbors --quiet input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood +r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" +r.mapcalc "$smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" + +fi + +# create temporary file to code colors for $smoothdz +TMP1=`g.tempfile pid=$$` + +if [ $? -ne 0 ] || [ -z "$TMP1" ]; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +else + + echo "creating temporary file to code colors" + +fi + + +echo "0% 104 034 139" > $TMP1 +echo "-5 violet" >> $TMP1 +echo "-3 aqua" >> $TMP1 +echo "-1 cyan" >> $TMP1 +echo "-0.5 green" >> $TMP1 +echo "0 white" >> $TMP1 +echo "0.5 yellow" >> $TMP1 +echo "1 orange" >> $TMP1 +echo "3 red" >> $TMP1 +echo "5 255 000 255" $TMP1 +echo "100% 255 000 255" >> $TMP1 +echo "end" >> $TMP1 + + +cat $TMP1 | r.colors --q map=$smoothdz color=rules + +echo "" +echo "*************************" +echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" +echo "*************************" +echo "" + +r.mapcalc "$new_dem=$smoothdz + $elev" + +r.colors --q map=$new_dem rast=$elev + +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))" + + +#grabsomestats +tmperosion=$prfx"_tmperosion1" +tmpdep=$prfx"_tmpdep1" + +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 + +txtout=$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 "*************************" + + + +echo "" +echo "Raster map $smoothdz shows filtered net erosion/deposition" +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 "" +# echo "Done" +# echo "" +#else +# echo "" +# echo "Cleaning up..." +# g.remove rast=$flowacc,$slope,$aspect,$sflowtopo,$qsx,$qsy,$qsxdx,$qsydy,$erdep,$neighbors +# echo "" +# echo "Done" +#fi + + +#remove the temp files to avoid confusion...\rm -f $TMP1 $TMP1.sort + + + + +# now we must go into a loop to get the rest of the dem's + +while [ "$step" -lt "$maxyrs" ] +do + laststep=$step + step=$(($step+$timestep)) # here is how we are controlling the iteration loop + + +old_dem=$prefx"_new_dem"$laststep + +echo "The following temporary files will be created:" +echo "" +neighbors=$prefx".neighbors"$step +echo "neighbors=$neighbors" +tempsmoothdz=$prefx".tempsmoothdz"$step +echo "tempsmoothdz=$tempsmoothdz" +temp2smoothdz=$prefx".temp2smoothdz"$step +echo "temp2smoothdz=$temp2smoothdz" +smoothdz=$prefx"_smoothdz"$step +echo "smoothdz=$smoothdz" +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".m"$step +echo "m=$m" +n=$prefx".n"$step +echo "n=$n" +erdep=$prefx".erosdep"$step +echo "erdep=$erdep" +old_bdrk=$prefx"_new_bdrk"$laststep +echo "old_bdrk=$old_bdrk" +old_soil=$prefx"_new_soil"$laststep +echo "old_soil=$old_soil" +echo "" +R=$Rprfx"_$step" +C=$Cprfx"_$step" +new_bdrk=$prefx"_new_bdrk"$step +new_soil=$prefx"_new_soil"$step +new_dem=$prefx"_new_dem"$step +echo "The new dem for this iteration will be called $new_dem" +echo "The new bedrock elevation map for this iteration will be called $new_bdrk" +echo "The new soil depth map for this iteration will be called $new_soil" + +echo "" +echo "##################################################" +echo "##################################################" +echo "" +echo "TIME STEP $step YPB" +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" + +r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp + +r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" + +g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" +rm -f /var/tmp/STREAM* + +else + +echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + +tmpflacc=$prefx".tmpflacc" + +r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc + +r.mapcalc "$flowacc=$tmpflacc*$res" + +g.remove --quiet rast=$tmpflacc + +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),$m) * exp(sin($slope),$n)" + + +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.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` + + +echo "" +echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +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 "$sflowtopo=if ($flowacc >= $cutoff, 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 band-pass 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 + +r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood +r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $old_soil, (-1 * $old_soil), $erdep)" +r.mapcalc "$temp2smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" + +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 + + +# create temporary file to code colors for $smoothdz +TMP1=`g.tempfile pid=$$` + +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +else + echo "creating temporary file to code colors" + +fi + +echo "0% 104 034 139" > $TMP1 +echo "-5 violet" >> $TMP1 +echo "-3 aqua" >> $TMP1 +echo "-1 cyan" >> $TMP1 +echo "-0.5 green" >> $TMP1 +echo "0 white" >> $TMP1 +echo "0.5 yellow" >> $TMP1 +echo "1 orange" >> $TMP1 +echo "3 red" >> $TMP1 +echo "5 255 000 255" $TMP1 +echo "100% 255 000 255" >> $TMP1 +echo "end" >> $TMP1 + + +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" +r.colors --q map=$new_dem rast=$elev + +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))" + + + +#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 "Raster map $smoothdz shows filtered net erosion/deposition" +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 + + +# 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 + exit 1 +fi + + +g.mlist type=rast sep=, pattern=$prefx"_smoothdz*" > $TMP2 +liststring=`cat $TMP2` + +echo "Any selected statistics will be performed using the following smoothdz files: $liststring" + +if [ "$GIS_FLAG_c" -eq 1 ]; then + +r.series --q input=$liststring output=$prefx"_cum_erdep" method=sum +fi + +if [ "$GIS_FLAG_m" -eq 1 ]; then + +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 + +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 + + + +# 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 +fi + +g.mlist type=rast sep=, pattern=$prefx"_new_soil*" > $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_soil" method=average +fi + +if [ "$GIS_FLAG_v" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_sdev_soil" method=stddev +fi + +if [ "$GIS_FLAG_a" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_max_soil" method=maximum +fi + + +if [ "$GIS_FLAG_u" -eq 1 ]; then + +r.series --q input=$liststring2 output=$prefx"_min_soil" method=minimum +fi +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort + + +echo "************************" + +if [ "$GIS_FLAG_k" -eq 1 ]; then +echo "" +echo "Done" +echo "" + +else +echo "" +echo "Cleaning up..." +g.mremove -f --q rast=$prefx".neighbors*" +g.mremove -f --q rast=$prefx".smoothdz*" +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".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".m*" +g.mremove -f --q rast=$prefx".n*" + + echo "" + echo "Done" + +fi + +if [ "$GIS_FLAG_n" -eq 1 ]; then + + g.mremove --q rast=$prefx"_smoothdz*" +fi + +if [ "$GIS_FLAG_l" -eq 1 ]; then + + g.mremove --q rast=$prefx"_new_soil*" +fi + +if [ "$GIS_FLAG_z" -eq 1 ]; then +echo "" +echo "Iterations complete, keeping region set to output maps" +echo "" +else +echo "" +echo "Iterations complete, restoring default region settings" +echo "" + +g.region -d -g + +echo "" +fi +echo "###################################################" +echo "###################################################" +echo "___________________________________________________" +echo "" +echo " DONE WITH EVERYHTING" +echo "" +echo "___________________________________________________" + + + + Property changes on: trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr ___________________________________________________________________ Name: svn:executable + * Deleted: trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol 2007-07-06 22:34:55 UTC (rev 940) +++ trunk/grassaddons/LandDyn/r.landscape_evol/r.landscape.evol 2007-07-06 22:37:37 UTC (rev 941) @@ -1,1332 +0,0 @@ -#!/bin/sh -# -############################################################################ -# -# MODULE: r.landscape.evol -# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University -# Helena Mitasova, North Carolina State University -# PURPOSE: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net -# erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil -# depth maps. This module uses appropriate flow on different landforms by default; however, -# singular flow regimes can be chosen instead. -# ACKNOWLEDGEMENTS:National Science Foundation Grant #BCS0410269 -# Based on work of H. Mitasova and C. S. Thaxton, and Heimsath et al, 1997. -# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University -# This program is free software under the GNU General Public -# License (>=v2). Read the file COPYING that comes with GRASS -# for details. -# -############################################################################# - - -#%Module -#% description: Create raster maps of net erosion/depostion, the modified terrain surface (DEM) after net erosion/deposition using the USPED equation, bedrock elevations after soil production, and soil depth maps. This module uses appropriate flow on different landforms by default; however, singular flow regimes can be chosen instead. THIS SCRIPT WILL PRODUCE MANY TEMPORARY MAPS AND REQUIRES A LOT OF FREE FILE SPACE! -#%End - -#%option -#% key: elev -#% type: string -#% gisprompt: old,cell,raster -#% description: Input elevation map (DEM) -#% required : yes -#% guisection: Input -#%end -#%option -#% key: initbdrk -#% type: string -#% gisprompt: old,cell,raster -#% description: Initial bedrock elevations map (for first iteration only) -#% answer: -#% required : yes -#% guisection: Input -#%end -#%option -#% key: prefx -#% type: string -#% description: Prefix for all output maps -#% answer: usped -#% required : yes -#% 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 -#%end -#%flag -#% key: k -#% description: -k Keep all intermediate files as well -#% guisection: Input -#%end -#%flag -#% key: e -#% description: -e Keep initial soil depths map -#% guisection: Input -#%end -#%flag -#% key: z -#% description: -z Keep region zoomed to output maps -#% answer: 1 -#% guisection: Input -#%end -#%flag -#% key: b -#% description: -b Use static bedrock elavations (do not create new soil) -#% answer: 1 -#% guisection: Input -#%end - - -#%option -#% key: R -#% type: string -#% description: Rainfall (R factor) constant or map -#% gisprompt: old,cell,raster -#% answer: 5 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: K -#% type: string -#% gisprompt: old,cell,raster -#% description: Soil erodability index (K factor) map or constant -#% answer: 0.32 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: C -#% type: string -#% gisprompt: old,cell,raster -#% description: Landcover index (C factor) map or constant -#% answer: 0.01 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: kappa -#% type: string -#% gisprompt: old,cell,raster -#% description: Hillslope diffusion (Kappa) rate map or constant (meters per kiloyear) -#% answer: 1 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: cutoff -#% type: string -#% description: Flow accumultion breakpoint value for shift from diffusion to overland flow (number of cells) -#% answer: 8 -#% required : yes -#% guisection: Variables -#%end -#%option -#% key: number -#% type: integer -#% description: number of iterations to run -#% answer: 1 -#% required : yes -#% guisection: Variables -#%end - - -#these are commented out as we currently utilize the profile curvature method described by Heimsath et al... -# #%option -# #% key: Ba -# #% type: string -# #% description: Rate of average soil production (Ba) -# #% answer: 0.00008 -# #% required : yes -# #% guisection: Variables -# #%end -# #%option -# #% key: Bb -# #% type: string -# #% description: Relationship between soil depth and production rate (Bb) -# #% answer: 0.1 -# #% required : yes -# #% guisection: Variables -# #%end - -#%flag -#% key: y -#% description: -y Don't smooth the map (faster, but spikes in erosion/deposition may result) -#% guisection: Smoothing_Filter -#%end -#%option -#% key: nbhood -#% type: string -#% description: Band-pass filter neighborhood size -#% answer: 7 -#% options: 1,3,5,7,9,11,13,15,17,19,21,23,25 -#% 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 -#% description: Neighborhood smoothing method -#% answer: median -#% options: median,mode,average -#% required : yes -#% guisection: Smoothing_Filter -#%end - -#%flag -#% key: c -#% description: -c Output cumulative erosion/depostition map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: m -#% description: -m Output mean erosion/depostition map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: t -#% description: -t Output standard deviation of erosion/depostition map from data for all iterations -#% 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 -#%end -#%flag -#% key: v -#% description: -v Output standard deviation soil depths map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: a -#% description: -a Output maximum soil depths map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: u -#% description: -u Output minimum soil depths map from data for all iterations -#% guisection: Statistics -#%end - -#%flag -#% key: w -#% description: -w Calcuate for only sheetwash across entire map -#% guisection: Flow_type -#%end -#%flag -#% key: r -#% description: -r Calcuate for only channelized flow across entire map -#% guisection: Flow_type -#%end -#%flag -#% key: d -#% description: -d Calcuate for only diffusive flow (soil creep) across entire map -#% guisection: Flow_type -#%end -#%flag -#% key: f -#% description: -f Use r.terrflow instead of r.flow to calculate flow accumulation (better for massive grids) -#% guisection: Flow_type -#%end - - - -if [ -z "$GISBASE" ] ; then - echo "You must be in GRASS GIS to run this program." >&2 - exit 1 -fi - -if [ "$1" != "@ARGS_PARSED@" ] ; then - exec g.parser "$0" "$@" -fi - -prefx=$GIS_OPT_prefx -elev=$GIS_OPT_elev -initbdrk=$GIS_OPT_initbdrk -R=$GIS_OPT_R -K=$GIS_OPT_K -C=$GIS_OPT_C -kappa=$GIS_OPT_kappa -Ba=$GIS_OPT_Ba -Bb=$GIS_OPT_Bb -aplpha=$GIS_OPT_method -sigma=$GIS_OPT_sigma -nbhood=$GIS_OPT_nbhood -cutoff=$GIS_OPT_cutoff -number=$GIS_OPT_number -echo "total number of iterations to be run= $number" -echo "" - -if [ $number -eq 1 ] ; then - -num="" - -else - -num="1" - -fi - -echo "The following temporary files will be created:" -echo "" -neighbors=$prefx".neighbors"$num -echo "neighbors=$neighbors" -tempsmoothdz=$prefx".tempsmoothdz"$num -echo "tempsmoothdz=$tempsmoothdz" -smoothdz=$prefx"_smoothdz"$num -echo "smoothdz=$smoothdz" -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".m"$num -echo "m=$m" -n=$prefx".n"$num -echo "n=$n" -erdep=$prefx".erosdep"$num -echo "erdep=$erdep" - - - -echo "" - -new_soil=$prefx"_new_soil"$num -new_dem=$prefx"_new_dem"$num - -initsoil=$prefx"_initsoil" - - -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"_new_bdrk"$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` - -# we must set the region to the map being used. otherwise r.flow will not work -echo "" -echo "Setting region to $elev" -g.region rast=$elev - -#now lets show before: -echo "" -echo "Original Resolution = $res1" - -#...and after: -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 -echo "" -echo "##################################################" -echo "##################################################" -echo "" - -if [ $number -eq 1 ] ; then - -echo "STARTING SIMULATION" -echo "" -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 - -echo "" -echo "##################################################" -echo "" -echo "*************************" -echo "step 1 of 8: calculating slope and aspect (if initial aspect not specified)" -echo "*************************" -echo "" - - -r.slope.aspect --q $elev 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" - -r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=temp.flowacc tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp - -r.mapcalc "$flowacc=temp.flowacc/$res" - - -g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",temp.flowacc -rm -f /var/tmp/STREAM* - -else - -echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" - -tmpflacc=$prefx".tmpflacc" - -r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc - -r.mapcalc "$flowacc=$tmpflacc*$res" - -g.remove --quiet rast=$tmpflacc - -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.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` - -echo "" -echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " -echo "" - -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)))" - -report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` -report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` - -echo "" -echo "(for diagnostics only) max m = $report1, min m = $report2" - - -r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff, 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 fully 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 "$initsoil=$elev - $initbdrk" - -echo "" -echo "*************************" -echo "step 7 of 8: running band-pass filter" -echo "*************************" -echo "" - -if [ "$GIS_FLAG_y" -eq 1 ]; then - -echo ""echo "You have selected not to smooth your files... Oh Well!" -echo "" - -r.mapcalc "$smoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" - -else - - -r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood -r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" -r.mapcalc "$smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" - -fi - -#checking to see if we should keep the initial soil depths map - - - - -# create temporary file to code colors for $smoothdz -TMP1=`g.tempfile pid=$$` - - -if [ $? -ne 0 ] || [ -z "$TMP1" ]; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -else - - echo "creating temporary file to code colors" - -fi - - -echo "0% 104 034 139" > $TMP1 -echo "-5 violet" >> $TMP1 -echo "-3 aqua" >> $TMP1 -echo "-1 cyan" >> $TMP1 -echo "-0.5 green" >> $TMP1 -echo "0 white" >> $TMP1 -echo "0.5 yellow" >> $TMP1 -echo "1 orange" >> $TMP1 -echo "3 red" >> $TMP1 -echo "5 255 000 255" $TMP1 -echo "100% 255 000 255" >> $TMP1 -echo "end" >> $TMP1 - - -cat $TMP1 | r.colors --q map=$smoothdz color=rules - -echo "" -echo "*************************" -echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" -echo "*************************" -echo "" - -r.mapcalc "$new_dem=$smoothdz + $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" - - -new_bdrk=$initbdrk -r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" - -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))" - -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))" - -#grabsomestats -tmperosion=$prfx"_tmperosion1" -tmpdep=$prfx"_tmpdep1" - -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 - -txtout=$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 "Raster map $smoothdz shows filtered net erosion/deposition" -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 "" -# echo "Done" -# echo "" -#else -# echo "" -# echo "Cleaning up..." -# g.remove rast=$flowacc,$slope,$aspect,$sflowtopo,$qsx,$qsy,$qsxdx,$qsydy,$erdep,$neighbors -# echo "" -# echo "Done" -#fi - - -#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"_new_dem"$laststep - -echo "The following temporary files will be created:" -echo "" -neighbors=$prefx".neighbors"$step -echo "neighbors=$neighbors" -tempsmoothdz=$prefx".tempsmoothdz"$step -echo "tempsmoothdz=$tempsmoothdz" -temp2smoothdz=$prefx".temp2smoothdz"$step -echo "temp2smoothdz=$temp2smoothdz" -smoothdz=$prefx"_smoothdz"$step -echo "smoothdz=$smoothdz" -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".m"$step -echo "m=$m" -n=$prefx".n"$step -echo "n=$n" -erdep=$prefx".erosdep"$step -echo "erdep=$erdep" -old_bdrk=$prefx"_new_bdrk"$laststep -echo "old_bdrk=$old_bdrk" -old_soil=$prefx"_new_soil"$laststep -echo "old_soil=$old_soil" -echo "" - -new_soil=$prefx"_new_soil"$step -new_dem=$prefx"_new_dem"$step -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"_new_bdrk"$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" - -r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$prefx".tmpflacc" tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp - -r.mapcalc "$flowacc=$prefx".tmpflacc"/$res" - -g.remove --q rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$prefx".tmpflacc" -rm -f /var/tmp/STREAM* - -else - -echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" - -tmpflacc=$prefx".tmpflacc" -r.flow -3 --quiet elevin=$elev aspin=$aspect dsout=$tmpflacc - -r.mapcalc "$flowacc=$tmpflacc*$res" - -g.remove --quiet rast=$tmpflacc - -fi - - - -echo "" -echo "*************************" -echo "step 3 of 8: calculating basic sediment transport rates" -echo "*************************" -echo "" - - -initbdrk - -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),$m) * exp(sin($slope),$n)" - - -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.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` - - -echo "" -echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " -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 "$sflowtopo=if ($flowacc >= $cutoff, 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 band-pass 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 - -r.neighbors --q input=$erdep output=$neighbors method=$GIS_OPT_method size=$GIS_OPT_nbhood -r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $old_soil, (-1 * $old_soil), $erdep)" -r.mapcalc "$temp2smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" - -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 - - -# create temporary file to code colors for $smoothdz -TMP1=`g.tempfile pid=$$` - -if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -else - echo "creating temporary file to code colors" - -fi - -echo "0% 104 034 139" > $TMP1 -echo "-5 violet" >> $TMP1 -echo "-3 aqua" >> $TMP1 -echo "-1 cyan" >> $TMP1 -echo "-0.5 green" >> $TMP1 -echo "0 white" >> $TMP1 -echo "0.5 yellow" >> $TMP1 -echo "1 orange" >> $TMP1 -echo "3 red" >> $TMP1 -echo "5 255 000 255" $TMP1 -echo "100% 255 000 255" >> $TMP1 -echo "end" >> $TMP1 - - -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" -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" - - -new_bdrk=$old_bdrk -r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" - -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))" - -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))" - - -#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 "Raster map $smoothdz shows filtered net erosion/deposition" -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 - - -# 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 - exit 1 -fi - - -g.mlist type=rast sep=, pattern=$prefx"_smoothdz*" > $TMP2 -liststring=`cat $TMP2` - -echo "Any selected statistics will be performed using the following smoothdz files: $liststring" - -if [ "$GIS_FLAG_c" -eq 1 ]; then - -r.series --q input=$liststring output=$prefx"_cum_erdep" method=sum -fi - -if [ "$GIS_FLAG_m" -eq 1 ]; then - -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 - -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 - - - -# 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 -fi - -g.mlist type=rast sep=, pattern=$prefx"_new_soil*" > $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_soil" method=average -fi - -if [ "$GIS_FLAG_v" -eq 1 ]; then - -r.series --q input=$liststring2 output=$prefx"_sdev_soil" method=stddev -fi - -if [ "$GIS_FLAG_a" -eq 1 ]; then - -r.series --q input=$liststring2 output=$prefx"_max_soil" method=maximum -fi - - -if [ "$GIS_FLAG_u" -eq 1 ]; then - -r.series --q input=$liststring2 output=$prefx"_min_soil" method=minimum -fi -\rm -f $TMP2 $TMP2.sort -\rm -f $TMP3 $TMP3.sort - - -echo "************************" - -if [ "$GIS_FLAG_k" -eq 1 ]; then - -echo "" -echo "Done" -echo "" - -else - -echo "" -echo "Cleaning up..." - -g.mremove -f --q rast=$prefx".neighbors*" -g.mremove -f --q rast=$prefx".smoothdz*" -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".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".m*" -g.mremove -f --q rast=$prefx".n*" - - echo "" - echo "Done" - -fi - -if [ "$GIS_FLAG_n" -eq 1 ]; then - - g.mremove --q rast=$prefx"_smoothdz*" -fi - -if [ "$GIS_FLAG_l" -eq 1 ]; then - - g.mremove --q rast=$prefx"_new_soil*" -fi - -if [ "$GIS_FLAG_z" -eq 1 ]; then -echo "" -echo "Iterations complete, keeping region set to output maps" -echo "" -else -echo "" -echo "Iterations complete, restoring default region settings" -echo "" - -g.region -d -g - -echo "" -fi -echo "###################################################" -echo "###################################################" -echo "___________________________________________________" -echo "" -echo " DONE WITH EVERYHTING" -echo "" -echo "___________________________________________________" - - - - Added: trunk/grassaddons/LandDyn/r.nompast.area/r.nompast.area =================================================================== --- trunk/grassaddons/LandDyn/r.nompast.area/r.nompast.area (rev 0) +++ trunk/grassaddons/LandDyn/r.nompast.area/r.nompast.area 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,550 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.nompast.area +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a series of iterative landuse maps from a catchment +# created by r.catchment based on vegetational succession, herd ecology, and pastoral economics. +# This model holds the percentage of the catchment to be grazed constant and calculates the +# number of herd animals that can be supported by that area. Optionally outputs c factor as well +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a series of iterative landuse maps from a catchment created by r.catchment based on vegetational succession, herd ecology, and pastoral economics. This model holds the percentage of the catchment to be grazed constant and calculates the number of herd animals that can be supported by that area. Optionally outputs c factor as well +#%END + +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: Input catchment map (from r.catchment or r.buffer) +#% required : yes +#%END +#%option +#% key: inituse +#% type: string +#% gisprompt: old,cell,raster +#% description: Optional initial landscape (Coded 0-21. If no map specified, an initial landscape of value 21 (mature woodland) is used) +#% required : no +#%END +#%option +#% key: rand +#% type: integer +#% description: percent of area to be grazed in any year (to be used in r.random) +#% answer: 50 +#% required : yes +#%END +#%option +#% key: size +#% type: integer +#% description: size of grazing patches (set as resolution in g.region) +#% answer: 30 +#% required : yes +#%END +#%option +#% key: effect +#% type: integer +#% description: Intensity of grazing (amount by which landcover is decreased after grazing) +#% answer: 1 +#% options: 1,2,3,4,5 +#% required : yes +#%END +#%option +#% key: fbmas +#% type: integer +#% description: Average mature woodland edible biomass (kg/ha/year) +#% answer: 350 +#% required : yes +#%END +#%option +#% key: sbmas +#% type: integer +#% description: Average shrubland edible biomass (kg/ha/year) +#% answer: 200 +#% required : yes +#%END +#%option +#% key: gbmas +#% type: integer +#% description: Average grassland edible biomass (kg/ha/year) +#% answer: 100 +#% required : yes +#%END +#%option +#% key: gweight +#% type: integer +#% description: Average weight of forage one goat for one year (kg) +#% answer: 584 +#% required : yes +#%END +#%option +#% key: sweight +#% type: integer +#% description: Average weight of forage for one sheep for year (kg) +#% answer: 894 +#% required : yes +#%END +#%option +#% key: gratio +#% type: integer +#% description: ratio of goats to sheep (ie. enter 1 for 1 goat to n sheep) +#% answer: 1 +#% required : yes +#%END +#%option +#% key: sratio +#% type: integer +#% description: ratio of sheep to goats (ie. enter 1 for n goats to 1 sheep) +#% answer: 1 +#% required : yes +#%END +#%option +#% key: loop +#% type: integer +#% description: number of iterations ("years") to run +#% answer: 20 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% answer: landcover +#% required : yes +#%END +#%flag +#% key: l +#% description: -l Suppress output of C factor map (output landuse map only) +#%END +#%flag +#% key: f +#% description: -f Output maps of random grazing patches at each iteration as well +#%END +#%flag +#% key: s +#% description: -s Output text files of land-use stats from the simulation (one will be named "prefix"_luse_stats.txt, the other "prefix"_biomass.txt, and both will be overwritten if you run the simulation again with the same prefix) +#%END + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +fbmas=$GIS_OPT_fbmas +sbmas=$GIS_OPT_sbmas +gbmas=$GIS_OPT_gbmas + + + +: $(( a = ( $gbmas / 3 ) )) +: $(( b = ( 2 * ( $gbmas / 3 ) ) )) +: $(( c = ( 3 * ( $gbmas / 3 ) ) )) +d=$gbmas +: $(( e = ( $gbmas + ( ( $sbmas - $gbmas ) / 5 ) ) )) +: $(( f = ( $gbmas + ( 2 * ( ( $sbmas -$gbmas ) / 5 ) ) ) )) +: $(( g = ( $gbmas + ( 3 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +: $(( h = ( $gbmas + ( 4 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +: $(( i = ( $gbmas + ( 5 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +j=$sbmas +: $(( k = ( $sbmas + ( ( $fbmas - $sbmas ) / 11 ) ) )) +: $(( l = ( $sbmas + (2 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( m = ( $sbmas + (3 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( n = ( $sbmas + (4 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( o = ( $sbmas + (5 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( p = ( $sbmas + (6 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( q = ( $sbmas + (7 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( r = ( $sbmas + (8 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( s = ( $sbmas + (9 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( t = ( $sbmas + (10 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +u=$fbmas + +TMP3=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0 = 0 badly overgrazed" > $TMP3 +echo "1 = $a overgrazed" >> $TMP3 +echo "2 = $b sparse grassland" >> $TMP3 +echo "3 = $c moderate grassland" >> $TMP3 +echo "4 = $d grassland" >> $TMP3 +echo "5 = $e grass and sparse shrubs" >> $TMP3 +echo "6 = $f grass and shrubs" >> $TMP3 +echo "7 = $g mainly shrubs" >> $TMP3 +echo "8 = $h developing maquis" >> $TMP3 +echo "9 = $i moderate maquis" >> $TMP3 +echo "10 = $j maquis" >> $TMP3 +echo "11 = $k moderately dense maquis" >> $TMP3 +echo "12 = $l dense maquis" >> $TMP3 +echo "13 = $m maquis and small trees" >> $TMP3 +echo "14 = $n young woodland and maquis" >> $TMP3 +echo "15 = $o mostly young open woodland" >> $TMP3 +echo "16 = $p young open woodland" >> $TMP3 +echo "17 = $q moderate open woodland" >> $TMP3 +echo "18 = $r maturing and moderate open woodland" >> $TMP3 +echo "19 = $s maturing open woodland" >> $TMP3 +echo "20 = $t mostly matured open woodland" >> $TMP3 +echo "21 = $u fully matured woodland" >> $TMP3 +echo "end" >> $TMP3 + + +TMP2=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0 grey" > $TMP2 +echo "$gbmas brown" >> $TMP2 +echo "$sbmas yellow" >> $TMP2 +echo "$fbmas green" >> $TMP2 +echo "end" >> $TMP2 + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0:1:0.5:0.5" > $TMP4 +echo "2:5:0.10:0.10" >> $TMP4 +echo "6:9:0.15:0.15" >> $TMP4 +echo "10:13:0.18:0.18" >> $TMP4 +echo "13:16:0.08:0.08" >> $TMP4 +echo "17:20:0.06:0.06" >> $TMP4 +echo "21:21:0.05:0.05" >> $TMP4 +echo "end" >> $TMP4 + +TMP5=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0.5 grey" > $TMP5 +echo "0.6 grey" >> $TMP5 +echo "0.19 brown" >> $TMP5 +echo "0.17 brown" >> $TMP5 +echo "0.10 yellow" >> $TMP5 +echo "0.05 green" >> $TMP5 +echo "end" >> $TMP5 + + + +echo "" +echo "*************************" +echo "step 1 of 4: Calculating MASK" +echo "*************************" +echo "" + + +r.mask input=$inmap maskcats=* + + + +echo "" +echo "*************************" +echo "step 2 of 4: Changing resolution to field size (will be reset)" +echo "*************************" +echo "" + +g.region save=temp_region +size=$GIS_OPT_size +g.region res=$size + + + +echo "" +echo "*************************" +echo "step 3 of 4: Sarting land use evolution calculation. This will start a loop and may take some time. Please do not interrupt the process until it has finished" +echo "*************************" +echo "" + + +echo "iteration 1" +echo "" + + + +inmap=$GIS_OPT_inmap +rand=$GIS_OPT_rand +loop=$GIS_OPT_loop +effect=$GIS_OPT_effect +prfx=$GIS_OPT_prfx +temp1=$prfx"_tmp1" +timer=$prfx"_timer1" +patches=$prfx"_patches1" +tmplus=$prfx"temp_landuse1" +lus=$prfx"_landuse1" +tmpinreclass=$prfx"_tmpinreclass" + +gweight=$GIS_OPT_gweight +sweight=$GIS_OPT_sweight +gratio=$GIS_OPT_gratio +sratio=$GIS_OPT_sratio + +inituse=$GIS_OPT_inituse + +txtout=$prfx"_luse_stats.txt" +txtout2=$prfx"_biomass.txt" + + +r.mapcalc "$tmpinreclass = if ($inmap, 1, null())" + +r.random --q input=$tmpinreclass n=$rand"%" raster_output=$patches + +if [ "$GIS_FLAG_f" -eq 1 ]; then + + echo "grazing patches map = $patches" + + fi + + +if [ -n "$GIS_OPT_inituse" ]; then + + +r.mapcalc "$timer= if (isnull($patches) && $inituse <= 20, $inituse + 1, (if(isnull($patches), 21, (if ($inituse < $effect, 0, $inituse - $effect)))))" + + +else + + +r.mapcalc "$timer = if (isnull($patches), 21, 21-$effect)" + + +fi + + + cat $TMP3 | r.reclass --q input=$timer output=$tmplus + +r.mapcalc "$lus = $tmplus" + + cat $TMP2 | r.colors --q map=$lus color=rules + + cat $TMP4 | r.recode --q input=$timer output=$prfx"_cfactor1" + + cat $TMP5 | r.colors --q map=$prfx"_cfactor1" color=rules + +r.mapcalc "$temp1=if(isnull($patches), null(), $lus)" +tempbmas=`eval r.sum rast=$temp1 | cut -d'.' -f1` + + temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2 | cut -d'.' -f1` + +: $(( bmas = ( ( ( $temparea / 100000000 ) * $tempbmas ) / 34 ) )) +# in above equation, .34 is an "efficiency factor" that is used to modify the total standing biomass to consumable biomas, and is derived from field sudies done by rangeland scientists + +: $(( efkg = ( ( ($sratio * $sweight) + ( $gratio * $gweight) ) / 2 ) )) + +: $(( ebmas = ($bmas / ( 5 + ( $effect + ( 9 / 4 ) ) ) ) )) + +: $(( num = ( $ebmas / $efkg ) )) + + echo "" + echo "Area of new randomized grazing patches = $temparea square meters" + echo "" + echo "Total amount of effective biomass available for grazing this year = $bmas" + echo "" + echo "Average fodder consumption of herd per animal = $efkg" + echo "" + echo "Total amount of forage grazed this year = $ebmas" + echo "" + echo "Total number of herd animals supported this year = $num" + echo "" +echo "***********************" + + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "Stats for $loop years of grazing at $rand% randomized grazing of the landscape in $size meter square patches" > $txtout +echo "" >> $txtout +echo "Year 1:" >> $txtout +echo "" >> $txtout +echo "Average biomass production (kg/ha/year),Landcover description,Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$prfx"_landuse1" fs=, nv=* nsteps=255 >> $txtout + +echo "Biomass amounts for $loop years of grazing at $rand% randomized grazing of the landscape in $size meter square patches with a $gratio to $sratio goat/sheep ratio where goats need $gweight kg/year of fodder and sheep need $sweight kg/year of fodder with an average of $efkg kg/year per herd animal. " > $txtout2 +echo "" >> $txtout2 +echo "Year,Total area grazed (sq. m),Total available fodder,Total fodder actually grazed,Number of herd animals supported,Difference from last year's herdsize" >> $txtout2 +echo "" >> $txtout2 +echo "1,$temparea,$bmas,$ebmas,$num,'n/a'" >> $txtout2 +fi + +g.remove --q rast=$temp1 + +step=1 + + +while [ "$step" -lt "$loop" ] +do + step=$(($step+1)) + echo "iteration $step" + laststep=$(($step-1)) + + + + outcfactor=$prfx"_cfactor"$step + tmplanduse=$prfx"temp_landuse"$step + outlanduse=$prfx"_landuse"$step + outpatches=$prfx"_patches"$step + temp=$prfx"_tmp"$step + newtimer=$prfx"_timer"$step + oldtimer=$prfx"_timer"$laststep + + +r.random --q input=$tmpinreclass n=$rand"%" raster_output=$outpatches + + if [ "$GIS_FLAG_f" -eq 1 ]; then + + echo "grazing patches map = $outpatches" + + fi + +r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 20, $oldtimer + 1, (if(isnull($outpatches), 21, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" + + + + cat $TMP3 | r.reclass --q input=$newtimer output=$tmplanduse + + r.mapcalc "$outlanduse = $tmplanduse" + + cat $TMP2 | r.colors --q map=$outlanduse color=rules + + cat $TMP4 | r.recode --q input=$newtimer output=$outcfactor + + cat $TMP5 | r.colors --q map=$outcfactor color=rules + +r.mapcalc "$temp=if(isnull($patches), null(), $outlanduse)" +tempbmas=`eval r.sum rast=$temp | cut -d'.' -f1` + + temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2 | cut -d'.' -f1` + +: $(( bmas = ( ( ( $temparea / 100000000 ) * $tempbmas ) / 34 ) )) +# in above equation, .34 is an "efficiency factor" that is used to modify the total standing biomass to consumable biomas, and is derived from field sudies done by rangeland scientists + +: $(( efkg = ( ( ($sratio * $sweight) + ( $gratio * $gweight) ) / 2 ) )) + +: $(( ebmas = ($bmas / ( 5 + ( $effect + ( 9 / 4 ) ) ) ) )) + +oldnum=$num + +: $(( num = ( $ebmas / $efkg ) )) + +: $(( dif = ($num - $oldnum) )) + + echo "" + echo "Area of new randomized grazing patches = $temparea square meters" + echo "" + echo "Total amount of effective biomass available for grazing this year = $bmas" + echo "" + echo "Average fodder consumption of herd per animal = $efkg" + echo "" + echo "Total amount of forage grazed this year = $ebmas" + echo "" + echo "Total number of herd animals supported this year = $num" + echo "" + echo "Difference from herdsize last year = $dif" + echo "" +echo "************************" +echo "" + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "" >> $txtout +echo "Year $step:" >> $txtout +echo "" >> $txtout +echo "Average biomass production (kg/year), Landcover description, Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$outlanduse fs=, nv=* nsteps=255 >> $txtout + +echo "$step,$temparea,$bmas,$ebmas,$num,$dif" >> $txtout2 + + +fi + +done + + +echo "" +echo "*************************" +echo "step 4 of 4: Cleaning up" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --q rast=$prfx"temp_landuse*" +g.mremove -f --q rast=$prfx"_cfactor*" +g.mremove -f --q rast=$prfx"_timer*" +g.mremove -f --q rast=$prfx"_tmpinreclass*" +g.mremove -f --q rast=$prfx"_tmp*" +g.remove --q rast=MASK + +elif [ "$GIS_FLAG_f" -eq 0 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --q rast=$prfx"_patches*" +g.mremove -f --q rast=$prfx"temp_landuse*" +g.mremove -f --q rast=$prfx"_cfactor*" +g.mremove -f --q rast=$prfx"_timer*" +g.mremove -f --q rast=$prfx"_tmpinreclass*" +g.mremove -f --q rast=$prfx"_tmp*" +g.remove --q rast=MASK + +elif [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 0 ] ; then + +g.remove --q rast=MASK +g.mremove -f --q rast=$prefx"temp_landuse*" +g.mremove -f --q rast=$prfx"_timer*" +g.mremove -f --q rast=$prfx"_tmpinreclass*" +g.mremove -f --q rast=$prfx"_tmp*" +else + + +g.mremove -f --q rast=$prfx"_patches*" +g.mremove -f --q rast=$prfx"temp_landuse*" +g.remove --q rast=MASK +g.mremove -f --q rast=$prfx"_timer*" +g.mremove -f --q rast=$prfx"_tmpinreclass*" +g.mremove -f --q rast=$prfx"_tmp*" + +fi + + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort +\rm -f $TMP5 $TMP5.sort + + +echo "" +echo "Resetting region" +echo "" + +g.region -g region=temp_region +g.remove --q region=temp_region + + +echo "" +echo "DONE!" +echo "" +echo "" + + Property changes on: trunk/grassaddons/LandDyn/r.nompast.area/r.nompast.area ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.nompast.num/r.nompast.num =================================================================== --- trunk/grassaddons/LandDyn/r.nompast.num/r.nompast.num (rev 0) +++ trunk/grassaddons/LandDyn/r.nompast.num/r.nompast.num 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,783 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.nompast.num +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a series of iterative landuse maps from a catchment +# created by r.catchment based on vegetational succession, herd ecology, and pastoral economics. +# This model holds the number of herd animals constant and calculates the area needed to support +# that number of animals. Optionally outputs c factor as well. +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a series of iterative landuse maps from a catchment created by r.catchment based on vegetational succession, herd ecology, and pastoral economics. This model holds the number of herd animals constant and calculates the area needed to support that number of animals.Optionally outputs c factor as well +#%END +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: Input catchment map (from r.catchment or r.buffer) +#% required : yes +#%END +#%option +#% key: inituse +#% type: string +#% gisprompt: old,cell,raster +#% description: Optional initial landscape (Coded 0-21. If no map specified, an initial landscape of value 21 (mature woodland) is used) +#% required : no +#%END +#%option +#% key: size +#% type: integer +#% description: size of grazing patches (to be used in g.region) +#% answer: 30 +#% required : yes +#%END +#%option +#% key: effect +#% type: integer +#% description: Intensity of grazing (amount by which landcover is decreased after grazing) +#% answer: 1 +#% options: 1,2,3,4,5 +#% required : yes +#%END +#%option +#% key: fbmas +#% type: integer +#% description: Average mature woodland edible biomass (kg/ha/year) +#% answer: 350 +#% required : yes +#%END +#%option +#% key: sbmas +#% type: integer +#% description: Average shrubland edible biomass (kg/ha/year) +#% answer: 200 +#% required : yes +#%END +#%option +#% key: gbmas +#% type: integer +#% description: Average grassland edible biomass (kg/ha/year) +#% answer: 100 +#% required : yes +#%END +#%option +#% key: gweight +#% type: integer +#% description: Average weight of forage one goat for one year (kg) +#% answer: 584 +#% required : yes +#%END +#%option +#% key: sweight +#% type: integer +#% description: Average weight of forage for one sheep for year (kg) +#% answer: 894 +#% required : yes +#%END +#%option +#% key: number +#% type: integer +#% description: Number of herd animals you wish to have graze +#% answer: 30 +#% required : yes +#%END +#%option +#% key: gratio +#% type: integer +#% description: ratio of goats to sheep (ie. enter 1 for 1 goat to n sheep) +#% answer: 1 +#% required : yes +#%END +#%option +#% key: sratio +#% type: integer +#% description: ratio of sheep to goats (ie. enter 1 for n goats to 1 sheep) +#% answer: 1 +#% required : yes +#%END +#%option +#% key: loop +#% type: integer +#% description: number of iterations ("years") to run +#% answer: 20 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% answer: nompast_herdnum +#% required : yes +#%END +#%flag +#% key: l +#% description: -l Suppress output of C factor map (output landuse map only) +#% answer: 1 +#%END +#%flag +#% key: f +#% description: -f Output maps of random grazing patches at each iteration as well +#%END +#%flag +#% key: s +#% description: -s Output text files of land-use stats from the simulation (one will be named "prefix"_luse_stats.txt, the other "prefix"_biomass.txt, and both will be overwritten if you run the simulation again with the same prefix) +#%END + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +fbmas=$GIS_OPT_fbmas +sbmas=$GIS_OPT_sbmas +gbmas=$GIS_OPT_gbmas + +#below we are setting up our succession sequence for a mediterranean environment... The absolute richness of the environment is controlled by the "biomass" input values for the three main stages of floristic growth (grassland, shrubland, and woodland), the values of which can be found in the ecological or rangeland science literature for specific mediterranean landscapes. All other stages are interpolated between the main three via linear regression. The number of main stages of a twenty year succession will need to be modified for other environments (and perhaps the twenty year time-limit should be expanded or contracted as well), as opposed to just changing the starting biomass values if one really wishes to model accurate succession in a non-mediterranean environment + +: $(( a = ( $gbmas / 3 ) )) +: $(( b = ( 2 * ( $gbmas / 3 ) ) )) +: $(( c = ( 3 * ( $gbmas / 3 ) ) )) +d=$gbmas +: $(( e = ( $gbmas + ( ( $sbmas - $gbmas ) / 5 ) ) )) +: $(( f = ( $gbmas + ( 2 * ( ( $sbmas -$gbmas ) / 5 ) ) ) )) +: $(( g = ( $gbmas + ( 3 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +: $(( h = ( $gbmas + ( 4 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +: $(( i = ( $gbmas + ( 5 * ( ( $sbmas - $gbmas ) / 5 ) ) ) )) +j=$sbmas +: $(( k = ( $sbmas + ( ( $fbmas - $sbmas ) / 11 ) ) )) +: $(( l = ( $sbmas + (2 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( m = ( $sbmas + (3 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( n = ( $sbmas + (4 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( o = ( $sbmas + (5 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( p = ( $sbmas + (6 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( q = ( $sbmas + (7 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( r = ( $sbmas + (8 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( s = ( $sbmas + (9 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +: $(( t = ( $sbmas + (10 * ( ( $fbmas - $sbmas ) / 11 ) ) ) )) +u=$fbmas + +TMP3=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +# now we take our biomass numbers calculated above and shove them into a temp file that we will use to reclass our timer maps into landcover maps later on + +echo "0 = 0 badly overgrazed" > $TMP3 +echo "1 = $a overgrazed" >> $TMP3 +echo "2 = $b sparse grassland" >> $TMP3 +echo "3 = $c moderate grassland" >> $TMP3 +echo "4 = $d grassland" >> $TMP3 +echo "5 = $e grass and sparse shrubs" >> $TMP3 +echo "6 = $f grass and shrubs" >> $TMP3 +echo "7 = $g mainly shrubs" >> $TMP3 +echo "8 = $h developing maquis" >> $TMP3 +echo "9 = $i moderate maquis" >> $TMP3 +echo "10 = $j maquis" >> $TMP3 +echo "11 = $k moderately dense maquis" >> $TMP3 +echo "12 = $l dense maquis" >> $TMP3 +echo "13 = $m maquis and small trees" >> $TMP3 +echo "14 = $n young woodland and maquis" >> $TMP3 +echo "15 = $o mostly young open woodland" >> $TMP3 +echo "16 = $p young open woodland" >> $TMP3 +echo "17 = $q moderate open woodland" >> $TMP3 +echo "18 = $r maturing and moderate open woodland" >> $TMP3 +echo "19 = $s maturing open woodland" >> $TMP3 +echo "20 = $t mostly matured open woodland" >> $TMP3 +echo "21 = $u fully matured woodland" >> $TMP3 +echo "end" >> $TMP3 + + +TMP2=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +# this creates a tempfile with color values for the output landcover maps + +echo "0 grey" > $TMP2 +echo "$gbmas brown" >> $TMP2 +echo "$sbmas yellow" >> $TMP2 +echo "$fbmas green" >> $TMP2 +echo "end" >> $TMP2 + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +# this creates a tempfile to recode our timer maps into c-factor maps later on + +echo "0:1:0.5:0.5" > $TMP4 +echo "2:5:0.10:0.10" >> $TMP4 +echo "6:9:0.15:0.15" >> $TMP4 +echo "10:13:0.18:0.18" >> $TMP4 +echo "13:16:0.08:0.08" >> $TMP4 +echo "17:20:0.06:0.06" >> $TMP4 +echo "21:21:0.05:0.05" >> $TMP4 +echo "end" >> $TMP4 + +TMP5=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +# this creates a tempfile to color our c-factor maps later on + +echo "0.5 grey" > $TMP5 +echo "0.6 grey" >> $TMP5 +echo "0.19 brown" >> $TMP5 +echo "0.17 brown" >> $TMP5 +echo "0.10 yellow" >> $TMP5 +echo "0.05 green" >> $TMP5 +echo "end" >> $TMP5 + + + +echo "" +echo "*************************" +echo "step 1 of 4: Calculating MASK" +echo "*************************" +echo "" + +if [ -n "MASK" ]; then +g.remove --q rast=MASK +fi + +inmap=$GIS_OPT_inmap +r.mask input=$inmap maskcats=* + + + +echo "" +echo "*************************" +echo "step 2 of 4: Changing resolution to field size (will be reset)" +echo "*************************" +echo "" + +if [ -n "temp_region" ]; then +g.remove --q region=temp_region +fi +g.region save=temp_region +size=$GIS_OPT_size +g.region res=$size + + + +echo "" +echo "*************************" +echo "step 3 of 4: Sarting land use evolution calculation. This will start a loop and may take some time. Please do not interrupt the process until it has finished" +echo "*************************" +echo "" + +d.mon start=x0 +d.monsize --quiet setmonitor=x0 setwidth=1000 setheight=750 + +d.frame -c -s frame=f1 at=0,100,0,60 +echo "Current Landcover" | d.text -b size=3 color=black at=1,1 rotation=0 + +d.frame -c -s frame=f2 at=50,100,64,100 + +d.frame -c -s frame=f3 at=0,100,61,63 + +d.frame -c -s frame=f4 at=0,48,64,100 + +d.frame -c -s frame=f5 at=48,50,64,100 + + +echo "Model Year 1" +echo "" + + +number=$GIS_OPT_number +loop=$GIS_OPT_loop +effect=$GIS_OPT_effect +prfx=$GIS_OPT_prfx +temp1=$prfx"_tmp1" +timer=$prfx"_timer1" +patches=$prfx"_patches1" +tmplus=$prfx"temp_landuse1" +lus=$prfx"_landuse1" +tmpinreclass=$prfx"_tmpinreclass" + +gweight=$GIS_OPT_gweight +sweight=$GIS_OPT_sweight +gratio=$GIS_OPT_gratio +sratio=$GIS_OPT_sratio + +txtout=$prfx"_landcover_stats.txt" +txtout2=$prfx"_landuse_stats.txt" + +inituse=$GIS_OPT_inituse + +r.mapcalc "$tmpinreclass = if ($inmap, 1, null())" + + + +rand=1 #setting up loop + + while [ "$rand" -le 100 ] + do + +echo "testing grazing at $rand percent" + +randpatches=$patches"_"$rand + +#randomly sampling our catchment in increasing percentages + +r.random --q input=$tmpinreclass n=$rand"%" raster_output=$randpatches + +#creating a "timer" map that keeps track of successional values + +if [ -n "$GIS_OPT_inituse" ]; then + +r.mapcalc "$timer= if (isnull($randpatches) && $inituse <= 20, $inituse + 1, (if(isnull($randpatches), 21, (if ($inituse < $effect, 0, $inituse - $effect)))))" + +else + +r.mapcalc "$timer = if (isnull($randpatches), 21, 21-$effect)" + +fi + +#creating landcover map from timer map + + cat $TMP3 | r.reclass --q input=$timer output=$tmplus + +r.mapcalc "$lus = $tmplus" +g.remove --q rast=$tmplus + + cat $TMP2 | r.colors --q map=$lus color=rules + +d.frame -s frame=f2 +d.rast map=$lus +d.barscale bcolor=none tcolor=black at=0.0,0.0 +d.frame -s frame=f5 +d.erase +echo "new model randomization: $rand% grazed" | d.text size=90 color=black at=10,15 + + + +#creating and then removing a temp map to calculate total biomass available to herd animals + +r.mapcalc "$temp1=if(isnull($randpatches), null(), $lus)" + + tempbmas=`eval r.sum --q rast=$temp1 | cut -d'.' -f1` + +g.remove --q rast=$temp1 + +#finding the total area of all the randomly picked grazing patches combined +#commenting out following formula, will now use r.sum to get the area +#temparea=`eval r.stats --q -n -a fs=- input=$randpatches | cut -d'-' -f2 | cut -d'.' -f1` + +tempsum=`eval r.sum --q rast=$randpatches | cut -d'.' -f1` +: $(( ( temparea = $tempsum * $size ) )) + +#now we run through some equations to discover the affects of this year's simulation on our landscape and our herd population + + +: $(( bmas = ( ( ( $temparea / 100000000 ) * $tempbmas ) / 34 ) )) +# in above equation, .34 is an "efficiency factor" that is used to modify the total standing biomass to consumable biomass for mixed browse/graze rangelands (averaged from the values for each of those types), and is derived from field sudies done by rangeland scientists (because we can't use decimles in BASH math, I divide by 34 instead of multiplying by .34) + +: $(( efkg = ( ( ($sratio * $sweight) + ( $gratio * $gweight) ) / 2 ) )) + +: $(( ebmas = ($bmas / ( 5 + ( $effect + ( 9 / 4 ) ) ) ) )) + +: $(( num = ( $ebmas / $efkg ) )) + + if [ "$num" -ge "$number" ] + then + break # Skip entire rest of loop. + fi + +rand=$(($rand+1)) #controlling loop + + done + + +d.frame -s frame=f2 +d.erase +d.frame -s frame=f1 +d.erase +d.rast map=$lus +echo "Current Landcover (1 Year)" | d.text -b size=3 color=black at=1,1 rotation=0 +d.barscale bcolor=none tcolor=black at=0.0,0.0 +d.frame -s frame=f3 +d.erase +d.legend -c -v -s map=$lus color=black lines=21 thin=1 labelnum=21 at=98,2,1,100 + + +if [ "$num" -lt "$number" ]; then + + echo "" + echo "Percent of land grazed this year = $rand" + echo "" + echo "Area of new randomized grazing patches needed to support $number animals = $temparea square meters" + echo "" + echo "Total amount of effective biomass available for grazing this year = $bmas" + echo "" + echo "Average fodder consumption of herd per animal = $efkg" + echo "" + echo "Total amount of forage grazed this year = $ebmas" + echo "" +echo "************************************************************************" +echo "" +echo "Herd size not supported by total use of catchment's landscape!!!!!!" +echo "Ending simulation with total herd size of $num herd animals at year 1" + + echo "" >> $txtout + echo "Year 1: herd number not supported! Ending simulation" >> $txtout + echo "" >> $txtout2 + echo "Herd number not supported by Year 1! Ending simulation" >> $txtout2 + + + +break # Skip entire rest of module. + +fi + +if [ "$GIS_FLAG_f" -eq 1 ]; then + + g.rename --q rast=$randpatches,$patches + echo "grazing patches map = $patches" + + fi + +g.mremove -f --quiet rast=$patches"_*" + + cat $TMP4 | r.recode --q input=$timer output=$prfx"_cfactor1" + + cat $TMP5 | r.colors --q map=$prfx"_cfactor1" color=rules + + + +d.frame -s frame=f4 +echo "Year 1" | d.text -b size=5 color=black at=2,10 +echo "" +echo "Percent of land grazed = $rand" | d.text size=3 color=black at=2,20 +echo "" +echo "Area of grazed patches = $temparea sq m" | d.text size=3 color=black at=2,30 +echo "" +echo "Number of herd animals supported = $number" | d.text size=3 color=black at=2,40 +echo "" +echo "Total amount of biomass available this year = $bmas" | d.text size=3 color=black at=2,50 +echo "" +echo "Average fodder consumption of herd per animal = $efkg" | d.text size=3 color=black at=2,60 +echo "" +echo "Total amount of forage grazed this year = $ebmas" | d.text size=3 color=black at=2,70 +echo "" +echo "***********************" + +#below is output for text files of stats from this model run + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "General landcover stats for $loop years of grazing $num herd animals on the landscape in $size meter square patches" > $txtout +echo "" >> $txtout +echo "Year 1:" >> $txtout +echo "" >> $txtout +echo "Average biomass production (kg/ha/year),Landcover description,Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$prfx"_landuse1" fs=, nv=* nsteps=255 >> $txtout + +echo "Biomass amounts for $loop years of grazing $number herd animals on the landscape in $size meter square patches with a $gratio to $sratio goat/sheep ratio where goats need $gweight kg/year of fodder and sheep need $sweight kg/year of fodder with an average of $efkg kg/year per herd animal. " > $txtout2 +echo "" >> $txtout2 +echo "Year,Percent of catchment grazed,Total area grazed (sq. m),Total available fodder,Total fodder actually grazed,Difference from last year's grazing extent (sq m)" >> $txtout2 +echo "" >> $txtout2 +echo "1,$rand,$temparea,$bmas,$ebmas,0" >> $txtout2 +fi + + + + + +step=2 #set up for outer loop + + +while [ "$step" -le "$loop" ] +do + + echo "Model Year $step" + laststep=$(($step-1)) #control for some comparisons with output from last iteration + + outcfactor=$prfx"_cfactor"$step + tmplanduse=$prfx"temp_landuse"$step + outlanduse=$prfx"_landuse"$step + outpatches=$prfx"_patches"$step + temp=$prfx"_tmp"$step + newtimer=$prfx"_timer"$step + oldtimer=$prfx"_timer"$laststep + +oldarea=$temparea +rand=1 #set up for inner loop + + + + while [ "$rand" -le 100 ] + do + +echo "testing grazing at $rand percent" + +randpatches=$outpatches"_"$rand + +#randomly sampling our catchment in increasing percentages + +r.random --q input=$tmpinreclass n=$rand"%" raster_output=$randpatches + +#modifying "timer" map with new data on landuse for this year + +r.mapcalc "$newtimer= if (isnull($randpatches) && $oldtimer <= 20, $oldtimer + 1, (if(isnull($randpatches), 21, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" + +#creating landcover map from timer map + + cat $TMP3 | r.reclass --q input=$newtimer output=$tmplanduse + +r.mapcalc "$outlanduse = $tmplanduse" +g.remove --q rast=$tmplanduse + + cat $TMP2 | r.colors --q map=$outlanduse color=rules + +d.frame -s frame=f2 +d.rast map=$outlanduse +d.barscale bcolor=none tcolor=black at=0.0,0.0 +d.frame -s frame=f5 +d.erase +echo "new model randomization: $rand% grazed" | d.text size=90 color=black at=10,15 + + + +#creating and then removing a temp map to calculate total biomass available to herd animals + +r.mapcalc "$temp=if(isnull($randpatches), null(), $outlanduse)" + + tempbmas=`eval r.sum --q rast=$temp | cut -d'.' -f1` + +g.remove --q rast=$temp + +#finding the total area of all the randomly picked grazing patches combined +#commenting out following formula. Will now use r.sum to get the area +# temparea=`eval r.stats --q -n -a fs=- input=$randpatches | cut -d'-' -f2 | cut -d'.' -f1` + +tempsum=`eval r.sum --q rast=$randpatches | cut -d'.' -f1` +: $(( ( temparea = $tempsum * $size ) )) + +#now we run through some equations to discover the affects of this year's simulation on our landscape and our herd population + +: $(( bmas = ( ( ( $temparea / 100000000 ) * $tempbmas ) / 34 ) )) +# in above equation, .34 is an "efficiency factor" that is used to modify the total standing biomass to consumable biomass for mixed browse/graze rangelands (averaged from the values for each of those types), and is derived from field sudies done by rangeland scientists (because we can't use decimles in BASH math, I divide by 34 instead of multiplying by .34) + +: $(( efkg = ( ( ($sratio * $sweight) + ( $gratio * $gweight) ) / 2 ) )) + +: $(( ebmas = ($bmas / ( 5 + ( $effect + ( 9 / 4 ) ) ) ) )) + + +: $(( num = ( $ebmas / $efkg ) )) + +: $(( dif = ($temparea - $oldarea) )) + + + + + if [ "$num" -ge "$number" ] + then + break # Skip entire rest of loop. + fi + + + rand=$(($rand+1)) #controlling inner loop + + + done + +d.frame -s frame=f2 +d.erase +d.frame -s frame=f1 +d.erase +d.rast map=$outlanduse +echo "Current Landcover ($step Years)" | d.text -b size=3 color=black at=1,1 rotation=0 +d.barscale bcolor=none tcolor=black at=0.0,0.0 +d.frame -s frame=f3 +d.erase +d.legend -c -v -s map=$outlanduse color=black lines=21 thin=1 labelnum=21 at=98,2,1,100 + +if [ "$num" -lt "$number" ]; then + + echo "" + echo "Percent of land grazed this year = $rand" + echo "" + echo "Area of new randomized grazing patches needed to support $num animals = $temparea square meters" + echo "" + echo "Total amount of effective biomass available for grazing this year = $bmas" + echo "" + echo "Average fodder consumption of herd per animal = $efkg" + echo "" + echo "Total amount of forage grazed this year = $ebmas" + echo "" + echo "Total number of herd animals supported this year = $num" + echo "" + echo "Difference from grazed area last year = $dif" + echo "" +echo "************************************************************************" +echo "" +echo "Herd size not supported by total use of catchment's landscape!!!!!!" +echo "Ending simulation with total herd size of $num herd animals at year $step" +echo "Try again with lower number of herd animals" + + + echo "" >> $txtout + echo "Year $step: herd number not supported! Ending simulation" >> $txtout + echo "" >> $txtout2 + echo "Herd number not supported by Year $step! Ending simulation" >> $txtout2 + + +break # Skip entire rest of module. + + +fi + + step=$(($step+1)) #controlling outer loop + + + if [ "$GIS_FLAG_f" -eq 1 ]; then + + g.rename --q rast=$randpatches,$outpatches + echo "grazing patches map = $outpatches" + + fi + + +g.mremove -f --quiet rast=$outpatches"_*" + + + cat $TMP2 | r.colors --q map=$outlanduse color=rules + + cat $TMP4 | r.recode --q input=$newtimer output=$outcfactor + + cat $TMP5 | r.colors --q map=$outcfactor color=rules + +d.frame -s frame=f4 +d.erase +echo "Year $step" | d.text -b size=5 color=black at=2,10 + echo "" +echo "Percent of land grazed = $rand" | d.text size=3 color=black at=2,20 +echo "" +echo "Area of grazed patches = $temparea sq m" | d.text size=3 color=black at=2,30 +echo "" +echo "Number of herd animals supported = $num" | d.text size=3 color=black at=2,40 +echo "" +echo "Total amount of biomass available this year = $bmas" | d.text size=3 color=black at=2,50 +echo "" +echo "Average fodder consumption of herd per animal = $efkg" | d.text size=3 color=black at=2,60 +echo "" +echo "Total amount of forage grazed this year = $ebmas" | d.text size=3 color=black at=2,70 +echo "" +echo "Difference from grazed area last year = $dif" | d.text -b size=3 color=black at=2,80 +echo "" +echo "************************" +echo "" + +#below is more output for text files of stats from this model run + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "" >> $txtout +echo "Year $step:" >> $txtout +echo "" >> $txtout +echo "Average biomass production (kg/year), Landcover description, Area (sq. m)" >> $txtout +echo "" >> $txtout +r.stats -a -l -n input=$outlanduse fs=, nv=* nsteps=255 >> $txtout + +echo "$step,$rand,$temparea,$bmas,$ebmas,$dif" >> $txtout2 + + +fi + + + + +done + + +echo "" +echo "*************************" +echo "step 4 of 4: Cleaning up" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 1 ] ; then + + + +g.mremove -f --quiet rast=$prfx"_cfactor*" +g.mremove -f --quiet rast=$prfx"_timer*" +g.mremove -f --quiet rast=$prfx"_tmpinreclass*" +g.remove --q rast=MASK + +elif [ "$GIS_FLAG_f" -eq 0 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --quiet rast=$prfx"_patches*" +g.mremove -f --quiet rast=$prfx"_cfactor*" +g.mremove -f --quiet rast=$prfx"_timer*" +g.mremove -f --quiet rast=$prfx"_tmpinreclass*" +g.remove --q rast=MASK + +elif [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 0 ] ; then + +g.remove --q rast=MASK +g.mremove -f --quiet rast=$prfx"_timer*" +g.mremove -f --quiet rast=$prfx"_tmpinreclass*" + +else + + +g.mremove -f --quiet rast=$prfx"_patches*" +g.remove --q rast=MASK +g.mremove -f --quiet rast=$prfx"_timer*" +g.mremove -f --quiet rast=$prfx"_tmpinreclass*" + +fi + + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort +\rm -f $TMP5 $TMP5.sort + + +echo "" +echo "Resetting region" +echo "" + +g.region -g region=temp_region +g.remove --q region=temp_region + + +echo "" +echo "DONE!" +echo "" +echo "" + + +d.mon -r + Property changes on: trunk/grassaddons/LandDyn/r.nompast.num/r.nompast.num ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.pastoral.simple/r.pastoral.simple =================================================================== --- trunk/grassaddons/LandDyn/r.pastoral.simple/r.pastoral.simple (rev 0) +++ trunk/grassaddons/LandDyn/r.pastoral.simple/r.pastoral.simple 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,377 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.pastoral.simple +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a series of iterative pastoral landuse maps from a catchment +# created by r.catchment. This model does not take pastoral ecology or economy into account. +# Optionally outputs c factor as well +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a series of iterative pastoral landuse maps from a catchmentcreated by r.catchment. This model does not take pastoral ecology or economy into account. Optionally outputs c factor as well +#%END + +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: Input catchment map (from r.cost.areas or r.buffer) +#% required : yes +#%END +#%option +#% key: rand +#% type: integer +#% description: percent of area to be grazed in any year (to be used in r.random) +#% answer: 50 +#% required : yes +#%END +#%option +#% key: size +#% type: integer +#% description: size of grazing patches (set as resolution in g.region) +#% answer: 30 +#% required : yes +#%END +#%option +#% key: effect +#% type: integer +#% description: Intensity of grazing (amount by which landcover is decreased after grazing) +#% answer: 1 +#% options: 1,2,3,4,5 +#% required : yes +#%END +#%option +#% key: loop +#% type: integer +#% description: number of iterations ("years") to run +#% answer: 10 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% answer: landcover +#% required : yes +#%END +#%flag +#% key: l +#% description: -l Suppress output of C factor map (output landuse map only) +#%END +#%flag +#% key: f +#% description: -f Output maps of random grazing patches at each iteration as well +#%END +#%flag +#% key: s +#% description: -s Output text file of land-use stats from the simulation (will be named "prefix"_luse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) +#%END + + +if [ -z "$GISBASE" ] ; then + g.message -e "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +inmap=$GIS_OPT_inmap +inmapa=$GIS_OPT_inmapa +rand=$GIS_OPT_rand +size=$GIS_OPT_size +loop=$GIS_OPT_loop +effect=$GIS_OPT_effect +prfx=$GIS_OPT_prfx +timer=$prfx".timer1" +txtout=$prfx"_luse_stats.txt" + +TMP1=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + g.message -e "ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + +TMP2=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then + g.message -e "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0 grey" > $TMP2 +echo "5 brown" >> $TMP2 +echo "10 orange" >> $TMP2 +echo "15 yellow" >> $TMP2 +echo "21 green" >> $TMP2 +echo "end" >> $TMP2 + +TMP3=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then + g.message -e "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0 = 0 badly overgrazed" > $TMP3 +echo "1 = 1 overgrazed" >> $TMP3 +echo "2 = 2 sparse grassland" >> $TMP3 +echo "3 = 3 moderate grassland" >> $TMP3 +echo "4 = 4 grassland" >> $TMP3 +echo "5 = 5 grass and sparse shrubs" >> $TMP3 +echo "6 = 6 grass and shrubs" >> $TMP3 +echo "7 = 7 mainly shrubs" >> $TMP3 +echo "8 = 8 developing maquis" >> $TMP3 +echo "9 = 9 moderate maquis" >> $TMP3 +echo "10 = 10 maquis" >> $TMP3 +echo "11 = 11 moderately dense maquis" >> $TMP3 +echo "12 = 12 dense maquis" >> $TMP3 +echo "13 = 13 maquis and small trees" >> $TMP3 +echo "14 = 14 young woodland and maquis" >> $TMP3 +echo "15 = 15 mostly young open woodland" >> $TMP3 +echo "16 = 16 young open woodland" >> $TMP3 +echo "17 = 17 moderate open woodland" >> $TMP3 +echo "18 = 18 maturing and moderate open woodland" >> $TMP3 +echo "19 = 19 maturing open woodland" >> $TMP3 +echo "20 = 20 mostly matured open woodland" >> $TMP3 +echo "21 = 21 fully matured woodland" >> $TMP3 +echo "end" >> $TMP3 + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for categories" 1>&2 + exit 1 +fi + +echo "0:1:0.5:0.5" > $TMP4 +echo "2:5:0.10:0.10" >> $TMP4 +echo "6:9:0.15:0.15" >> $TMP4 +echo "10:13:0.18:0.18" >> $TMP4 +echo "13:16:0.08:0.08" >> $TMP4 +echo "17:20:0.06:0.06" >> $TMP4 +echo "21:21:0.05:0.05" >> $TMP4 +echo "end" >> $TMP4 + +TMP5=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0.5 grey" > $TMP5 +echo "0.6 grey" >> $TMP5 +echo "0.19 brown" >> $TMP5 +echo "0.17 brown" >> $TMP5 +echo "0.10 yellow" >> $TMP5 +echo "0.05 green" >> $TMP5 +echo "end" >> $TMP5 + + + +g.message message='' +g.message message='*************************' +g.message message='step 1 of 4: Calculating MASK' +g.message message='*************************' +g.message message='' + + +r.mask --quiet input=$inmap maskcats=* + + +g.message message='' +g.message message='*************************' +g.message message='step 2 of 4: Changing resolution to field size (will be reset)' +g.message message='*************************' +g.message message='' + +g.region save=temp_region + +g.region res=$size + + + +g.message message='' +g.message message='*************************' +g.message message='step 3 of 4: Sarting land use evolution calculation. This will start a loop and may take some time. Please do not interrupt the process until it has finished' +g.message message='*************************' +g.message message='' + + +g.message message="iteration 1" + +r.mapcalc "tmpinreclass = if ($inmap, 1, null())" + +patches=$prfx"_patches1" + + +r.random --q input=tmpinreclass n=$rand"%" raster_output=$patches + +if [ "$GIS_FLAG_f" -eq 1 ]; then + + g.message message="grazing patches map = $patches" + + fi + +r.mapcalc "$timer = if (isnull($patches), 21, 21-$effect)" + + + cat $TMP3 | r.reclass --q input=$timer output=temp_landuse1 + + r.mapcalc "$prfx"_landuse1" = temp_landuse1" + + cat $TMP2 | r.colors --q map=$prfx"_landuse1" color=rules + + cat $TMP4 | r.recode --q input=$prfx"_landuse1" output=$prfx"_cfactor_1" + + cat $TMP5 | r.colors --q map=$prfx"_cfactor_1" color=rules + + + temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2` + g.message message='' + g.message message="Area of new randomized grazing patches = $temparea square meters" + + + +g.message message="***********************" + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +echo "Stats for $loop years of grazing at $rand% grazing of the landscape in $size square meter patches" > $txtout +g.message message='' >> $txtout +echo "Year 1:" >> $txtout +g.message message='' >> $txtout +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout +g.message message='' >> $txtout +r.stats -a -l -n input=$prfx"_landuse1" fs=, nv=* nsteps=255 >> $txtout + +fi + +step=1 + + +while [ "$step" -lt "$loop" ] +do + step=$(($step+1)) + g.message message="iteration $step" + laststep=$(($step-1)) + + + + outcfactor=$prfx"_cfactor_"$step + tmplanduse="temp_landuse"$step + outlanduse=$prfx"_landuse"$step + outpatches=$prfx"_patches"$step + newtimer=$prfx".timer"$step + oldtimer=$prfx".timer"$laststep + r.random --q input=tmpinreclass n=$rand"%" raster_output=$outpatches + + if [ "$GIS_FLAG_f" -eq 1 ]; then + + g.message message="grazing patches map = $outpatches" + + fi + +r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 20, $oldtimer + 1, (if(isnull($outpatches), 21, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" + + + + cat $TMP3 | r.reclass --q input=$newtimer output=$tmplanduse + + r.mapcalc "$outlanduse = $tmplanduse" + + cat $TMP2 | r.colors --q map=$outlanduse color=rules + + cat $TMP4 | r.recode --q input=$outlanduse output=$outcfactor + + cat $TMP5 | r.colors --q map=$outcfactor color=rules + + temparea=`eval r.stats -n -a fs=- input=$outpatches | cut -d'-' -f2` + g.message message='' + g.message message="Area of new randomized grazing patches = $temparea square meters" +g.message message='' +g.message message='' +g.message message="************************" +g.message message='' + +if [ "$GIS_FLAG_s" -eq 1 ]; then + +g.message message='' >> $txtout +echo "Year $step:" >> $txtout +g.message message='' >> $txtout +echo "Landcover class #, Landcover description, Area (sq. m)" >> $txtout +g.message message='' >> $txtout +r.stats -a -l -n input=$outlanduse fs=, nv=* nsteps=255 >> $txtout + +fi + +done + + +g.message message='' +g.message message="*************************" +g.message message="step 4 of 4: Cleaning up" +g.message message="*************************" +g.message message='' + +if [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --q rast=temp_landuse* +g.mremove -f --q rast=$prfx"_cfactor*" +g.mremove -f --q rast=$prfx".timer*" +g.remove --q rast=tmpinreclass,MASK + +elif [ "$GIS_FLAG_f" -eq 0 -a "$GIS_FLAG_l" -eq 1 ] ; then + + +g.mremove -f --q rast=$prfx"_patches*" +g.mremove -f --q rast=temp_landuse* +g.mremove -f --q rast=$prfx"_cfactor*" +g.mremove -f --q rast=$prfx".timer*" +g.remove --q rast=tmpinreclass,MASK + +elif [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_l" -eq 0 ] ; then + +g.remove --q rast=tmpinreclass,MASK +g.mremove -f --q rast=temp_landuse* +g.mremove -f --q rast=$prfx".timer*" +else + + +g.mremove -f --q rast=$prfx"_patches*" +g.mremove -f --q rast=temp_landuse* +g.remove --q rast=tmpinreclass,MASK +g.mremove -f --q rast=$prfx".timer*" + +fi + + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort +\rm -f $TMP5 $TMP5.sort + + +g.message message='' +g.message message="Resetting region" +g.message message='' + +g.region -g region=temp_region +g.remove --q region=temp_region + + +g.message message='' +g.message message='DONE!' +g.message message='' +g.message message='' + Property changes on: trunk/grassaddons/LandDyn/r.pastoral.simple/r.pastoral.simple ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.rfactor/r.rfactor =================================================================== --- trunk/grassaddons/LandDyn/r.rfactor/r.rfactor (rev 0) +++ trunk/grassaddons/LandDyn/r.rfactor/r.rfactor 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,346 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.rfactor +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Calculates estimated annual R factor for use in r.landscape.evol +# from mean annual precip, and monthly average precip maps. +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# Based on Renard and Freimund, 1994. +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Calculates estimated annual (and optionally monthly) R factor for use in r.landscape.evol from mean annual precip, and monthly average precip maps. +#%End +#%option +#% key: annual +#% type: string +#% gisprompt: old,cell,raster +#% description: Input annual precip map. +#% required : yes +#%END +#%option +#% key: jan +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Jan average precip map. +#% required : yes +#%END +#%option +#% key: feb +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Feb average precip map. +#% required : yes +#%END +#%option +#% key: mar +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Mar average precip map. +#% required : yes +#%END +#%option +#% key: apr +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Apr average precip map. +#% required : yes +#%END +#%option +#% key: may +#% type: string +#% gisprompt: old,cell,raster +#% description: Input May average precip map. +#% required : yes +#%END +#%option +#% key: jun +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Jun average precip map. +#% required : yes +#%END +#%option +#% key: jul +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Jul average precip map. +#% required : yes +#%END +#%option +#% key: aug +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Aug average precip map. +#% required : yes +#%END +#%option +#% key: sep +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Sep average precip map. +#% required : yes +#%END +#%option +#% key: oct +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Oct average precip map. +#% required : yes +#%END +#%option +#% key: nov +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Nov average precip map. +#% required : yes +#%END +#%option +#% key: dec +#% type: string +#% gisprompt: old,cell,raster +#% description: Input Dec average precip map. +#% required : yes +#%END +#%option +#% key: prefx +#% type: string +#% description: Prefix for all output map(s). +#% answer: rfactor +#% required : yes +#%END +#%flag +#% key: m +#% description: -m Calcuate average monthly R factor maps as well. +#%END +#%flag +#% key: f +#% description: -f Output Modified Fournier Index map(s) as well. +#%END + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +annual=$GIS_OPT_annual +jan=$GIS_OPT_jan +feb=$GIS_OPT_feb +mar=$GIS_OPT_mar +apr=$GIS_OPT_apr +may=$GIS_OPT_may +jun=$GIS_OPT_jun +jul=$GIS_OPT_jul +aug=$GIS_OPT_aug +sep=$GIS_OPT_sep +oct=$GIS_OPT_oct +nov=$GIS_OPT_nov +dec=$GIS_OPT_dec +prefx=$GIS_OPT_prefx +echo "prefix=$prefx" +res=`eval g.region -m | grep "nsres=" | cut -d = -f 2` +echo "res=$res" +rannual=$prefx".annual.r" +echo "annual r factor map=$rannual" +fm=$prefx".annual.fournier" + +if [ "$GIS_FLAG_f" -eq 1 ]; then +echo "annual modified fournier index map=$fm" +fi + +if [ "$GIS_FLAG_m" -eq 1 ]; then +fmjan=$prefx".jan.fournier" +fmfeb=$prefx".feb.fournier" +fmmar=$prefx".mar.fournier" +fmapr=$prefx".apr.fournier" +fmmay=$prefx".may.fournier" +fmjun=$prefx".jun.fournier" +fmjul=$prefx".jul.fournier" +fmaug=$prefx".aug.fournier" +fmsep=$prefx".sep.fournier" +fmoct=$prefx".oct.fournier" +fmnov=$prefx".nov.fournier" +fmdec=$prefx".dec.fournier" +rjan=$prefx".jan.r" +echo "jan r factor map=$rjan" +rfeb=$prefx".feb.r" +echo "feb r factor map=$rfeb" +rmar=$prefx".mar.r" +echo "mar r factor map=$rmar" +rapr=$prefx".apr.r" +echo "apr r factor map=$rapr" +rmay=$prefx".may.r" +echo "may r factor map=$rmay" +rjun=$prefx".jun.r" +echo "jun r factor map=$rjun" +rjul=$prefx".jul.r" +echo "jul r factor map=$rjul" +raug=$prefx".aug.r" +echo "aug r factor map=$raug" +rsep=$prefx".sep.r" +echo "sep r factor map=$rsep" +roct=$prefx".oct.r" +echo "oct r factor map=$roct" +rnov=$prefx".nov.r" +echo "nov r factor map=$rnov" +rdec=$prefx".dec.r" +echo "dec r factor map=$rdec" +fi + +if [ "$GIS_FLAG_m" -eq 1 -a "$GIS_FLAG_f" -eq 1 ]; then +echo "jan modified fournier index map=$fmjan" +echo "feb modified fournier index map=$fmfeb" +echo "mar modified fournier index map=$fmmar" +echo "apr modified fournier index map=$fmapr" +echo "may modified fournier index map=$fmrmay" +echo "jun modified fournier index map=$fmjun" +echo "jul modified fournier index map=$fmjul" +echo "aug modified fournier index map=$fmaug" +echo "sep modified fournier index map=$fmsep" +echo "oct modified fournier index map=$fmoct" +echo "nov modified fournier index map=$fmnov" +echo "dec modified fournier index map=$fmdec" +fi + +if [ "$GIS_FLAG_m" -eq 1 ]; then +echo "" +echo "******First making annual R factor map******" +echo "" +fi + +echo "" +echo "*************************" +echo "step 1 of 2: Calculating Modified Fournier Index map" +echo "*************************" +echo "" + + +r.mapcalc "$fm=((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)/$annual" + + +echo "" +echo "*************************" +echo "step 2 of 2: Calculating estimated R-factor map" +echo "*************************" +echo "" + +r.mapcalc "$rannual=(95.77-(6.081*$fm)+(0.477*exp($fm,2)))/17.2" + +#Below are the two the r-factor regression conversions suggested by Renard and Freimund (1994)for Fournier < 55 and Fournier > 55. However, with the maps I have used to test this script, the first regression outputs unreasonable r factor values. Therefore, this module only uses the second regresion for all Fournier Index values. Please see Renard and Friemund (1994) for their explanation of why two different regressions should be used. +#r.mapcalc "$output=if($fm<55,(0.07397*exp($fm,1.847))/17.2,(95.77-(6.081*$fm)+(0.477*exp($fm,2)))/17.2)" + +if [ "$GIS_FLAG_m" -eq 1 ]; then +echo "" +echo "******Now making monthly R factor maps******" +echo "" +echo "" +echo "*************************" +echo "step 1 of 2: Calculating Modified Fournier Index maps for each month. This may take some time..." +echo "*************************" +echo "" + +r.mapcalc "$fmjan=(exp($jan,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmfeb=(exp($feb,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmmar=(exp($mar,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmapr=(exp($apr,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmmay=(exp($may,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmjun=(exp($jun,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmjul=(exp($jul,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmaug=(exp($aug,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmsep=(exp($sep,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmoct=(exp($oct,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmnov=(exp($nov,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +r.mapcalc "$fmdec=(exp($dec,2))/((exp($jan,2)+exp($feb,2)+exp($mar,2)+exp($apr,2)+exp($may,2)+exp($jun,2)+exp($jul,2)+exp($aug,2)+exp($sep,2)+exp($oct,2)+exp($nov,2)+exp($dec,2))/12)" + +echo "" +echo "*************************" +echo "step 2 of 2: Calculating estimated monthly R-factor maps. This may take some time..." +echo "*************************" +echo "" + +r.mapcalc "$rjan=(95.77-(6.081*$fmjan)+(0.477*exp($fmjan,2)))/17.2" + +r.mapcalc "$rfeb=(95.77-(6.081*$fmfeb)+(0.477*exp($fmfeb,2)))/17.2" + +r.mapcalc "$rmar=(95.77-(6.081*$fmmar)+(0.477*exp($fmmar,2)))/17.2" + +r.mapcalc "$rapr=(95.77-(6.081*$fmapr)+(0.477*exp($fmapr,2)))/17.2" + +r.mapcalc "$rmay=(95.77-(6.081*$fmmay)+(0.477*exp($fmmay,2)))/17.2" + +r.mapcalc "$rjun=(95.77-(6.081*$fmjun)+(0.477*exp($fmjun,2)))/17.2" + +r.mapcalc "$rjul=(95.77-(6.081*$fmjul)+(0.477*exp($fmjul,2)))/17.2" + +r.mapcalc "$raug=(95.77-(6.081*$fmaug)+(0.477*exp($fmaug,2)))/17.2" + +r.mapcalc "$rsep=(95.77-(6.081*$fmsep)+(0.477*exp($fmsep,2)))/17.2" + +r.mapcalc "$roct=(95.77-(6.081*$fmoct)+(0.477*exp($fmoct,2)))/17.2" + +r.mapcalc "$rnov=(95.77-(6.081*$fmnov)+(0.477*exp($fmnov,2)))/17.2" + +r.mapcalc "$rdec=(95.77-(6.081*$fmdec)+(0.477*exp($fmdec,2)))/17.2" + +fi + +if [ "$GIS_FLAG_m" -eq 1 -a "$GIS_FLAG_f" -eq 1 ]; then +echo "" +echo "Done" +echo "" + +elif [ "$GIS_FLAG_m" -eq 1 -a "$GIS_FLAG_f" -eq 0 ]; then + +echo "" +echo "Cleaning up" +echo "" + +g.remove rast=$fm,$fmjan,$fmfeb,$fmmar,$fmapr,$fmmay,$fmjun,$fmjul,$fmaug,$fmsep,$fmoct,$fmnov,$fmdec + +echo "" +echo "Done" +echo "" + +elif [ "$GIS_FLAG_m" -eq 0 -a "$GIS_FLAG_f" -eq 1 ]; then + +echo "" +echo "Done" +echo "" + +else + + +echo "" +echo "Cleaning up" +echo "" + +g.remove rast=$fm + +echo "" +echo "Done" +echo "" + +fi Property changes on: trunk/grassaddons/LandDyn/r.rfactor/r.rfactor ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.rfactor.iterate/r.rfactor.iterate =================================================================== --- trunk/grassaddons/LandDyn/r.rfactor.iterate/r.rfactor.iterate (rev 0) +++ trunk/grassaddons/LandDyn/r.rfactor.iterate/r.rfactor.iterate 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,583 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.rfactor.iterate +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Calculates estimated annual (and optionally monthly) R factor for use in r.landscape.evol from +# mean annual precip, and monthly average precip maps. This script operates iteratively on input +# maps already in the current mapset which conform to the naming convention "prefix(ie. the +# prefix specified in r.climate)_Month(ie. "Dec" for december map or "Ann" for yearly +# map)_year(integer year number of precip map starting from most recent and ascending as you go +# backwards in time). An example is: "rainfall_Ann_2000" which would be the name of a map of +# average annual precip for the year 2000BP that has a prefix of "rainfall"). This naming +# convention will be automatically generated by r.climate. When entering the input prefixes here, +# leave off the year number (ie "_2000") as these will be controlled by the variables "max", +# "min", and "stepsize". An example input prefix is: "rainfall_Ann" for all average annual precip +# maps. +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# Based on Renard and Freimund, 1994. +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Calculates estimated annual (and optionally monthly) R factor for use in r.landscape.evol from mean annual precip, and monthly average precip maps. This script operates iteratively on input maps already in the current mapset which conform to the naming convention "prefix(ie. the prefix specified in r.climate)_Month(ie. "Dec" for december map or "Ann" for yearly map)_year(integer year number of precip map starting from most recent and ascending as you go backwards in time). An example is: "rainfall_Ann_2000" which would be the name of a map of average annual precip for the year 2000BP that has a prefix of "rainfall"). This naming convention will be automatically generated by r.climate. When entering the input prefixes here, leave off the year number (ie "_2000") as these will be controlled by the variables "max", "min", and "stepsize". An example input prefix is: "rainfall_Ann" for all average annual precip maps. +#%End +#%option +#% key: annual +#% type: string +#% description: Input annual precip map prefix. +#% answer: prefix_Ann +#% required : yes +#%END +#%option +#% key: jan +#% type: string +#% description: Input Jan average precip map prefix. +#% answer: prefix_Jan +#% required : yes +#%END +#%option +#% key: feb +#% type: string +#% description: Input Feb average precip map prefix. +#% answer: prefix_Feb +#% required : yes +#%END +#%option +#% key: mar +#% type: string +#% description: Input Mar average precip map prefix. +#% answer: prefix_Mar +#% required : yes +#%END +#%option +#% key: apr +#% type: string +#% description: Input Apr average precip map prefix. +#% answer: prefix_Apr +#% required : yes +#%END +#%option +#% key: may +#% type: string +#% description: Input May average precip map prefix. +#% answer: prefix_May +#% required : yes +#%END +#%option +#% key: jun +#% type: string +#% description: Input Jun average precip map prefix. +#% answer: prefix_Jun +#% required : yes +#%END +#%option +#% key: jul +#% type: string +#% description: Input Jul average precip map prefix. +#% answer: prefix_Jul +#% required : yes +#%END +#%option +#% key: aug +#% type: string +#% description: Input Aug average precip map prefix. +#% answer: prefix_Aug +#% required : yes +#%END +#%option +#% key: sep +#% type: string +#% description: Input Sep average precip map prefix. +#% answer: prefix_Sep +#% required : yes +#%END +#%option +#% key: oct +#% type: string +#% description: Input Oct average precip map prefix. +#% answer: prefix_Oct +#% required : yes +#%END +#%option +#% key: nov +#% type: string +#% description: Input Nov average precip map prefix. +#% answer: prefix_Nov +#% required : yes +#%END +#%option +#% key: dec +#% type: string +#% description: Input Dec average precip map prefix. +#% answer: prefix_Dec +#% required : yes +#%END +#%option +#% key: prefx +#% type: string +#% description: Prefix for all output map(s). +#% answer: rfactor +#% required : yes +#%END +#%option +#% key: max +#% type: integer +#% description: Maximum step value (ie. oldest (finish) year) +#% required : yes +#%END +#%option +#% key: min +#% type: integer +#% description: Minimum sgtep value (ie. youngest (start) year) +#% required : yes +#%END +#%option +#% key: stepsize +#% type: integer +#% description: Iteration step value (ie. number of years between steps) +#% required : yes +#%END +#%flag +#% key: m +#% description: -m Calcuate average monthly R factor maps as well. +#%END +#%flag +#% key: f +#% description: -f Output Modified Fournier Index map(s) as well. +#%END + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +annual=$GIS_OPT_annual +jan=$GIS_OPT_jan +feb=$GIS_OPT_feb +mar=$GIS_OPT_mar +apr=$GIS_OPT_apr +may=$GIS_OPT_may +jun=$GIS_OPT_jun +jul=$GIS_OPT_jul +aug=$GIS_OPT_aug +sep=$GIS_OPT_sep +oct=$GIS_OPT_oct +nov=$GIS_OPT_nov +dec=$GIS_OPT_dec +prefx=$GIS_OPT_prefx +echo "prefix=$prefx" +res=`eval g.region -m | grep "nsres=" | cut -d = -f 2` +echo "res=$res" +rannual=$prefx"_$annual" +echo "annual r factor map prefix=$rannual" +fm=$prefx"_$annual""_fournier" +step=$GIS_OPT_min +max=$GIS_OPT_max +stepsize=$GIS_OPT_stepsize + +if [ "$GIS_FLAG_f" -eq 1 ]; then +echo "annual modified fournier index map prefix=$fm" +fi + +if [ "$GIS_FLAG_m" -eq 1 ]; then +fmjan=$prefx"_$jan""_fournier" +fmfeb=$prefx"_$feb""_fournier" +fmmar=$prefx"_$mar""_fournier" +fmapr=$prefx"_$apr""_fournier" +fmmay=$prefx"_$may""_fournier" +fmjun=$prefx"_$jun""_fournier" +fmjul=$prefx"_$jul""_fournier" +fmaug=$prefx"_$aug""_fournier" +fmsep=$prefx"_$sep""_fournier" +fmoct=$prefx"_$oct""_fournier" +fmnov=$prefx"_$nov""_fournier" +fmdec=$prefx"_$dec""_fournier" +rjan=$prefx"_$jan""_r" +echo "jan r factor map prefix=$rjan" +rfeb=$prefx"_$feb""_r" +echo "feb r factor map prefix=$rfeb" +rmar=$prefx"_$mar""_r" +echo "mar r factor map prefix=$rmar" +rapr=$prefx"_$apr""_r" +echo "apr r factor map prefix=$rapr" +rmay=$prefx"__$may""_r" +echo "may r factor map prefix=$rmay" +rjun=$prefx"_$jun""_r" +echo "jun r factor map prefix=$rjun" +rjul=$prefx"_$jul""_r" +echo "jul r factor map prefix=$rjul" +raug=$prefx"_$aug""_r" +echo "aug r factor map prefix=$raug" +rsep=$prefx"_$sep""_r" +echo "sep r factor map prefix=$rsep" +roct=$prefx"_$oct""_r" +echo "oct r factor map prefix=$roct" +rnov=$prefx"_$nov""_r" +echo "nov r factor map prefix=$rnov" +rdec=$prefx"_$dec""_r" +echo "dec r factor map prefix=$rdec" +fi + +if [ "$GIS_FLAG_m" -eq 1 -a "$GIS_FLAG_f" -eq 1 ]; then +echo "jan modified fournier index map prefix=$fmjan" +echo "feb modified fournier index map prefix=$fmfeb" +echo "mar modified fournier index map prefix=$fmmar" +echo "apr modified fournier index map prefix=$fmapr" +echo "may modified fournier index map prefix=$fmrmay" +echo "jun modified fournier index map prefix=$fmjun" +echo "jul modified fournier index map prefix=$fmjul" +echo "aug modified fournier index map prefix=$fmaug" +echo "sep modified fournier index map prefix=$fmsep" +echo "oct modified fournier index map prefix=$fmoct" +echo "nov modified fournier index map prefix=$fmnov" +echo "dec modified fournier index map prefix=$fmdec" +fi + + +# We must calculate the output map(s) for the first year before entering a "while" loop to get the output map(s) for the rest of the years. This is because the "while" loop will actually start at "step + stepsize" (ie. the second year) instead of the first year... + +#now we must create a MASK to work under (becuse of the consequent NULL modification needed) + +r.mapcalc "MASK=if(isnull($ranual"_$step"), null(), 1)" + +echo "" +echo "*************************" +echo "ITERATION $step" +echo "*************************" +echo "" + + + +if [ "$GIS_FLAG_m" -eq 1 ]; then +echo "" +echo "******First making annual R factor map******" +echo "" +fi + + +echo "" +echo "*************************" +echo "step 1 of 2: Calculating Modified Fournier Index map" +echo "*************************" +echo "" + + +r.mapcalc "$fm"_$step"=((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)/$annual"_$step"" + + +echo "" +echo "*************************" +echo "step 2 of 2: Calculating estimated R-factor map" +echo "*************************" +echo "" + +#Below are the two the r-factor regression conversions suggested by Renard and Freimund (1994)for Fournier < 55 and Fournier > 55. However, with the maps I have used to test this script, the first regression outputs unreasonable r factor values. Therefore, this module only uses the second regresion for all Fournier Index values. Please see Renard and Friemund (1994) for their explanation of why two different regressions should be used. +#r.mapcalc "$output=if($fm<55,(0.07397*exp($fm,1.847))/17.2,(95.77-(6.081*$fm)+(0.477*exp($fm,2)))/17.2)" + +r.mapcalc "$rannual"_$step"=(95.77-(6.081*$fm"_$step")+(0.477*exp($fm"_$step",2)))/17.2" + +#now we must change any null values produced to zero + +r.mapcalc "$rannual"_$step"=if(isnull($rannual"_$step"), 0, $rannual"_$step")" + + +if [ "$GIS_FLAG_m" -eq 1 ]; then +echo "" +echo "******Now making monthly R factor maps******" +echo "" +echo "" +echo "*************************" +echo "step 1 of 2: Calculating Modified Fournier Index maps for each month. This may take some time..." +echo "*************************" +echo "" + +r.mapcalc "$fmjan"_$step"=(exp($jan"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmfeb"_$step"=(exp($feb"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmmar"_$step"=(exp($mar"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmapr"_$step"=(exp($apr"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmmay"_$step"=(exp($may"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmjun"_$step"=(exp($jun"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmjul"_$step"=(exp($jul"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmaug"_$step"=(exp($aug"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmsep"_$step"=(exp($sep"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep,2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmoct"_$step"=(exp($oct"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmnov"_$step"=(exp($nov"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +r.mapcalc "$fmdec"_$step"=(exp($dec"_$step",2))/((exp($jan"_$step",2)+exp($feb,2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + +echo "" +echo "*************************" +echo "step 2 of 2: Calculating estimated monthly R-factor maps. This may take some time..." +echo "*************************" +echo "" + +r.mapcalc "$rjan"_$step"=(95.77-(6.081*$fmjan"_$step")+(0.477*exp($fmjan"_$step",2)))/17.2" + +r.mapcalc "$rjan"_$step"=if(isnull($rjan"_$step"), 0, $rjan"_$step")" + +r.mapcalc "$rfeb"_$step"=(95.77-(6.081*$fmfeb"_$step")+(0.477*exp($fmfeb"_$step",2)))/17.2" + +r.mapcalc "$rfeb"_$step"=if(isnull($rfeb"_$step"), 0, $rfeb"_$step")" + +r.mapcalc "$rmar"_$step"=(95.77-(6.081*$fmmar"_$step")+(0.477*exp($fmmar"_$step",2)))/17.2" + +r.mapcalc "$rmar"_$step"=if(isnull($rmar"_$step"), 0, $rmar"_$step")" + +r.mapcalc "$rapr"_$step"=(95.77-(6.081*$fmapr"_$step")+(0.477*exp($fmapr"_$step",2)))/17.2" + +r.mapcalc "$rapr"_$step"=if(isnull($rapr"_$step"), 0, $rapr"_$step")" + +r.mapcalc "$rmay"_$step"=(95.77-(6.081*$fmmay"_$step")+(0.477*exp($fmmay"_$step",2)))/17.2" + +r.mapcalc "$rmay"_$step"=if(isnull($rmay"_$step"), 0, $rmay"_$step")" + +r.mapcalc "$rjun"_$step"=(95.77-(6.081*$fmjun"_$step")+(0.477*exp($fmjun"_$step",2)))/17.2" + +r.mapcalc "$rjun"_$step"=if(isnull($rjun"_$step"), 0, $rjun"_$step")" + +r.mapcalc "$rjul"_$step"=(95.77-(6.081*$fmjul"_$step")+(0.477*exp($fmjul"_$step",2)))/17.2" + +r.mapcalc "$rjul"_$step"=if(isnull($rjul"_$step"), 0, $rjul"_$step")" + +r.mapcalc "$raug"_$step"=(95.77-(6.081*$fmaug"_$step")+(0.477*exp($fmaug"_$step",2)))/17.2" + +r.mapcalc "$raug"_$step"=if(isnull($raug"_$step"), 0, $raug"_$step")" + +r.mapcalc "$rsep"_$step"=(95.77-(6.081*$fmsep"_$step")+(0.477*exp($fmsep"_$step",2)))/17.2" + +r.mapcalc "$rsep"_$step"=if(isnull($rsep"_$step"), 0, $rsep"_$step")" + +r.mapcalc "$roct"_$step"=(95.77-(6.081*$fmoct"_$step")+(0.477*exp($fmoct"_$step",2)))/17.2" + +r.mapcalc "$roct"_$step"=if(isnull($roct"_$step"), 0, $roct"_$step")" + +r.mapcalc "$rnov"_$step"=(95.77-(6.081*$fmnov"_$step")+(0.477*exp($fmnov"_$step",2)))/17.2" + +r.mapcalc "$rnov"_$step"=if(isnull($rnov"_$step"), 0, $rnov"_$step")" + +r.mapcalc "$rdec"_$step"=(95.77-(6.081*$fmdec"_$step")+(0.477*exp($fmdec"_$step",2)))/17.2" + +r.mapcalc "$rdec"_$step"=if(isnull($rdec"_$step"), 0, $rdec"_$step")" + +fi + +# now we must enter a loop to get the subsequent years' output maps... + +while [ "$step" -le "$max" ] +do + step=$(($step+$stepsize)) + + # the above statement controls the loop... + + echo "" + echo "*************************" + echo "ITERATION $step" + echo "*************************" + echo "" + + + if [ "$GIS_FLAG_m" -eq 1 ]; then + echo "" + echo "******First making annual R factor map******" + echo "" + fi + + + echo "" + echo "*************************" + echo "step 1 of 2: Calculating Modified Fournier Index map" + echo "*************************" + echo "" + + + r.mapcalc "$fm"_$step"=((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)/$annual"_$step"" + + + echo "" + echo "*************************" + echo "step 2 of 2: Calculating estimated R-factor map" + echo "*************************" + echo "" + + #Below are the two the r-factor regression conversions suggested by Renard and Freimund (1994)for Fournier < 55 and Fournier > 55. However, with the maps I have used to test this script, the first regression outputs unreasonable r factor values. Therefore, this module only uses the second regresion for all Fournier Index values. Please see Renard and Friemund (1994) for their explanation of why two different regressions should be used. + #r.mapcalc "$output=if($fm<55,(0.07397*exp($fm,1.847))/17.2,(95.77-(6.081*$fm)+(0.477*exp($fm,2)))/17.2)" + + r.mapcalc "$rannual"_$step"=(95.77-(6.081*$fm"_$step")+(0.477*exp($fm"_$step",2)))/17.2" + + #now we must change any null values produced to zero + + r.mapcalc "$rannual"_$step"=if(isnull($rannual"_$step"), 0, $rannual"_$step")" + + if [ "$GIS_FLAG_m" -eq 1 ]; then + echo "" + echo "******Now making monthly R factor maps******" + echo "" + echo "" + echo "*************************" + echo "step 1 of 2: Calculating Modified Fournier Index maps for each month. This may take some time..." + echo "*************************" + echo "" + + r.mapcalc "$fmjan"_$step"=(exp($jan"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmfeb"_$step"=(exp($feb"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmmar"_$step"=(exp($mar"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmapr"_$step"=(exp($apr"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmmay"_$step"=(exp($may"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmjun"_$step"=(exp($jun"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmjul"_$step"=(exp($jul"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmaug"_$step"=(exp($aug"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmsep"_$step"=(exp($sep"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep,2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmoct"_$step"=(exp($oct"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmnov"_$step"=(exp($nov"_$step",2))/((exp($jan"_$step",2)+exp($feb"_$step",2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + r.mapcalc "$fmdec"_$step"=(exp($dec"_$step",2))/((exp($jan"_$step",2)+exp($feb,2)+exp($mar"_$step",2)+exp($apr"_$step",2)+exp($may"_$step",2)+exp($jun"_$step",2)+exp($jul"_$step",2)+exp($aug"_$step",2)+exp($sep"_$step",2)+exp($oct"_$step",2)+exp($nov"_$step",2)+exp($dec"_$step",2))/12)" + + echo "" + echo "*************************" + echo "step 2 of 2: Calculating estimated monthly R-factor maps. This may take some time..." + echo "*************************" + echo "" + + r.mapcalc "$rjan"_$step"=(95.77-(6.081*$fmjan"_$step")+(0.477*exp($fmjan"_$step",2)))/17.2" + + r.mapcalc "$rjan"_$step"=if(isnull($rjan"_$step"), 0, $rjan"_$step")" + + r.mapcalc "$rfeb"_$step"=(95.77-(6.081*$fmfeb"_$step")+(0.477*exp($fmfeb"_$step",2)))/17.2" + + r.mapcalc "$rfeb"_$step"=if(isnull($rfeb"_$step"), 0, $rfeb"_$step")" + + r.mapcalc "$rmar"_$step"=(95.77-(6.081*$fmmar"_$step")+(0.477*exp($fmmar"_$step",2)))/17.2" + + r.mapcalc "$rmar"_$step"=if(isnull($rmar"_$step"), 0, $rmar"_$step")" + + r.mapcalc "$rapr"_$step"=(95.77-(6.081*$fmapr"_$step")+(0.477*exp($fmapr"_$step",2)))/17.2" + + r.mapcalc "$rapr"_$step"=if(isnull($rapr"_$step"), 0, $rapr"_$step")" + + r.mapcalc "$rmay"_$step"=(95.77-(6.081*$fmmay"_$step")+(0.477*exp($fmmay"_$step",2)))/17.2" + + r.mapcalc "$rmay"_$step"=if(isnull($rmay"_$step"), 0, $rmay"_$step")" + + r.mapcalc "$rjun"_$step"=(95.77-(6.081*$fmjun"_$step")+(0.477*exp($fmjun"_$step",2)))/17.2" + + r.mapcalc "$rjun"_$step"=if(isnull($rjun"_$step"), 0, $rjun"_$step")" + + r.mapcalc "$rjul"_$step"=(95.77-(6.081*$fmjul"_$step")+(0.477*exp($fmjul"_$step",2)))/17.2" + + r.mapcalc "$rjul"_$step"=if(isnull($rjul"_$step"), 0, $rjul"_$step")" + + r.mapcalc "$raug"_$step"=(95.77-(6.081*$fmaug"_$step")+(0.477*exp($fmaug"_$step",2)))/17.2" + + r.mapcalc "$raug"_$step"=if(isnull($raug"_$step"), 0, $raug"_$step")" + + r.mapcalc "$rsep"_$step"=(95.77-(6.081*$fmsep"_$step")+(0.477*exp($fmsep"_$step",2)))/17.2" + + r.mapcalc "$rsep"_$step"=if(isnull($rsep"_$step"), 0, $rsep"_$step")" + + r.mapcalc "$roct"_$step"=(95.77-(6.081*$fmoct"_$step")+(0.477*exp($fmoct"_$step",2)))/17.2" + + r.mapcalc "$roct"_$step"=if(isnull($roct"_$step"), 0, $roct"_$step")" + + r.mapcalc "$rnov"_$step"=(95.77-(6.081*$fmnov"_$step")+(0.477*exp($fmnov"_$step",2)))/17.2" + + r.mapcalc "$rnov"_$step"=if(isnull($rnov"_$step"), 0, $rnov"_$step")" + + r.mapcalc "$rdec"_$step"=(95.77-(6.081*$fmdec"_$step")+(0.477*exp($fmdec"_$step",2)))/17.2" + + r.mapcalc "$rdec"_$step"=if(isnull($rdec"_$step"), 0, $rdec"_$step")" + + fi + + + + + +done + +# The loop is now finished. + +echo "" +echo "ITERATIONS FINISHED" +echo "" +echo "Checking for cleanup options..." +echo "" + +# Entering the cleanup stage. This requires a nested if statement because of the optional flags... + + +if [ "$GIS_FLAG_m" -eq 1 -a "$GIS_FLAG_f" -eq 1 ]; then +echo "" +echo "Done" +echo "" + +elif [ "$GIS_FLAG_m" -eq 1 -a "$GIS_FLAG_f" -eq 0 ]; then + +echo "" +echo "Cleaning up" +echo "" + +g.mremove rast=$fm* + +echo "" +echo "Done" +echo "" + +elif [ "$GIS_FLAG_m" -eq 0 -a "$GIS_FLAG_f" -eq 1 ]; then + +echo "" +echo "Done" +echo "" + +else + + +echo "" +echo "Cleaning up" +echo "" + +g.mremove rast=$fm* + +echo "" +echo "Done" +echo "" + +fi + +#now we remove our MASK + +g.remove rast=MASK + +echo "" +echo "DONE WITH EVERYTHING!" +echo "" Property changes on: trunk/grassaddons/LandDyn/r.rfactor.iterate/r.rfactor.iterate ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult =================================================================== --- trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult (rev 0) +++ trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,393 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.landuse.agr +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a series of iterative agricultural landuse maps from a catchment +# created by r.catchment. This model takes natural vegetational succession into account. +# Optionally outputs c factor as well +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a series of iterative agricultural landuse maps from a catchment created by r.catchment. This model takes natural vegetational succession into account. Optionally outputs c factor as well +#%END + +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: Input catchment map (from r.catchment) +#% required : yes +#%END +#%option +#% key: rand +#% type: integer +#% description: percent of area to be fields (to be used in r.random) +#% answer: 20 +#% required : yes +#%END +#%option +#% key: size +#% type: integer +#% description: size of fields (set as resolution in g.region) +#% answer: 45 +#% required : yes +#%END +#%option +#% key: loop +#% type: integer +#% description: number of iterations to run +#% answer: 50 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% required : yes +#%END +#%flag +#% key: m +#% description: -m output some stats to a text file in your home directory +#% answer: 1 +#%END +#%flag +#% key: s +#% description: -s Suppress output of landuse map (output C factor map only) +#%END +#%flag +#% key: f +#% description: -f Output maps of random fields at each iteration as well +#%END + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +inmap=$GIS_OPT_inmap +rand=$GIS_OPT_rand +size=$GIS_OPT_size +loop=$GIS_OPT_loop +prfx=$GIS_OPT_prfx +txtout=$prfx"_stats.txt" + +TMP1=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file" 1>&2 + exit 1 +fi + +TMP2=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0 brown" > $TMP2 +echo "7 orange" >> $TMP2 +echo "14 yellow" >> $TMP2 +echo "21 green" >> $TMP2 +echo "end" >> $TMP2 + +TMP3=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0 = 0 actively cultivated field" > $TMP3 +echo "1 = 1 field with weeds" >> $TMP3 +echo "2 = 2 returning grassland" >> $TMP3 +echo "3 = 3 moderate grassland" >> $TMP3 +echo "4 = 4 grassland" >> $TMP3 +echo "5 = 5 grass and sparse shrubs" >> $TMP3 +echo "6 = 6 grass and shrubs" >> $TMP3 +echo "7 = 7 mainly shrubs" >> $TMP3 +echo "8 = 8 developing maquis" >> $TMP3 +echo "9 = 9 moderate maquis" >> $TMP3 +echo "10 = 10 maquis" >> $TMP3 +echo "11 = 11 moderately dense maquis" >> $TMP3 +echo "12 = 12 dense maquis" >> $TMP3 +echo "13 = 13 maquis and small trees" >> $TMP3 +echo "14 = 14 young woodland and maquis" >> $TMP3 +echo "15 = 15 mostly young open woodland" >> $TMP3 +echo "16 = 16 young open woodland" >> $TMP3 +echo "17 = 17 moderate open woodland" >> $TMP3 +echo "18 = 18 maturing and moderate open woodland" >> $TMP3 +echo "19 = 19 maturing open woodland" >> $TMP3 +echo "20 = 20 mostly matured open woodland" >> $TMP3 +echo "21 = 21 fully matured woodland" >> $TMP3 +echo "end" >> $TMP3 + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0:1:0.1:0.1" > $TMP4 +echo "2:3:0.15:0.15" >> $TMP4 +echo "4:6:0.1:0.1" >> $TMP4 +echo "7:9:0.09:0.09" >> $TMP4 +echo "10:13:0.08:0.08" >> $TMP4 +echo "13:16:0.07:0.07" >> $TMP4 +echo "17:20:0.06:0.06" >> $TMP4 +echo "21:21:0.05:0.05" >> $TMP4 +echo "end" >> $TMP4 + +TMP5=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then + echo "ERROR: unable to create temporary file for colors" 1>&2 + exit 1 +fi + +echo "0.15 grey" > $TMP5 +echo "0.1 magenta" >> $TMP5 +echo "0.09 red" >> $TMP5 +echo "0.08 orange" >> $TMP5 +echo "0.08 brown" >> $TMP5 +echo "0.06 yellow" >> $TMP5 +echo "0.05 green" >> $TMP5 +echo "end" >> $TMP5 + + + +echo "" +echo "*************************" +echo "step 1 of 4: Calculating MASK" +echo "*************************" +echo "" + +r.mapcalc "temp_background_1=if(isnull($inmap), 21)" +cat $TMP3 | r.reclass --quiet input=temp_background_1 output=temp_background_2 +r.mapcalc "temp_background=if(isnull(temp_background_2), null(), temp_background_2)" +g.remove --quiet rast=temp_background_2,temp_background_1 + + +r.mask input=$inmap maskcats=* + + + +echo "" +echo "*************************" +echo "step 2 of 4: Changing resolution to field size (will be reset)" +echo "*************************" +echo "" + +g.region save=temp_region + +g.region res=$size + + + +echo "" +echo "*************************" +echo "step 3 of 4: Sarting land use evolution calculation. This will start a loop and may take some time. Please do not interrupt the process until it has finished" +echo "*************************" +echo "" + +echo "Year 1" + +r.mapcalc "tmpinreclass = if ($inmap, 0, null())" +r.mapcalc "temp_class0 = if ($inmap, 21, null())" + + +r.random input=tmpinreclass n=$rand"%" raster_output=$prfx"_fields1" + +if [ "$GIS_FLAG_f" -eq 1 ]; then + + echo "fields map = $prfx"_fields1"" + + fi + + + r.patch --quiet input=$prfx"_fields1",temp_class0 output=temp_landuse1_1 + + cat $TMP3 | r.reclass --quiet input=temp_landuse1_1 output=temp_landuse1 + +g.rename --quiet rast=MASK,$prfx"mask" + + r.mapcalc "$prfx"_landuse1" = if (isnull($inmap), temp_background, temp_landuse1)" + + cat $TMP2 | r.colors --quiet map=$prfx"_landuse1" color=rules + + cat $TMP4 | r.recode --quiet input=$prfx"_landuse1" output=$prfx"_cfactor_1" + + cat $TMP5 | r.colors --quiet map=$prfx"_cfactor_1" color=rules + + + temparea=`eval r.stats -n --quiet -a fs=- input=$prfx"_fields1" | cut -d'-' -f2` + echo "" + echo "Area of randomized fields = $temparea square meters" + + + + if [ "$GIS_FLAG_m" -eq 1 ]; then + + r.mapcalc "tempmap_arable=if($prfx"_landuse1" >= 10, 1, null())" + + arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` + + r.mapcalc "tempmap_fallow=if($prfx"_landuse1" > 1 && $prfx"_landuse1" < 10, 1, null())" + + fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` + + g.remove --quiet rast=tempmap_arable,tempmap_fallow + +echo "Stats for $rand"%" ($temparea sq.m) agricultural use of input catchment $inmap" > $txtout +echo "" >> $txtout +echo "Year,Area of potentially arable land (sq.m), Area of non arable fallow land (sq.m)" >> $txtout +echo "1,$arablearea,$fallowarea" >> $txtout + fi + +echo "***********************" +step=1 + + +while [ "$step" -lt "$loop" ] +do + step=$(($step+1)) + echo "Year $step" + laststep=$(($step-1)) + + + tmpcfactor="temp_cfactor_"$step + outcfactor=$prfx"_cfactor_"$step + tmplanduse="temp_landuse"$step + tmp2landuse="temp_landuse"$step"_$step" + outlanduse=$prfx"_landuse"$step + outfields=$prfx"_fields"$step + tcs="temp_class"$step + tcls="temp_landuse"$laststep + +g.rename --quiet rast=$prfx"mask",MASK + + r.random --quiet input=tmpinreclass n=$rand"%" raster_output=$outfields + + if [ "$GIS_FLAG_f" -eq 1 ]; then + + echo "fields map = $outfields" + + fi + + + r.mapcalc "$tcs = if ($tcls < 21, ($tcls + 1), $tcls)" + + r.patch --quiet input=$outfields,$tcs output=$tmp2landuse + + cat $TMP3 | r.reclass --quiet input=$tmp2landuse output=$tmplanduse + +g.rename --quiet rast=MASK,$prfx"mask" + + r.mapcalc "$outlanduse =if (isnull($inmap), temp_background, $tmplanduse)" + + cat $TMP2 | r.colors --quiet map=$outlanduse color=rules + + cat $TMP4 | r.recode --quiet input=$outlanduse output=$outcfactor + + cat $TMP5 | r.colors --quiet map=$outcfactor color=rules + + + temparea=`eval r.stats -n --quiet -a fs=- input=$outfields | cut -d'-' -f2` + echo "" + echo "Field placement re-randomized. Still cultivating $temparea square meters" + + + if [ "$GIS_FLAG_m" -eq 1 ]; then + + r.mapcalc "tempmap_arable=if($outlanduse >= 10, 1, null())" + + arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` + + r.mapcalc "tempmap_fallow=if($outlanduse > 1 && $outlanduse < 10, 1, null())" + + fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` + + g.remove --quiet rast=tempmap_arable,tempmap_fallow + + +echo "$step,$arablearea,$fallowarea" >> $txtout + + fi + +echo "" +echo "" +echo "************************" +echo "" + + +done + + +echo "" +echo "*************************" +echo "step 4 of 4: Cleaning up" +echo "*************************" +echo "" + +if [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_s" -eq 1 ] ; then + +g.remove --quiet rast=tmpinreclass,MASK +g.mremove --quiet -f rast=temp* +g.mremove --quiet -f rast=*mask +g.mremove --quiet -f rast=$prfx"_landuse*" + +elif [ "$GIS_FLAG_f" -eq 0 -a "$GIS_FLAG_s" -eq 1 ] ; then + +g.remove --quiet rast=tmpinreclass,MASK +g.mremove --quiet -f rast=temp* +g.mremove --quiet -f rast=$prfx"_fields*" +g.mremove --quiet -f rast=*mask +g.mremove --quiet -f rast=$prfx"_landuse*" + +elif [ "$GIS_FLAG_f" -eq 1 -a "$GIS_FLAG_s" -eq 0 ] ; then + +g.remove --quiet rast=tmpinreclass,MASK +g.mremove --quiet -f rast=temp* +g.mremove --quiet -f rast=*mask + +else + +g.remove --quiet rast=tmpinreclass,MASK +g.mremove --quiet -f rast=$prfx"_fields*" +g.mremove --quiet -f rast=temp* +g.mremove --quiet -f rast=*mask + +fi + +\rm -f $TMP1 $TMP1.sort +\rm -f $TMP2 $TMP2.sort +\rm -f $TMP3 $TMP3.sort +\rm -f $TMP4 $TMP4.sort +\rm -f $TMP5 $TMP5.sort + + +echo "" +echo "Resetting region" +echo "" + +g.region -g region=temp_region +g.remove region=temp_region + + +echo "" +echo "DONE!" +echo "" +echo "" + Property changes on: trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/LandDyn/r.soildepth/r.soildepth =================================================================== --- trunk/grassaddons/LandDyn/r.soildepth/r.soildepth (rev 0) +++ trunk/grassaddons/LandDyn/r.soildepth/r.soildepth 2007-07-06 22:37:37 UTC (rev 941) @@ -0,0 +1,181 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.soildepth +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Create soil depth map based on hillslope curvature. +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# Based on equations from Heimsath et al, 1997 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Create soil depth map based on hillslope curvature +#%End +#%option +#% key: elev +#% type: string +#% gisprompt: old,cell,raster +#% description: Input elevation map (DEM) +#% required : yes +#%END +#%option +#% key: bedrock +#% type: string +#% gisprompt: old,cell,raster +#% description: Output bedrock elevation map +#% required : yes +#%END +#%option +#% key: soildepth +#% type: string +#% gisprompt: old,cell,raster +#% description: Output soil depths map +#% required : no +#%END +#%option +#% key: kappa +#% type: string +#% description: What is the kappa value (diffusion coefficient per year) for the region? +#% answer: 0.00001 +#% required : yes +#%END +#%option +#% key: t +#% type: integer +#% description: How many years should the soil develop over (how old is the landscape)? +#% answer: 100000 +#% required : yes +#%END +#%flag +#% key: r +#% description: -r Keep soil production rate map +#%END + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + + +elev=$GIS_OPT_elev + +if [ -z $GIS_OPT_soildepth ] ; then + +soildepth="temp_soildepth" + +else + +soildepth=$GIS_OPT_soildepth + +fi + +bedrock=$GIS_OPT_bedrock +kappa=$GIS_OPT_kappa +t=$GIS_OPT_t +pc="temp.pc.deletable" +tc="temp.tc.deletable" +rate="temp.rate.deletable" +meancurv="temp.meancurv.deletable" + +echo "" +echo "STEP 1, calculating profile and tangental curvatures" +echo "" + +r.slope.aspect --quiet $elev pcurv=$pc tcurv=$tc + +echo "" +echo "STEP 2, caclulating rate of soil production from mean hillslope curvatures" +echo "" + +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) will be rescaled from 2 to 0 " +echo "" + + +r.mapcalc "$rate=$kappa*(2-($meancurv*(2/($max)-($min))))" + +rate1=`eval r.univar -g map=$rate percentile=90 | grep "mean=" | cut -d'=' -f2` + +echo "mean rate = $rate1" + +echo "" +echo "STEP 3, calculating soil depth for given amount of time" +echo "" + +echo "age of landscape = $t" +echo "output = $soildepth" + +r.mapcalc "$soildepth = ($rate*10000)" + +meandepth=`eval r.univar -g map=$soildepth percentile=90 | grep "mean=" | cut -d'=' -f2` + +echo "mean depth = $meandepth" +echo "" + +if [ "$GIS_FLAG_r" -eq 1 ]; then +g.remove --q rast=$pc,$tc +g.rename --o --q rast=$rate,$soildepth"_prod_rate" +else +g.remove --q rast=$pc,$tc,$rate,$meancurv +fi + + + + +echo "" +echo "STEP 4, calculating bedrock elevation for given soil depth" +echo "" + +r.mapcalc "$bedrock=($elev) - ($soildepth)" + +if [ -n "$GIS_OPT_soildepth" ]; then +echo "" +echo " DONE!" +echo "" +echo "########################################################" +echo "# #" +echo "# Soil depth map = $soildepth #" +echo "# Bedrock elevation map = $bedrock #" + +else +echo "" +echo " DONE!" +echo "" +echo "########################################################" +echo "# #" +echo "# #" +echo "# Bedrock elevation map = $bedrock #" + +g.remove --quiet rast=$soildepth + +fi + +if [ "$GIS_FLAG_r" -eq 1 ]; then +echo "# Soil production rate map = $soildepth"_prod_rate" #" +echo "# #" +echo "########################################################" +else +echo "# #" +echo "########################################################" +fi + + Property changes on: trunk/grassaddons/LandDyn/r.soildepth/r.soildepth ___________________________________________________________________ Name: svn:executable + * From ullah at grass.itc.it Sat Jul 7 00:40:21 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Sat Jul 7 00:40:23 2007 Subject: [grass-addons] r942 - trunk/grassaddons/LandDyn Message-ID: <200707062240.l66MeLmp020932@grass.itc.it> Author: ullah Date: 2007-07-07 00:40:16 +0200 (Sat, 07 Jul 2007) New Revision: 942 Removed: trunk/grassaddons/LandDyn/r.landscape_evol/ Log: replaced by r.landscape.evol From ullah at grass.itc.it Sat Jul 7 01:08:33 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Sat Jul 7 01:08:34 2007 Subject: [grass-addons] r943 - trunk/grassaddons/LandDyn/r.aggregate.stats Message-ID: <200707062308.l66N8X5b021390@grass.itc.it> Author: ullah Date: 2007-07-07 01:08:27 +0200 (Sat, 07 Jul 2007) New Revision: 943 Modified: trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats Log: changed script to accept suffix search patterns as well Modified: trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats =================================================================== --- trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats 2007-07-06 22:40:16 UTC (rev 942) +++ trunk/grassaddons/LandDyn/r.aggregate.stats/r.aggregate.stats 2007-07-06 23:08:27 UTC (rev 943) @@ -4,8 +4,8 @@ # # MODULE: r.aggregate.stats # AUTHOR(S): Isaac Ullah, Arizona State University -# PURPOSE: Aggregates a series of maps (based on a shared prefix) using r.series, then calculates summary -# statistics for the aggragate map. +# PURPOSE: Aggregates a series of maps (based on a shared file name pattern) using r.series, +# then calculates univariate statistics for the aggragate map. # ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 # COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University # This program is free software under the GNU General Public @@ -16,14 +16,14 @@ #%Module -#% description: Aggregates a series of maps (based on a shared prefix) using r.series, then calculates summary statistics for the aggragate map. +#% description: Aggregates a series of maps (based on a shared file name pattern) using r.series, then calculates univariate statistics for the aggragate map. #%END #%option -#% key: prefix +#% key: pattern #% type: string #% gisprompt: old,cell,raster -#% description: prefix of series +#% description: Pattern of first part of file names (prefixes) for map series (use -f if for suffixes) #% required : yes #%END @@ -33,18 +33,23 @@ #% answer: average #% options: average,count,median,mode,minimum,min_raster,maximum,max_raster,stddev,sum,variance,diversity,slope,offset,quart1,quart3,perc90 #% required : yes -#% description: method of aggregating map series (see r.series help for option descriptions) +#% description: Method of aggregating map series (see r.series help for option descriptions) #% required : yes #%END #%flag +#% key: f +#% description: -f Search pattern is for suffixes (last part of file names) +#%END + +#%flag #% key: s #% description: -s Only calculate sum of aggregate map #%END #%flag #% key: k -#% description: -k Keep aggregate map (will be called "'prefix'_'method'") +#% description: -k Keep aggregate map (will be called "'pattern'_'method'") #%END @@ -59,15 +64,22 @@ fi - prefix=$GIS_OPT_prefix + pattern=$GIS_OPT_pattern method=$GIS_OPT_method - string=$prefix"_temp_list.txt" + string=$pattern"_temp_list.txt" -g.mlist --quiet type=rast sep=, pattern=$prefix"*" > $string +if [ "$GIS_FLAG_s" -eq 1 ]; then +g.mlist --quiet type=rast sep=, pattern="*"$pattern > $string - tempmap=$prefix"_temp_aggregate" +else +g.mlist --quiet type=rast sep=, pattern=$pattern"*" > $string + +fi + + tempmap=$pattern"_temp_aggregate" + r.series input=`cat $string` output=$tempmap method=$method if [ "$GIS_FLAG_s" -eq 1 ]; then @@ -97,7 +109,7 @@ if [ "$GIS_FLAG_k" -eq 1 ]; then - output=$prefix"_"$method + output=$pattern"_"$method g.rename --quiet rast=$tempmap,$output From barton at grass.itc.it Sat Jul 7 18:46:03 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Jul 7 18:46:05 2007 Subject: [grass-addons] r944 - trunk/grassaddons/gui Message-ID: <200707071646.l67Gk3PV016068@grass.itc.it> Author: barton Date: 2007-07-07 18:45:53 +0200 (Sat, 07 Jul 2007) New Revision: 944 Modified: trunk/grassaddons/gui/location_wizard.py Log: Clean up MessageBox strings for final location creation output. Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-07-06 23:08:27 UTC (rev 943) +++ trunk/grassaddons/gui/location_wizard.py 2007-07-07 16:45:53 UTC (rev 944) @@ -575,17 +575,19 @@ def OnDText(self, event): self.datum = event.GetString() - self.datumdesc = self.parent.datums[self.datum][0] - self.ellipsoid = self.parent.datums[self.datum][1] - self.datumparams = self.parent.datums[self.datum][2] + if self.datum in self.parent.datums: + self.datumdesc = self.parent.datums[self.datum][0] + self.ellipsoid = self.parent.datums[self.datum][1] + self.datumparams = self.parent.datums[self.datum][2] self._onBrowseParams(None,self.datum) def OnTText(self, event): self.transform = event.GetString() - self.transdatum = self.parent.transforms[self.transform][0] - self.transregion = self.parent.transforms[self.transform][1] - self.transparams = self.parent.transforms[self.transform][2] + if self.transform in self.parent.transforms: + self.transdatum = self.parent.transforms[self.transform][0] + self.transregion = self.parent.transforms[self.transform][1] + self.transparams = self.parent.transforms[self.transform][2] def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -1822,9 +1824,11 @@ proj4string = '%s %s' % (proj4string, proj4params) - dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to \n\ - %s: %s%s\n\ - (PROJ.4 string: %s)" % (location,projdesc,datumdesc,ellipsedesc,proj4string), + msgtext = "New location '%s' will be created georeferenced to" % location + georeftext = '%s: %s%s' % (projdesc,datumdesc,ellipsedesc) + p4text = '(PROJ.4 string: %s)' % proj4string + + dlg = wx.MessageDialog(self.wizard, msgtext+' '+georeftext+' '+p4text, "Create new location?", wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_NO: @@ -1849,8 +1853,8 @@ def CustomCreate(self): proj4string = self.custompage.proj4string - dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created using \ - PROJ.4 string: %s" % (location,proj4string), + dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created using PROJ.4 string: %s" + % (location,proj4string), "Create new location?", wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_NO: @@ -1888,8 +1892,8 @@ dlg.Destroy() return False - dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to \ - EPSG code %s: %s" % (location, epsgcode, epsgdesc), + dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to EPSG code %s: %s" + % (location, epsgcode, epsgdesc), "Create new location from EPSG code?", wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_NO: @@ -1947,7 +1951,7 @@ cmdlist = [] - dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to file '%s'"\ + dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to file '%s'" % (location, georeffile), "Create new location from georeferenced file?", wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_NO: From bundala at grass.itc.it Sat Jul 7 21:44:33 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Sat Jul 7 21:44:35 2007 Subject: [grass-addons] r945 - trunk/grassaddons/v.generalize Message-ID: <200707071944.l67JiXrQ017274@grass.itc.it> Author: bundala Date: 2007-07-07 21:44:27 +0200 (Sat, 07 Jul 2007) New Revision: 945 Added: trunk/grassaddons/v.generalize/pq.c trunk/grassaddons/v.generalize/pq.h Modified: trunk/grassaddons/v.generalize/description.html trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/misc.c trunk/grassaddons/v.generalize/misc.h trunk/grassaddons/v.generalize/simplification.c Log: Douglas-Peucker Reduction Algorithm, binary max heap, slightly cleaner code Modified: trunk/grassaddons/v.generalize/description.html =================================================================== --- trunk/grassaddons/v.generalize/description.html 2007-07-07 16:45:53 UTC (rev 944) +++ trunk/grassaddons/v.generalize/description.html 2007-07-07 19:44:27 UTC (rev 945) @@ -35,10 +35,12 @@

  • Vertex Reduction
  • Reumann-Witkam Algorithm
  • + Different algortihms requires different parameters, but all the algorithms have one parameter in common. It is threshold parameter. In general, the degree @@ -49,6 +51,11 @@
  • Douglas-Peucker - "Quicksort" of line simplification, the most widely used algorithm. Input parameters: input, threshold. For more information, please check: http://geometryalgorithms.com/Archive/algorithm_0205/algorithm_0205.htm.
  • +
  • Douglas-Peucker Reduction Algorithm is essentially the same algorithm as the + algorithm above. The difference is that it takes additional parameter reduction + which denotes the percentage of the number of points on the new line with respect + to the number of points on the original line. Input parameters: input, + threshold, reduction.
  • Lang - Another standard algorithm. Input parameters: input, threshold, look_ahead. For an excellent description, check: http://www.sli.unimelb.edu.au/gisweb/LGmodule/LGLangVisualisation.htm.
  • Vertex Reduction - Simplest among the algorithms. Input parameters: input, threshold. @@ -61,6 +68,25 @@ check http://www.ifp.uni-stuttgart.de/lehre/vorlesungen/GIS1/Lernmodule/Lg/LG_de_6.html(german)
  • +

    +Douglas-Peucker and Douglas-Peucker Reduction Algorithm use the same method +to simplify the lines. Note that +

    +v.generalize input=in output=out method=douglas threshold=eps
    +
    +is equivalent to +
    +v.generalize input=in output=out method=douglas_reduction threshold=eps reduction=0
    +
    +However, in this case, the first method is faster. Also observe that +douglas_reduction never outputs less vertices than douglas. And that, +in general, douglas is more efficient than douglas_reduction. +Also, the effect of +
    +v.generalize input=in output=out method=douglas_reduction threshold=0 reduction=X
    +
    +is that 'out' contains approximately only X% of points of 'in'. +

    SMOOTHING

    @@ -71,7 +97,7 @@

  • McMaster's Distance-Weighting Algorithm - Works by taking the weighted average of look_ahead consecutive points where the weight is the distance from the point to the currently smoothed point. And parameter threshold is used for linear interpolation between the original position of the point and newly computed position where value 0 means the original position. - Input parameters: input, threshold, look_ahead. + Input parameters: input, threshold, look_ahead.
  • Chaiken's Algorithm - "Inscribes" a line touching the original line such that the points on this new line are at least threshold apart. Input parameters: input, threshold. This algorithms @@ -114,4 +140,4 @@
    Wolf Bergenheim, Mentor -

    Last changed: $Date: 2007/04/07 23:17:35 $ +

    Last changed: $Date: 2007/07/07 21:38:06 $ Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-07 16:45:53 UTC (rev 944) +++ trunk/grassaddons/v.generalize/main.c 2007-07-07 19:44:27 UTC (rev 945) @@ -23,7 +23,7 @@ #include #include "misc.h" -#define DOUGLASS 0 +#define DOUGLAS 0 #define LANG 1 #define VERTEX_REDUCTION 2 #define REUMANN 3 @@ -32,6 +32,7 @@ #define CHAIKEN 6 #define HERMITE 7 #define SNAKES 8 +#define DOUGLAS_REDUCTION 9 int main(int argc, char *argv[]) { @@ -43,10 +44,10 @@ struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out, *thresh_opt, *method_opt, *look_ahead_opt; struct Option *iterations_opt, *cat_opt, *alfa_opt, *beta_opt, *type_opt; - struct Option *field_opt, *where_opt; + struct Option *field_opt, *where_opt, *reduction_opt; int with_z; int total_input, total_output; /* Number of points in the input/output map respectively */ - double thresh, alfa, beta; + double thresh, alfa, beta, reduction; int method; int look_ahead, iterations; int chcat; @@ -55,6 +56,7 @@ double x, y; int simplification, mask_type; VARRAY *varray; + char *s; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */ @@ -78,9 +80,10 @@ method_opt->required = YES; method_opt->multiple = NO; method_opt->options = - "douglas,lang,reduction,reumann,boyle,distance_weighting,chaiken,hermite,snakes"; + "douglas,douglas_reduction,lang,reduction,reumann,boyle,distance_weighting,chaiken,hermite,snakes"; method_opt->answer = "douglas"; - method_opt->descriptions = _("douglas;Douglass-Peucker Algorithm;" + method_opt->descriptions = _("douglas;Douglas-Peucker Algorithm;" + "douglas_reduction;Douglas-Peucker Algorithm with reduction parameter;" "lang;Lang Simplification Algorithm;" "reduction;Vertex Reduction Algorithm eliminates points close to each other;" "reumann;Reumann-Witkam Algorithm;" @@ -106,6 +109,16 @@ look_ahead_opt->answer = "7"; look_ahead_opt->description = _("Look-ahead parameter"); + reduction_opt = G_define_option(); + reduction_opt->key = "reduction"; + reduction_opt->type = TYPE_DOUBLE; + reduction_opt->required = YES; + reduction_opt->answer = "50"; + reduction_opt->options = "0-100"; + reduction_opt->description = + _ + ("Percentage of the points in the output of 'douglas_reduction' algorithm"); + alfa_opt = G_define_option(); alfa_opt->key = "alfa"; alfa_opt->type = TYPE_DOUBLE; @@ -139,42 +152,39 @@ look_ahead = atoi(look_ahead_opt->answer); alfa = atof(alfa_opt->answer); beta = atof(beta_opt->answer); + reduction = atof(reduction_opt->answer); iterations = atoi(iterations_opt->answer); mask_type = type_mask(type_opt); G_debug(3, "Method: %s", method_opt->answer); - if (method_opt->answer[0] == 'd' && method_opt->answer[1] == 'o') { - method = DOUGLASS; - } - else if (method_opt->answer[0] == 'l') { + s = method_opt->answer; + + if (strcmp(s, "douglas") == 0) + method = DOUGLAS; + else if (strcmp(s, "lang") == 0) method = LANG; - } - else if (method_opt->answer[0] == 'v') { + else if (strcmp(s, "reduction") == 0) method = VERTEX_REDUCTION; - } - else if (method_opt->answer[0] == 'r') { + else if (strcmp(s, "reumann") == 0) method = REUMANN; - } - else if (method_opt->answer[0] == 'b') { + else if (strcmp(s, "boyle") == 0) method = BOYLE; - } - else if (method_opt->answer[0] == 'd') { + else if (strcmp(s, "distance_weighting") == 0) method = DISTANCE_WEIGHTING; - } - else if (method_opt->answer[0] == 'c') { + else if (strcmp(s, "chaiken") == 0) method = CHAIKEN; - } - else if (method_opt->answer[0] == 'h') { + else if (strcmp(s, "hermite") == 0) method = HERMITE; - } - else { + else if (strcmp(s, "snakes") == 0) method = SNAKES; - }; + else if (strcmp(s, "douglas_reduction") == 0) + method = DOUGLAS_REDUCTION; + /* simplification or smoothing? */ switch (method) { - case DOUGLASS: + case DOUGLAS: case LANG: case VERTEX_REDUCTION: case REUMANN: @@ -254,9 +264,13 @@ int after = 0; for (iter = 0; iter < iterations; iter++) { switch (method) { - case DOUGLASS: - douglass_peucker(Points, thresh, with_z); + case DOUGLAS: + douglas_peucker(Points, thresh, with_z); break; + case DOUGLAS_REDUCTION: + douglas_peucker_reduction(Points, thresh, reduction, + with_z); + break; case LANG: lang(Points, thresh, look_ahead, with_z); break; Modified: trunk/grassaddons/v.generalize/misc.c =================================================================== --- trunk/grassaddons/v.generalize/misc.c 2007-07-07 16:45:53 UTC (rev 944) +++ trunk/grassaddons/v.generalize/misc.c 2007-07-07 19:44:27 UTC (rev 945) @@ -38,3 +38,33 @@ return res; }; +int get_furthest(struct line_pnts *Points, int a, int b, int with_z, + double *dist) +{ + int index = a; + double d = 0; + + int i; + double x0 = Points->x[a]; + double x1 = Points->x[b]; + double y0 = Points->y[a]; + double y1 = Points->y[b]; + double z0 = Points->z[a]; + double z1 = Points->z[b]; + + double px, py, pz, pdist, di; + int status; + + for (i = a + 1; i < b; i++) { + di = dig_distance2_point_to_line(Points->x[i], Points->y[i], + Points->z[i], x0, y0, z0, x1, y1, z1, + with_z, &px, &py, &pz, &pdist, + &status); + if (di > d) { + d = di; + index = i; + }; + }; + *dist = d; + return index; +}; Modified: trunk/grassaddons/v.generalize/misc.h =================================================================== --- trunk/grassaddons/v.generalize/misc.h 2007-07-07 16:45:53 UTC (rev 944) +++ trunk/grassaddons/v.generalize/misc.h 2007-07-07 19:44:27 UTC (rev 945) @@ -1,9 +1,18 @@ #ifndef MISC_H_ #define MISC_H_ +#include + /* returns bitmask for all the types specified in type_opt * e.g GV_LINE | GV_BOUNDARY */ -int type_mask(struct Option *type_opt); +extern int type_mask(struct Option *type_opt); +/* returns the squared distance and the index of the point furthest + * from the line segment Points[a], Points[b] such that the + * index of this points is in [a,b] + */ +extern int get_furthest(struct line_pnts *Points, int a, int b, int with_z, + double *dist); + #endif Added: trunk/grassaddons/v.generalize/pq.c =================================================================== --- trunk/grassaddons/v.generalize/pq.c (rev 0) +++ trunk/grassaddons/v.generalize/pq.c 2007-07-07 19:44:27 UTC (rev 945) @@ -0,0 +1,100 @@ + +/**************************************************************** + * + * MODULE: v.generalize + * + * AUTHOR(S): Daniel Bundala + * + * PURPOSE: priority queue / binary heap + * + * + * COPYRIGHT: (C) 2002-2005 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 "pq.h" + +int binary_heap_init(int size, binary_heap * bh) +{ + bh->items = 0; + bh->key = (double *)G_malloc(sizeof(double) * (size + 1)); + if (bh->key == NULL) + return 0; + bh->value = (int *)G_malloc(sizeof(int) * (size + 1)); + if (bh->value == NULL) { + G_free(bh->key); + return 0; + }; + return 1; +}; + +void binary_heap_free(binary_heap * bh) +{ + G_free(bh->key); + G_free(bh->value); + return; +}; + +void binary_heap_push(double key, int value, binary_heap * bh) +{ + int i = ++(bh->items); + + while (i != 1 && key > bh->key[i / 2]) { + bh->key[i] = bh->key[i / 2]; + bh->value[i] = bh->value[i / 2]; + i /= 2; + }; + + bh->key[i] = key; + bh->value[i] = value; + return; +}; + +int binary_heap_extract_max(binary_heap * bh, int *value) +{ + int n = bh->items; + if (n == 0) + return 0; + *value = bh->value[1]; + + + bh->key[1] = bh->key[n]; + bh->value[1] = bh->value[n]; + + int i = 1; + double td; + int tv; + + + while (1) { + int greater = i; + int left = 2 * i; + int right = 2 * i + 1; + + if (left < n && bh->key[left] > bh->key[i]) + greater = left; + if (right < n && bh->key[right] > bh->key[greater]) + greater = right; + + if (greater = i) + break; + + td = bh->key[i]; + bh->key[i] = bh->key[greater]; + bh->key[greater] = td; + + tv = bh->value[i]; + bh->value[i] = bh->value[greater]; + bh->value[greater] = tv; + + i = greater; + }; + + bh->items--; + return 1; +}; Property changes on: trunk/grassaddons/v.generalize/pq.c ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/v.generalize/pq.h =================================================================== --- trunk/grassaddons/v.generalize/pq.h (rev 0) +++ trunk/grassaddons/v.generalize/pq.h 2007-07-07 19:44:27 UTC (rev 945) @@ -0,0 +1,50 @@ + +/**************************************************************** + * + * MODULE: v.generalize + * + * AUTHOR(S): Daniel Bundala + * + * PURPOSE: priority queue / binary max heap + * + * + * COPYRIGHT: (C) 2002-2005 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. + * + ****************************************************************/ + +#ifndef PQ_H +#define PQ_H + +#include + +/* None of the functions below tests overflows, + * only extract_max treats underflow */ + +typedef struct +{ + int items; + double *key; + int *value; +} binary_heap; + +/* initializes new empty binary heap. Returns 1 + * on success, 0 otherwise */ +int binary_heap_init(int size, binary_heap * bh); + +/* frees the memory occupied by a heap */ +void binary_heap_free(binary_heap * bh); + +/* this function pushes (key, value) to the heap */ +void binary_heap_push(double key, int value, binary_heap * bh); + +/* passes the key of the element with the highest key and + * deletes this key. Returns 1 on success, 0 on empty heap */ +int binary_heap_extract_max(binary_heap * bh, int *value); + + +#endif Property changes on: trunk/grassaddons/v.generalize/pq.h ___________________________________________________________________ Name: svn:executable + * Modified: trunk/grassaddons/v.generalize/simplification.c =================================================================== --- trunk/grassaddons/v.generalize/simplification.c 2007-07-07 16:45:53 UTC (rev 944) +++ trunk/grassaddons/v.generalize/simplification.c 2007-07-07 19:44:27 UTC (rev 945) @@ -22,9 +22,9 @@ #include #include #include "point.h" +#include "pq.h" - -int douglass_peucker(struct line_pnts *Points, double thresh, int with_z) +int douglas_peucker(struct line_pnts *Points, double thresh, int with_z) { int *stack = G_malloc(sizeof(int) * Points->n_points * 2); @@ -91,7 +91,7 @@ index[icount++] = last; } else { - /* break line into two parts, the order of pushing is crucial! It gurantees, that we are going to theleft */ + /* break line into two parts, the order of pushing is crucial! It gurantees, that we are going to the left */ stack[top++] = maxindex; stack[top++] = last; stack[top++] = first; @@ -253,7 +253,7 @@ diffd = point_dist2(diff); sp = point_dot(diff, sub); dist = (diffd * subd - sp * sp) / subd; - /* if the point is out of the threshlod-sausage, store it a calculates + /* if the point is out of the threshlod-sausage, store it and calculate * all variables which do not change for each line-point calculation */ if (dist > thresh) { @@ -294,3 +294,118 @@ return Points->n_points; }; + +/* douglas-peucker algorithm which simplifies a line to a line with + * at most reduction% of points. + * returns the number of points in the output line. It is approx + * reduction/100 * Points->n_points. + */ +int douglas_peucker_reduction(struct line_pnts *Points, double thresh, + double reduction, int with_z) +{ + + int i; + int n = Points->n_points; + /* the maximum number of points which may be + * included in the output */ + int nexp = n * (reduction / (double)100.0); + /* line too short */ + if (n < 3) + return n; + + /* indicates which point were selected by the algorithm */ + int *sel; + sel = G_calloc(sizeof(int), n); + if (sel == NULL) { + G_fatal_error(_("Out of memory")); + return n; + }; + + /* array used for storing the indices of line segments+furthest point */ + int *index; + index = G_malloc(sizeof(int) * 3 * n); + if (index == NULL) { + G_fatal_error(_("Out of memory")); + G_free(sel); + return n; + }; + + int indices; + + /* preserve first and last point */ + sel[0] = sel[n - 1] = 1; + nexp -= 2; + + thresh *= thresh; + + double d; + int mid = get_furthest(Points, 0, n - 1, with_z, &d); + int em; + + /* priority queue of line segments, + * key is the distance of the furthest point */ + binary_heap pq; + if (!binary_heap_init(n, &pq)) { + G_fatal_error(_("Out of memory")); + G_free(sel); + G_free(index); + return n; + }; + + + if (d > thresh) { + index[0] = 0; + index[1] = n - 1; + index[2] = mid; + binary_heap_push(d, 0, &pq); + indices = 3; + }; + + /* while we can add new points and queue is non-empty */ + while (nexp > 0) { + /* empty heap */ + if (!binary_heap_extract_max(&pq, &em)) + break; + int left = index[em]; + int right = index[em + 1]; + int furt = index[em + 2]; + /*mark the furthest point */ + sel[furt] = 1; + nexp--; + + /* consider left and right segment */ + mid = get_furthest(Points, left, furt, with_z, &d); + if (d > thresh) { + binary_heap_push(d, indices, &pq); + index[indices++] = left; + index[indices++] = furt; + index[indices++] = mid; + }; + + mid = get_furthest(Points, furt, right, with_z, &d); + if (d > thresh) { + binary_heap_push(d, indices, &pq); + index[indices++] = furt; + index[indices++] = right; + index[indices++] = mid; + }; + + }; + + /* copy selected points */ + int selected = 0; + for (i = 0; i < n; i++) { + if (sel[i]) { + Points->x[selected] = Points->x[i]; + Points->y[selected] = Points->y[i]; + Points->z[selected] = Points->z[i]; + selected++; + }; + }; + + G_free(sel); + G_free(index); + binary_heap_free(&pq); + Points->n_points = selected; + return Points->n_points; +}; From landa at grass.itc.it Mon Jul 9 18:10:11 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Mon Jul 9 18:10:15 2007 Subject: [grass-addons] r946 - in trunk/grassaddons/gui: gui_modules icons Message-ID: <200707091610.l69GABwe027448@grass.itc.it> Author: landa Date: 2007-07-09 18:10:11 +0200 (Mon, 09 Jul 2007) New Revision: 946 Modified: 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/gui_modules/wxgui_utils.py trunk/grassaddons/gui/icons/icon.py Log: Digitization tool: Various updates, experimental DisplayDriver introduced -- based on SWIG-Python interface, EXTREMELY SLOW!!! Will replaced by C/C++ driver in the future Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-07-07 19:44:27 UTC (rev 945) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-07-09 16:10:11 UTC (rev 946) @@ -610,6 +610,8 @@ self.qdist = qdist self.action = action + self.selectedLines = [] # id of selected feature + self.mapInfo = VectorAttributesInfo(self.map) if self.layer > 0 and \ @@ -636,7 +638,10 @@ self.layer != layer: continue - found, selected = self.mapInfo.SelectFromTable(layer, self.cat, self.queryCoords, self.qdist) + # line detected, number of selected records + line, selected = self.mapInfo.SelectFromTable(layer, self.cat, + self.queryCoords, self.qdist) + if (self.action == "add" and selected > 0) or \ self.action == "update": self.SetTitle(_("Update attributes")) @@ -645,10 +650,13 @@ else: self.SetTitle(_("Display attributes")) - if not found or \ - (self.action != "add" and selected == 0): + if not line or \ + (self.action != "add" 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)) @@ -819,7 +827,8 @@ """Check DB connection""" layerCommand = cmd.Command(cmd=["v.db.connect", "-g", "--q", - "map=%s" % self.map]) + "map=%s" % self.map,], + dlgMsg='txt') if layerCommand.returncode != 0: return False @@ -863,11 +872,11 @@ """ table = self.layers[layer]["table"] selected = 0 - found = False + line = None if queryCoords: # snapping distance cmdWhat = cmd.Command(cmd=['v.what', - '-a', '--q', + '-a', '-d', '--q', 'map=%s' % self.map, 'east_north=%f,%f' % \ (float(queryCoords[0]), float(queryCoords[1])), @@ -882,12 +891,13 @@ name = name.strip() self.tables[table][name][1] = value.strip() selected+=1; - if "category" in item.lower(): + 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(): + elif "key column:" in item.lower(): read = True else: - found = True # select values selectCommand = cmd.Command(cmd=["v.db.select", "-v", "--q", "map=%s" % self.map, @@ -900,7 +910,7 @@ self.tables[table][name][1] = value selected+=1 - return (found, selected) + return (line, selected) def main(argv=None): if argv is None: Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-07-07 19:44:27 UTC (rev 945) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-07-09 16:10:11 UTC (rev 946) @@ -4,6 +4,7 @@ CLASSES: * VEdit * VDigit + * DisplayDriver * SettingsDialog PURPOSE: Digitization tool wxPython GUI prototype @@ -23,6 +24,9 @@ for details. """ +import sys +import string + import wx import wx.lib.colourselect as csel @@ -30,12 +34,25 @@ import dbm from debug import Debug as Debug +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." + class AbstractDigit: """ Abstract digitization class """ def __init__(self, settings=None): - self.map = None + self.map = None + self.driver = None + if not settings: self.settings = {} # symbology @@ -51,6 +68,7 @@ self.settings["symbolCentroidDup"] = (True, "violet") self.settings["symbolNodeOne"] = (True, "red") self.settings["symbolNodeTwo"] = (True, "dark green") + self.settings["symbolVertex"] = (True, "pink") # display self.settings["snapping"] = (10, "screen pixels") # value, unit @@ -102,11 +120,20 @@ return self.settings["category"] - def ReInitialize(self, map): + def ReInitialize(self, map=None, mapwindow=None): """Re-initialize settings according selected map layer""" self.map = map - self.SetCategory() - + + if self.map: + Debug.msg (3, "AbstractDigit.ReInitialize(): map=%s" % \ + map) + + self.SetCategory() + self.driver = DisplayDriver(map, mapwindow) + else: + del self.driver + self.driver = None + class VEdit(AbstractDigit): """ Prototype of digitization class based on v.edit command @@ -133,8 +160,9 @@ Debug.msg (3, "VEdit.AddPoint(): map=%s, type=%s, layer=%d, cat=%d, x=%f, y=%f" % \ (map, type, layer, cat, x, y)) - - self._AddFeature (map=map, input=addstring) + Debug.msg (4, "Vline.AddPoint(): input=%s" % addstring) + + self._AddFeature (map=map, input=addstring, flags=['-s']) def AddLine (self, map, type, coords): """ @@ -148,8 +176,10 @@ if type == "boundary": key = "B" + flags = ['-c', '-s'] # close boundaries else: key = "L" + flags = ['-s'] addstring="""%s %d 1\n""" % (key, len(coords)) for point in coords: @@ -162,20 +192,58 @@ (key, layer, cat, coords)) Debug.msg (4, "Vline.AddLine(): input=%s" % addstring) - self._AddFeature (map=map, input=addstring) + self._AddFeature (map=map, input=addstring, flags=flags) - def _AddFeature (self, map, input): + def _AddFeature (self, map, input, flags): """ General method which adds feature to the vector map """ - command = ["v.edit", "-n", "--q", + threshold = Digit.settings["snapping"][0] + if Digit.settings["snapping"][1] == "screen pixels": + # pixel -> cell + print "#", threshold + threshold = self.driver.mapwindow.Distance(beginpt=(0,0), + endpt=(threshold,0)) + + + print "#", threshold + + command = ["v.edit", "-n", "--q", "map=%s" % map, "tool=add", - "thresh=-1.0" ] + "thresh=%f" % threshold] + # additional flags + for flag in flags: + command.append(flag) # run the command vedit = cmd.Command(cmd=command, stdin=input) + # redraw map + self.driver.ReDrawMap(map) + + def DeleteSelectedLines(self): + """Delete vector feature from map""" + + if not self.driver.highlighted: + Debug.msg(4, "Digit.DeleteSelectedLines(): ids=%s" % \ + self.driver.highligted) + return False + + ids = ",".join(["%d" % v for v in self.driver.highlighted]) + command = ["v.edit", "-n", "--q", + "map=%s" % self.map, + "tool=delete", + "ids=%s" % ids] + + # run the command + vedit = cmd.Command(cmd=command) + + # redraw map + self.driver.ReDrawMap(self.map) + + return True + class VDigit(AbstractDigit): """ Prototype of digitization class based on v.digit reimplementation @@ -184,6 +252,252 @@ """ pass +class DisplayDriver: + """ + 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, map, mapwindow): + self.mapwindow = mapwindow + self.ids = {} # dict[g6id] = [DCid] + self.highlighted = [] # list of highlighted objects (g6id) + + g6lib.G_gisinit('') + + 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 __del__(self): + if self.mapInfo: + g6lib.Vect_close(self.mapInfo) + if self.points: + g6lib.Vect_destroy_line_struct(self.points) + if self.cats: + g6lib.Vect_destroy_cats_struct(self.cats) + + def __SetPen(self, line, symbol): + # see include/vect/dig_defines.h + # define GV_POINT 0x01 + # define GV_LINE 0x02 + # define GV_BOUNDARY 0x04 + # define GV_CENTROID 0x08 + # define GV_FACE 0x10 + # define GV_KERNEL 0x20 + # define GV_AREA 0x40 + # define GV_VOLUME 0x80 + + if line in self.highlighted: + symbol = "symbolHighlight" + + width = Digit.settings["lineWidth"][0] + + if Digit.settings[symbol][0] in [True, None]: + self.mapwindow.pen = self.mapwindow.polypen = wx.Pen(colour=Digit.settings[symbol][1], + width=width, style=wx.SOLID) + else: + self.mapwindow.pen = self.mapwindow.polypen = None + + def SetHighlighted(self, ids): + """Set highlighted objects in PseudoDC + + For disable highlighting set ids=[] + """ + # reset + self.highlighted = [] + + for line in ids: + self.highlighted.append(line) + + Debug.msg(4, "DisplayDriver.SetHightlighted(): dcIds=%s, lineIds=%s" % \ + (ids, self.highlighted)) + + def SelectLinesByBox(self, rect): + """Alternative method for selecting vector feature + in the map by given bounding box. + + rect = ((x1, y1), (x2, y2)) + This method should be in the future reimplemented using + PseudoDC.FindObjectInsideBBox()""" + + type = 255 # all types (see include/vect/dig_defines.h) + 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) + + self.highligted = [] + for idx in range(list.n_values): + line = g6lib.intArray_getitem(list.value, idx) + if line not in self.highlighted: + self.highlighted.append(line) + + Debug.msg(4, "DisplayDriver.SelectLinesByBox(%s): n=%d, ids=%s" % \ + (rect, list.n_values, self.highlighted)) + + g6lib.Vect_destroy_line_struct(bbox) + g6lib.Vect_destroy_list(list) + + return self.highlighted + + 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): + """Draw map content in PseudoDC""" + Debug.msg(4, "DisplayDriver.DrawMap()") + self.DisplayLines() + + def DisplayLines(self): + """Display all lines in PseudoDC""" + nlines = g6lib.Vect_get_num_lines(self.mapInfo) + Debug.msg(4, "DisplayDriver.DisplayLines(): nlines=%d" % nlines) + #symb_set_driver_color ( SYMB_HIGHLIGHT ); + for line in range(1, nlines + 1): + #symb = LineSymb[i]; + #if ( !Symb[symb].on ) continue; + 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)) + class DigitSettingsDialog(wx.Dialog): """ Standard settings dialog for digitization purposes @@ -371,7 +685,8 @@ ("Centroid (outside area)", "symbolCentroidOut"), ("Centroid (duplicate in area)", "symbolCentroidDup"), ("Node (one line)", "symbolNodeOne"), - ("Node (two lines)", "symbolNodeTwo")) + ("Node (two lines)", "symbolNodeTwo"), + ("Vertex", "symbolVertex")) def OnChangeCategoryMode(self, event): """Change category mode""" Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-07 19:44:27 UTC (rev 945) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-09 16:10:11 UTC (rev 946) @@ -223,7 +223,6 @@ """ Draws map and overlay decorations """ - if drawid == None: if pdctype == 'image' : drawid = imagedict[img] @@ -250,7 +249,7 @@ if pdctype == 'clear': # erase the display bg = wx.WHITE_BRUSH -# bg = wx.Brush(self.GetBackgroundColour()) + # bg = wx.Brush(self.GetBackgroundColour()) pdc.SetBackground(bg) pdc.Clear() self.Refresh() @@ -264,56 +263,59 @@ pdc.SetIdBounds(drawid, (coords[0],coords[1],w,h)) elif pdctype == 'box': # draw a box on top of the map - pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) - pdc.SetPen(self.pen) - x2 = max(coords[0],coords[2]) - x1 = min(coords[0],coords[2]) - y2 = max(coords[1],coords[3]) - y1 = min(coords[1],coords[3]) - rwidth = x2-x1 - rheight = y2-y1 - rect = wx.Rect(x1,y1,rwidth,rheight) - pdc.DrawRectangleRect(rect) - pdc.SetIdBounds(drawid,rect) - self.ovlcoords[drawid] = coords + if self.pen: + pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) + pdc.SetPen(self.pen) + x2 = max(coords[0],coords[2]) + x1 = min(coords[0],coords[2]) + y2 = max(coords[1],coords[3]) + y1 = min(coords[1],coords[3]) + rwidth = x2-x1 + rheight = y2-y1 + rect = wx.Rect(x1,y1,rwidth,rheight) + pdc.DrawRectangleRect(rect) + pdc.SetIdBounds(drawid,rect) + self.ovlcoords[drawid] = coords elif pdctype == 'line': # draw a line on top of the map - pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) - pdc.SetPen(self.pen) - pdc.DrawLine(coords[0], coords[1], coords[2], coords[3]) - pdc.SetIdBounds(drawid,(coords[0], coords[1], coords[2], coords[3])) - self.ovlcoords[drawid] = coords + if self.pen: + pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) + pdc.SetPen(self.pen) + pdc.DrawLine(coords[0], coords[1], coords[2], coords[3]) + pdc.SetIdBounds(drawid,(coords[0], coords[1], coords[2], coords[3])) + self.ovlcoords[drawid] = coords elif pdctype == 'polyline': # draw a polyline on top of the map - pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) - pdc.SetPen(self.polypen) - pdc.DrawLines(self.polycoords) + if self.polypen: + pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) + pdc.SetPen(self.polypen) + pdc.DrawLines(coords) + + # get bounding rectangle for polyline + xlist = [] + ylist = [] + if len(coords) > 0: + for point in coords: + x,y = point + xlist.append(x) + ylist.append(y) + x1=min(xlist) + x2=max(xlist) + y1=min(ylist) + y2=max(ylist) + pdc.SetIdBounds(drawid,(x1,y1,x2,y2)) + self.ovlcoords[drawid] = [x1,y1,x2,y2] - # get bounding rectangle for polyline - xlist = [] - ylist = [] - if len(self.polycoords) > 0: - for point in self.polycoords: - x,y = point - xlist.append(x) - ylist.append(y) - x1=min(xlist) - x2=max(xlist) - y1=min(ylist) - y2=max(ylist) - pdc.SetIdBounds(drawid,(x1,y1,x2,y2)) - self.ovlcoords[drawid] = [x1,y1,x2,y2] - elif pdctype == 'point': # draw point - ## pen = self.RandomPen() - pdc.SetPen(self.pen) - pdc.DrawPoint(coords[0], coords[1]) - coordsBound = (coords[0] - 5, - coords[1] - 5, - coords[0] + 5, - coords[1] + 5) - pdc.SetIdBounds(drawid, coordsBound) - self.ovlcoords[drawid] = coords + if self.pen: + pdc.SetPen(self.pen) + pdc.DrawPoint(coords[0], coords[1]) + coordsBound = (coords[0] - 5, + coords[1] - 5, + coords[0] + 5, + coords[1] + 5) + pdc.SetIdBounds(drawid, coordsBound) + self.ovlcoords[drawid] = coords elif pdctype == 'text': # draw text on top of map text = img[0] @@ -332,6 +334,8 @@ pdc.EndDrawing() self.Refresh() + return drawid + def TextBounds(self, textinfo, coords): """ Return text boundary data @@ -382,7 +386,7 @@ the same size as the Window """ - # set size of the input image + # set size of the input image self.Map.width, self.Map.height = self.GetClientSize() # Make new off screen bitmap: this bitmap will always have the @@ -453,13 +457,14 @@ return img - def UpdateMap(self, img=None): + def UpdateMap(self): """ Updates the canvas anytime there is a change to the underlying images or to the geometry of the canvas. """ - Debug.msg (2, "BufferedWindow.UpdateMap(%s): render=%s" % (img, self.render)) + Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s" % \ + (self.render)) if self.render: # render new map images self.Map.width, self.Map.height = self.GetClientSize() @@ -467,7 +472,9 @@ self.img = self.GetImage() self.resize = False - if not self.img: return + if not self.img: + return + try: id = self.imagedict[self.img] except: @@ -476,6 +483,7 @@ # paint images to PseudoDC self.pdc.Clear() self.pdc.RemoveAll() + self.Draw(self.pdc, self.img, drawid=id) # draw map image background self.ovldict = self.GetOverlay() # list of decoration overlay images if self.ovldict != {}: # draw scale and legend overlays @@ -495,12 +503,16 @@ self.resize = False # update statusbar - #Debug.msg (3, "BufferedWindow.UpdateMap(%s): region=%s" % self.Map.region) self.Map.SetRegion() self.parent.statusbar.SetStatusText("Ext: %.2f(W)-%.2f(E), %.2f(N)-%.2f(S)" % (self.Map.region["w"], self.Map.region["e"], self.Map.region["n"], self.Map.region["s"]), 0) + digit = self.parent.digittoolbar + if digit and Digit.driver: + self.pen = wx.Pen(colour='red', width=2, style=wx.SOLID) + Digit.driver.DrawMap() + def EraseMap(self): """ Erase the map display @@ -551,7 +563,7 @@ """ Mouse zoom rectangles and lines """ - Debug.msg (4, "BufferedWindow.MouseDraw(): use=%s, box=%s" % \ + Debug.msg (5, "BufferedWindow.MouseDraw(): use=%s, box=%s" % \ (self.mouse['use'], self.mouse['box'])) if self.mouse['box'] == "box": boxid = wx.ID_NEW @@ -582,25 +594,36 @@ self.Draw(self.pdc, drawid=self.lineid, pdctype='line', coords=mousecoords) - def DrawLines(self): + def DrawLines(self, polycoords=None): """Draw polyline in PseudoDC""" - Debug.msg (5, "BufferedWindow.DrawLines(): coords=%s" % \ - self.polycoords) + if not polycoords: # alternative coordinates + polycoords = self.polycoords + + Debug.msg (4, "BufferedWindow.DrawLines(): coords=%s" % \ + polycoords) - self.plineid = wx.ID_NEW + 1 - if len(self.polycoords) > 0: - self.Draw(self.pdc, drawid=self.plineid, pdctype='polyline', coords=self.polycoords) + if len(polycoords) > 0: + self.plineid = wx.NewId() + self.Draw(self.pdc, drawid=self.plineid, pdctype='polyline', coords=polycoords) + return self.plineid + return -1 + def DrawCross(self, coords, size, rotation=0): """Draw cross in PseudoDC TODO: implement rotation """ + Debug.msg(4, "BufferedWindow.DrawCross(): coords=%s, size=%d" % \ + (coords, size)) coordsCross = ((coords[0] - size, coords[1], coords[0] + size, coords[1]), (coords[0], coords[1] - size, coords[0], coords[1] + size)) + + self.lineid = wx.NewId() for lineCoords in coordsCross: - self.lineid = wx.ID_NEW + 1 self.Draw(self.pdc, drawid=self.lineid, pdctype='line', coords=lineCoords) + + return self.lineid def MouseActions(self, event): """ @@ -639,7 +662,7 @@ Debug.msg (5, "BufferedWindow.MouseAction(): Dragging") currpos = event.GetPositionTuple()[:] end = (currpos[0] - self.mouse['begin'][0], \ - currpos[1] - self.mouse['begin'][1]) + currpos[1] - self.mouse['begin'][1]) # dragging or drawing box with left button if self.mouse['use'] == 'pan': @@ -701,7 +724,7 @@ digit = self.parent.digittoolbar self.mouse['begin'] = event.GetPositionTuple()[:] east, north = self.Pixel2Cell(self.mouse['begin'][0], - self.mouse['begin'][1]) + self.mouse['begin'][1]) try: map = digit.layers[digit.layerSelectedID].name @@ -718,11 +741,15 @@ offset = 5 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 digit.action == "addLine": if digit.type in ["point", "centroid"]: # add new point - self.DrawCross(self.mouse['begin'], 5) + #self.DrawCross(self.mouse['begin'], 5) Digit.AddPoint(map=map, type=digit.type, x=east, y=north) @@ -753,30 +780,42 @@ self.DrawLines() elif digit.action == "deleteLine": # delete selected feature + # -> unselect selected feature + # Digit.driver.SetHighlighted([]) pass - #digit.DeleteLine(map=map, - #east, north) + elif digit.action == "moveLine": + pass elif digit.action == "displayAttributes": 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") + layer=-1, queryCoords=(east, north), + qdist=qdist, + pos=posWindow, + action="update") if not updateRecordDlg.mapInfo and \ Digit.settings["addRecord"]: updateRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, - layer=-1, queryCoords=(east, north), qdist=qdist, + layer=-1, + queryCoords=(east, north), + qdist=qdist, pos=posWindow, action="add") - if updateRecordDlg.mapInfo and \ - 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]) + if updateRecordDlg.mapInfo: + # highlight feature & re-draw map + Digit.driver.SetHighlighted(updateRecordDlg.selectedLines) + self.UpdateMap() + + 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 + Digit.driver.SetHighlighted([]) + self.UpdateMap() else: # get decoration id self.lastpos = self.mouse['begin'] = event.GetPositionTuple()[:] @@ -823,8 +862,14 @@ elif self.mouse["use"] == "pointer" and self.parent.digittoolbar: # digitization - pass - + digit = self.parent.digittoolbar + self.mouse['end'] = event.GetPositionTuple()[:] + if digit.action in ["deleteLine", "moveLine"]: + highlight = Digit.driver.SelectLinesByBox((self.Pixel2Cell(self.mouse['begin'][0],self.mouse['begin'][1]), + self.Pixel2Cell(self.mouse['end'][0], self.mouse['end'][1]))) + + self.UpdateMap() + elif self.dragid != None: # end drag of overlay decoration self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid) @@ -860,6 +905,9 @@ # self.polycoords = [] # self.mouse['begin'] = self.mouse['end'] = [0, 0] # self.Refresh() + elif self.mouse['use'] == 'pointer' and self.parent.digittoolbar: + # digitization tool + pass else: # select overlay decoration options dialog clickposition = event.GetPositionTuple()[:] @@ -912,9 +960,10 @@ Debug.msg (5, "BufferedWindow.OnRightUp(): use=%s" % \ self.mouse["use"]) - if self.parent.digittoolbar and self.parent.digittoolbar.action == "addLine": - digit = self.parent.digittoolbar - if digit.type in ["line", "boundary"]: + digit = self.parent.digittoolbar + if digit: + if digit.action == "addLine" and \ + digit.type in ["line", "boundary"]: try: map = digit.layers[digit.layerSelectedID].name except: @@ -923,14 +972,14 @@ _("Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() - + if map: # add new line mapcoords = [] # xy -> EN for coord in self.polycoords: mapcoords.append(self.Pixel2Cell (coord[0], coord[1])) - + Digit.AddLine(map=map, type=self.parent.digittoolbar.type, coords=mapcoords) @@ -940,7 +989,7 @@ offset = 5 posWindow = self.ClientToScreen((self.polycoords[-1][0] + offset, self.polycoords[-1][1] + offset)) - + # select attributes based on layer and category addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, layer=Digit.settings["layer"], @@ -948,7 +997,7 @@ pos=posWindow, action="addLine") if addRecordDlg.mapInfo and \ - addRecordDlg.ShowModal() == wx.ID_OK: + addRecordDlg.ShowModal() == wx.ID_OK: sqlfile = tempfile.NamedTemporaryFile(mode="w") sqlfile.file.write(addRecordDlg.GetSQLString()) sqlfile.file.flush() @@ -962,7 +1011,15 @@ # redraw map self.render=True self.UpdateMap() - + elif digit.action == "deleteLine": + Digit.DeleteSelectedLines() + Digit.driver.SetHighlighted([]) + self.UpdateMap() + elif digit.action == "moveLine": + #Digit.MoveSelectedLines() + Digit.driver.SetHighlighted([]) + self.UpdateMap() + event.Skip() def OnMouseMoving(self, event): @@ -984,15 +1041,18 @@ def OnMiddleDown(self, event): """Middle mouse button pressed""" digit = self.parent.digittoolbar - if self.mouse["use"] == "pointer" and \ - digit and \ - digit.action == "addLine" and \ - digit.type in ["line", "boundary"]: - # remove last point from the line - self.polycoords.pop() - self.mouse['begin'] = self.polycoords[-1] - self.ClearLines() - self.DrawLines() + if self.mouse["use"] == "pointer" and digit: + if digit.action == "addLine" and \ + digit.type in ["line", "boundary"]: + # remove last point from the line + self.polycoords.pop() + self.mouse['begin'] = self.polycoords[-1] + self.ClearLines() + self.DrawLines() + elif digit.action in ["deleteLine", "moveLine"]: + # unselected selected features + Digit.driver.SetHighlighted([]) + self.UpdateMap() def ClearLines(self): """ @@ -1014,11 +1074,24 @@ Input : int x, int y Output: float x, float y """ - newx = self.Map.region['w'] + x * self.Map.region["ewres"] - newy = self.Map.region['n'] - y * self.Map.region["nsres"] + east = self.Map.region['w'] + x * self.Map.region["ewres"] + north = self.Map.region['n'] - y * self.Map.region["nsres"] - return (newx, newy) + return (east, north) + def Cell2Pixel(self, east, north): + """ + Calculates image coordinates to real word 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"]) + + return (x, y) + def Zoom(self, begin, end, zoomtype): """ Calculates new region while (un)zoom/pan-ing @@ -1254,6 +1327,15 @@ if tmpreg: os.environ["GRASS_REGION"] = tmpreg + def Distance(self, beginpt, endpt): + """Calculete distance""" + x1,y1 = beginpt + x2,y2 = endpt + east = (x2-x1) * self.Map.region["ewres"] + north = (y2-y1) * self.Map.region["nsres"] + + return math.sqrt(math.pow((east),2) + math.pow((north),2)) + class MapFrame(wx.Frame): """ Main frame for map display window. Drawing takes place in child double buffered @@ -1351,7 +1433,6 @@ # self.InitDisplay() # initialize region values - self.dist = 0.0 #segment length for measurement self.totaldist = 0.0 # total length measured # initialize buffered DC ## self.MapWindow = DrawWindow(self) @@ -1499,12 +1580,14 @@ """ Redraw button clicked """ + Debug.msg(3, "BufferedWindow.ReDraw():") self.MapWindow.UpdateMap() def ReRender(self, event): """ Rerender button clicked """ + Debug.msg(3, "BufferedWindow.ReRender():") self.render = True self.MapWindow.UpdateMap() @@ -1797,14 +1880,14 @@ Calculate map distance from screen distance and print to output window """ - x1,y1 = beginpt - x2,y2 = endpt - east = (x2-x1) * self.Map.region["ewres"] - north = (y2-y1) * self.Map.region["nsres"] - self.dist = round(math.sqrt(math.pow((east),2) + math.pow((north),2)),3) - self.totaldist += self.dist - d,dunits = self.FormatDist(self.dist) - td,tdunits = self.FormatDist(self.totaldist) + dist = self.MapWindow.Distance(beginpt, endpt) + + dist = round(dist, 3) + d, dunits = self.FormatDist(dist) + + self.totaldist += dist + td, tdunits = self.FormatDist(self.totaldist) + strdist = str(d) strtotdist = str(td) @@ -1818,8 +1901,11 @@ else: mstring = 'segment = %s %s\ttotal distance = %s %s\n' \ % (strdist,dunits,strtotdist,tdunits) + self.gismanager.goutput.cmd_output.write(mstring) + return dist + def Profile(self, event): """ Init profile canvas and tools Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-07 19:44:27 UTC (rev 945) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-09 16:10:11 UTC (rev 946) @@ -26,7 +26,8 @@ import cmd import grassenv -import digit +from digit import Digit as Digit +from digit import DigitSettingsDialog as DigitSettingsDialog from debug import Debug as Debug from icon import Icons as Icons @@ -160,8 +161,8 @@ """ def __init__(self, parent, map): - self.mapcontent = map - self.parent = parent + self.mapcontent = map # Map class instance + self.parent = parent # # selected map to digitize self.layerSelectedID = None @@ -314,11 +315,14 @@ pass def OnMoveLine(self, event): - pass - + Debug.msg(4, "Digittoolbar.OnMoveLine():") + self.action = "moveLine" + self.parent.MapWindow.mouse['box'] = 'box' + def OnDeleteLine(self, event): + Debug.msg(4, "Digittoolbar.OnDeleteLine():") self.action = "deleteLine" - Debug.msg(4, "Digittoolbar.OnDeleteLine():") + self.parent.MapWindow.mouse['box'] = 'box' def OnDisplayCats(self, event): pass @@ -332,9 +336,8 @@ def OnSettings(self, event): """Show settings dialog""" - settingsDialog = digit.DigitSettingsDialog(parent=self.parent, title=_("Digitization settings"), - style=wx.DEFAULT_DIALOG_STYLE) - settingsDialog.Show() + DigitSettingsDialog(parent=self.parent, title=_("Digitization settings"), + style=wx.DEFAULT_DIALOG_STYLE).Show() def OnSelectMap (self, event): """ @@ -360,7 +363,7 @@ """ try: self.layerSelectedID = self.layers.index(layerSelected) - mapName = self.layers[self.layerSelectedID].name + mapLayer = self.layers[self.layerSelectedID] except: return False @@ -370,26 +373,37 @@ # set initial category number for new features (layer=1), etc. Debug.msg (4, "DigitToolbar.StartEditing(): layerSelectedID=%d layer=%s" % \ - (self.layerSelectedID, mapName)) + (self.layerSelectedID, mapLayer.name)) - digit.Digit.ReInitialize(mapName) + Digit.ReInitialize(mapLayer.name, self.parent.MapWindow) + # deactive layer + self.mapcontent.ChangeLayerActive(mapLayer, False) + + # draw map content + #self.driver.DrawMap() + return True def StopEditing (self, layerSelected): """ Unmark currently enabled map layer. """ - try: - if self.layers[self.layerSelectedID] == layerSelected: - self.layerSelectedID = None - Debug.msg (4, "DigitToolbar.StopEditing(): layerSelectedID=%d layer=%s" % \ - (self.layerSelectedID, self.layers[self.layerSelectedID].name)) - self.combo.SetValue ('Select vector map') - return True - except: - return False + 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) + Digit.ReInitialize() + + return True + + return False + def UpdateListOfLayers (self, updateTool=False): """ Update list of available vector map layers. Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-07-07 19:44:27 UTC (rev 945) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-07-09 16:10:11 UTC (rev 946) @@ -30,8 +30,6 @@ gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","gui_modules" ) sys.path.append(gmpath) -#gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","icons") -#sys.path.append(gmpath) import select import menuform @@ -340,14 +338,14 @@ event.Skip() return + # mark layer as 'edited' + self.mapdisplay.digittoolbar.StopEditing(maplayer) + if self.mapdisplay.digittoolbar: # disable the tool self.mapdisplay.RemoveToolbar("digit") else: # tool already enabled pass - # mark layer as 'edited' - self.mapdisplay.digittoolbar.StopEditing (maplayer) - def OnPopupProperties (self, event): """Popup properties dialog""" self.PropertiesDialog(self.layer_selected) Modified: trunk/grassaddons/gui/icons/icon.py =================================================================== --- trunk/grassaddons/gui/icons/icon.py 2007-07-07 19:44:27 UTC (rev 945) +++ trunk/grassaddons/gui/icons/icon.py 2007-07-09 16:10:11 UTC (rev 946) @@ -227,7 +227,7 @@ "digCopyCats": MetaIcon (img=icons_img["digCopyCats"], label="Copy categories", desc="Not implemented yet"), "digDeleteLine": MetaIcon (img=icons_img["digDeleteLine"], label="Delete line", - desc="Not implemented yet"), + desc="Left: Select; Middle: Unselect; Right: Confirm"), "digDispAttr": MetaIcon (img=icons_img["digDispAttr"], label="Display attributes", desc="Display attributes of given feature"), "digDispCats": MetaIcon (img=icons_img["digDispCats"], label="Display categories", @@ -235,7 +235,7 @@ "digEditLine": MetaIcon (img=icons_img["digEditLine"], label="Edit line", desc="Not implemented yet"), "digMoveLine": MetaIcon (img=icons_img["digMoveLine"], label="Move line", - desc="Not implemented yet"), + desc="Left: Select; Middle: Unselect; Right: Confirm"), "digMoveVertex": MetaIcon (img=icons_img["digMoveVertex"], label="Move vertex", desc="Not implemented yet"), "digRemoveVertex": MetaIcon (img=icons_img["digRemoveVertex"], label="Remove vertex", From bundala at grass.itc.it Mon Jul 9 18:59:50 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Mon Jul 9 18:59:51 2007 Subject: [grass-addons] r947 - trunk/grassaddons/v.generalize Message-ID: <200707091659.l69Gxo5V029355@grass.itc.it> Author: bundala Date: 2007-07-09 18:59:42 +0200 (Mon, 09 Jul 2007) New Revision: 947 Modified: trunk/grassaddons/v.generalize/point.c trunk/grassaddons/v.generalize/point.h trunk/grassaddons/v.generalize/smoothing.c Log: Removed sqrt calculations in Chaiken's algorithm Modified: trunk/grassaddons/v.generalize/point.c =================================================================== --- trunk/grassaddons/v.generalize/point.c 2007-07-09 16:10:11 UTC (rev 946) +++ trunk/grassaddons/v.generalize/point.c 2007-07-09 16:59:42 UTC (rev 947) @@ -86,6 +86,12 @@ (a.z - b.z) * (a.z - b.z)); }; +inline double point_dist_square(POINT a, POINT b) +{ + return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + + (a.z - b.z) * (a.z - b.z); +}; + POINT_LIST *point_list_new(POINT p) { POINT_LIST *pl; Modified: trunk/grassaddons/v.generalize/point.h =================================================================== --- trunk/grassaddons/v.generalize/point.h 2007-07-09 16:10:11 UTC (rev 946) +++ trunk/grassaddons/v.generalize/point.h 2007-07-09 16:59:42 UTC (rev 947) @@ -52,6 +52,8 @@ extern inline void points_copy_last(struct line_pnts *Points, int pos); /* distance between two points */ extern inline double point_dist(POINT a, POINT b); +/* squared distance between two points */ +extern inline double point_dist_square(POINT a, POINT b); /* creates empty list of points */ extern POINT_LIST *point_list_new(POINT p); /* insert new value to the list just after the l. i.e l->next.p = p */ Modified: trunk/grassaddons/v.generalize/smoothing.c =================================================================== --- trunk/grassaddons/v.generalize/smoothing.c 2007-07-09 16:10:11 UTC (rev 946) +++ trunk/grassaddons/v.generalize/smoothing.c 2007-07-09 16:59:42 UTC (rev 947) @@ -132,7 +132,6 @@ /* Chaiken's algorithm. Return the number of points in smoothed line - * TODO: remove sqrt from the distance test */ int chaiken(struct line_pnts *Points, double thresh, int with_z) { @@ -147,7 +146,7 @@ if (n < 3) return n; - // thresh *= thresh; + thresh *= thresh; head.next = NULL; cur = &head; @@ -167,7 +166,7 @@ point_list_add(cur, m1); - if (point_dist(p0, m1) > thresh) { + if (point_dist_square(p0, m1) > thresh) { point_add(p1, m1, &tmp); /* need to refine the partition */ point_scalar(tmp, 0.5, &p2); point_add(p1, p0, &tmp); @@ -317,6 +316,9 @@ int n = Points->n_points; int i, j; + if (n < 3) + return n; + int plus = 4; if (!matrix_init(n + 2 * plus, n + 2 * plus, &g)) { From bundala at grass.itc.it Tue Jul 10 18:23:37 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Tue Jul 10 18:23:39 2007 Subject: [grass-addons] r948 - trunk/grassaddons/v.generalize Message-ID: <200707101623.l6AGNb1J009419@grass.itc.it> Author: bundala Date: 2007-07-10 18:23:34 +0200 (Tue, 10 Jul 2007) New Revision: 948 Modified: trunk/grassaddons/v.generalize/description.html trunk/grassaddons/v.generalize/main.c Log: added 'copy attributes' flag and fixed some typos and mistakes in description.html Modified: trunk/grassaddons/v.generalize/description.html =================================================================== --- trunk/grassaddons/v.generalize/description.html 2007-07-09 16:59:42 UTC (rev 947) +++ trunk/grassaddons/v.generalize/description.html 2007-07-10 16:23:34 UTC (rev 948) @@ -23,9 +23,7 @@ of one line does not affect the other lines. The first and the last point of each line is never translated and/or deleted.

    -

    -If the category ranges are provided, this module affects only the lines with (at least) one of the category numbers in (at least) one category range. -

    +

    SIMPLIFICATION

    v.generalize contains following line simplification algorithms @@ -69,22 +67,22 @@

    -Douglas-Peucker and Douglas-Peucker Reduction Algorithm use the same method +Douglas-Peucker and Douglas-Peucker Reduction Algorithm use the same method to simplify the lines. Note that -

    +
     v.generalize input=in output=out method=douglas threshold=eps
    -
    +
    is equivalent to -
    +
     v.generalize input=in output=out method=douglas_reduction threshold=eps reduction=0
    -
    +
    However, in this case, the first method is faster. Also observe that -douglas_reduction never outputs less vertices than douglas. And that, -in general, douglas is more efficient than douglas_reduction. +douglas_reduction never outputs less vertices than douglas. And that, +in general, douglas is more efficient than douglas_reduction. Also, the effect of -
    +
     v.generalize input=in output=out method=douglas_reduction threshold=0 reduction=X
    -
    +
    is that 'out' contains approximately only X% of points of 'in'.

    @@ -100,7 +98,7 @@ Input parameters: input, threshold, look_ahead.
  • Chaiken's Algorithm - "Inscribes" a line touching the original line such that the points on this new line - are at least threshold apart. Input parameters: input, threshold. This algorithms + are at least threshold apart. Input parameters: input, threshold. This algorithm approximates given line very well.
  • Hermite Interpolation - This algorithm takes the points of the given line as the control points of hermite cubic spline and approximates this spline by the points approximatelly threshold apart. @@ -115,18 +113,23 @@

    One of the key advantages of Hermite Interpolation is the fact that the computed line always passes throught the points of the original line whereas the lines produced by the -remaining algorithms never pass through these points. In some sense, this algorihtm outputs +remaining algorithms never pass through these points. In some sense, this algorithm outputs the line which "circumsrcibes" given line. On the other hand, Chaiken's Algorithm outputs the line which "inscribes" given line. Moreover this line always touches/intersects the centre -of the line segment between two consecutive points. For many iterations, the property above does +of the line segment between two consecutive points. For more iterations, the property above does not hold, but the computed lines are very similar to the Bezier Splines. The disadvantage of these two algorithm is that they increase the number of point.

    Note that Boyle's, McMaster's and Snakes algorithm are sometime used in the signal processing to smooth the signals. More importantly, these algorithms never change the number of points on the lines. i.e they only -translate the points around, they do not insert any new points. +translate the points, they do not insert any new points.

    +

    +Snakes Algorithm is the slowest among the algorithms presented here. Also, +it requires quite a lot of memory. This means, that it is not very efficient +for maps with the lines consisting of many segments. +

    SEE ALSO

    Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-09 16:59:42 UTC (rev 947) +++ trunk/grassaddons/v.generalize/main.c 2007-07-10 16:23:34 UTC (rev 948) @@ -45,6 +45,7 @@ struct Option *map_in, *map_out, *thresh_opt, *method_opt, *look_ahead_opt; struct Option *iterations_opt, *cat_opt, *alfa_opt, *beta_opt, *type_opt; struct Option *field_opt, *where_opt, *reduction_opt; + struct Flag *ca_flag; int with_z; int total_input, total_output; /* Number of points in the input/output map respectively */ double thresh, alfa, beta, reduction; @@ -144,6 +145,11 @@ cat_opt = G_define_standard_option(G_OPT_V_CATS); where_opt = G_define_standard_option(G_OPT_WHERE); + + ca_flag = G_define_flag(); + ca_flag->key = 'c'; + ca_flag->description = _("Copy attributes"); + /* options and flags parser */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); @@ -331,7 +337,8 @@ }; /* finally copy tables */ - Vect_copy_tables(&In, &Out, layer); + if (ca_flag->answer) + Vect_copy_tables(&In, &Out, layer); Vect_build(&Out, stdout); From ullah at grass.itc.it Tue Jul 10 22:04:52 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Tue Jul 10 22:04:53 2007 Subject: [grass-addons] r949 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200707102004.l6AK4qx2011375@grass.itc.it> Author: ullah Date: 2007-07-10 22:04:47 +0200 (Tue, 10 Jul 2007) New Revision: 949 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-10 16:23:34 UTC (rev 948) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-10 20:04:47 UTC (rev 949) @@ -48,6 +48,33 @@ #% required : yes #% guisection: Input #%end +#%option +#% key: outdem +#% type: string +#% gisprompt: string +#% description: Name stem for output elevation map(s) (preceded by prefix and followed by numerical suffix if more than one iteration) +#% answer: elevation +#% required: yes +#% guisection: Input +#%end +#%option +#% key: outsoil +#% type: string +#% gisprompt: string +#% description: Name stem for the output soil depth map(s) (preceded by prefix and followed by numerical suffix if more than one iteration) +#% answer: soildepth +#% required: yes +#% guisection: Input +#%end +#%option +#% key: outbdrk +#% type: string +#% gisprompt: string +#% description: Name stem for the output bedrock map(s) (required if the -b option is NOT checked; preceded by prefix and followed by numerical suffix if more than one iteration) +#% answer: bedrock +#% required: no +#% guisection: Input +#%end #%flag #% key: n #% description: -n Do not output maps of net erosion/deposition @@ -267,6 +294,9 @@ prefx=$GIS_OPT_prefx elev=$GIS_OPT_elev initbdrk=$GIS_OPT_initbdrk +outbdrk=$GIS_OPT_outbdrk +outdem=$GIS_OPT_outdem +outsoil=$GIS_OPT_outsoil R=$GIS_OPT_R K=$GIS_OPT_K C=$GIS_OPT_C @@ -336,9 +366,8 @@ echo "" -new_soil=$prefx"_new_soil"$num -new_dem=$prefx"_new_dem"$num - +new_soil=$prefx$outsoil$num +new_dem=$prefx$outdem$num initsoil=$prefx"_initsoil" @@ -351,7 +380,7 @@ else -new_bdrk=$prefx"_new_bdrk"$num +new_bdrk=$prefx$outbdrk$num echo "The new bedrock elevation map for this iteration will be called $new_bdrk" fi @@ -588,7 +617,7 @@ echo "" -#this is commented out because I don't fully 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. +#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)" @@ -827,8 +856,8 @@ echo "old_soil=$old_soil" echo "" -new_soil=$prefx"_new_soil"$step -new_dem=$prefx"_new_dem"$step +new_soil=$prefx$outsoil$step +new_dem=$prefx$outdem$step 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" @@ -838,11 +867,13 @@ else -new_bdrk=$prefx"_new_bdrk"$step +new_bdrk=$prefx$outbdrk$step echo "The new bedrock elevation map for this iteration will be called $new_bdrk" fi + + echo "" echo "##################################################" echo "##################################################" From ullah at grass.itc.it Tue Jul 10 22:05:20 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Tue Jul 10 22:05:22 2007 Subject: [grass-addons] r950 - in trunk/grassaddons/LandDyn/devs_landcover_scripts: r.cfactor r.landcover.update Message-ID: <200707102005.l6AK5KUh011399@grass.itc.it> Author: ullah Date: 2007-07-10 22:05:12 +0200 (Tue, 10 Jul 2007) New Revision: 950 Modified: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update Log: minor change to naming system Modified: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor 2007-07-10 20:04:47 UTC (rev 949) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.cfactor/r.cfactor 2007-07-10 20:05:12 UTC (rev 950) @@ -28,11 +28,11 @@ #%END #%option -#% key: prfx +#% key: outcfact #% type: string #% gisprompt: string -#% description: prefix for all output maps -#% answer: year1 +#% description: c_factor output map name +#% answer: year1_cfactor #% required : yes #%END @@ -71,15 +71,12 @@ inmap=$GIS_OPT_inmap -prfx=$GIS_OPT_prfx +outcfact=$GIS_OPT_outcfact cfact_rules=$GIS_OPT_cfact_rules cfact_color=$GIS_OPT_cfact_color - -outcfact=$prfx"cfactor" - #setting initial conditions of map area g.region rast=$inmap Modified: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update 2007-07-10 20:04:47 UTC (rev 949) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.landcover.update/r.landcover.update 2007-07-10 20:05:12 UTC (rev 950) @@ -16,7 +16,7 @@ #%Module -#% description: CUpdates a map of landcover by the amounts specified in an impacts map +#% description: Updates a map of landcover by the amounts specified in an impacts map #%END #%option @@ -45,11 +45,11 @@ #%END #%option -#% key: prfx +#% key: outmap #% type: string #% gisprompt: string -#% description: prefix for all output maps -#% answer: year1 +#% description: land cover output map name (no prefix) +#% answer: landcover #% required : yes #%END @@ -94,7 +94,7 @@ impacts=$GIS_OPT_impacts -prfx=$GIS_OPT_prfx +outmap=$GIS_OPT_outmap max=$GIS_OPT_max @@ -103,13 +103,13 @@ lc_color=$GIS_OPT_lc_color -txtout=$prfx"luse_stats.txt" +txtout=$outmap"luse_stats.txt" -temp_lc=$prfx"temp_landcover" +temp_lc=$outmap"temp_landcover" -temp_reclass=$prfx"temp_landcover_reclass" +temp_reclass=$outmap"temp_landcover_reclass" -outlc=$prfx"landcover" +outlc=$outmap #setting initial conditions of map area From landa at grass.itc.it Wed Jul 11 17:14:06 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Jul 11 17:14:09 2007 Subject: [grass-addons] r951 - in trunk/grassaddons/gui: gui_modules icons Message-ID: <200707111514.l6BFE6TA028479@grass.itc.it> Author: landa Date: 2007-07-11 17:14:06 +0200 (Wed, 11 Jul 2007) New Revision: 951 Modified: 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: Digitization tool: other tools implemeneted (move line, add/remove vertex) Still TEMPORARY solution (C/C++ Display driver needed) Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-07-10 20:05:12 UTC (rev 950) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-07-11 15:14:06 UTC (rev 951) @@ -37,7 +37,7 @@ 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" + #g6libPath = "/usr/src/gis/grass6/swig/python" sys.path.append(g6libPath) import python_grass6 as g6lib except: @@ -52,7 +52,8 @@ def __init__(self, settings=None): self.map = None self.driver = None - + self.threshold = 0 # set by driver constructor + if not settings: self.settings = {} # symbology @@ -71,8 +72,11 @@ self.settings["symbolVertex"] = (True, "pink") # display + self.settings["lineWidth"] = (2, "screen pixels") + + # snapping self.settings["snapping"] = (10, "screen pixels") # value, unit - self.settings["lineWidth"] = (2, "screen pixels") + self.settings["snapToVertex"] = False # digitize new record self.settings["addRecord"] = True self.settings["layer"] = 1 @@ -198,20 +202,14 @@ """ General method which adds feature to the vector map """ - threshold = Digit.settings["snapping"][0] - if Digit.settings["snapping"][1] == "screen pixels": - # pixel -> cell - print "#", threshold - threshold = self.driver.mapwindow.Distance(beginpt=(0,0), - endpt=(threshold,0)) - - - print "#", threshold - + command = ["v.edit", "-n", "--q", "map=%s" % map, "tool=add", - "thresh=%f" % threshold] + "thresh=%f" % self.threshold] + + print "#", self.threshold + # additional flags for flag in flags: command.append(flag) @@ -223,15 +221,16 @@ self.driver.ReDrawMap(map) def DeleteSelectedLines(self): - """Delete vector feature from map""" + """Delete selected vector features from the vector map""" - if not self.driver.highlighted: - Debug.msg(4, "Digit.DeleteSelectedLines(): ids=%s" % \ - self.driver.highligted) + if not self.driver.selected: return False - - ids = ",".join(["%d" % v for v in self.driver.highlighted]) - command = ["v.edit", "-n", "--q", + + Debug.msg(4, "Digit.DeleteSelectedLines(): ids=%s" % \ + self.driver.selected) + + ids = ",".join(["%d" % v for v in self.driver.selected]) + command = ["v.edit", "--q", "map=%s" % self.map, "tool=delete", "ids=%s" % ids] @@ -243,7 +242,85 @@ self.driver.ReDrawMap(self.map) return True + + def MoveSelectedLines(self, move): + """Move selected vector features""" + + if not self.driver.selected: + return False + + Debug.msg(4, "Digit.MoveSelectedLines(): ids=%s, move=%s" % \ + (self.driver.selected, move)) + + print "#", move + + ids = ",".join(["%d" % v for v in self.driver.selected]) + command = ["v.edit", "--q", + "map=%s" % self.map, + "tool=move", + "ids=%s" % ids, + "move=%f,%f" % (float(move[0]),float(move[1]))] + + # run the command + vedit = cmd.Command(cmd=command) + + # redraw map + self.driver.ReDrawMap(self.map) + + return True + + def SplitLine(self, coords): + """Split selected line on position 'coords'""" + try: + line = self.driver.selected[0] + except: + return False + + command = ["v.edit", "--q", + "map=%s" % self.map, + "tool=break", + "ids=%s" % line, + "coords=%f,%f" % (float(coords[0]),float(coords[1])), + "thresh=%f" % self.threshold] + + # run the command + vedit = cmd.Command(cmd=command) + + # redraw map + self.driver.ReDrawMap(self.map) + + return True + + def AddVertex(self, coords): + """Add new vertex to the selected line on position 'coords'""" + return self.__ModifyVertex(coords, "vertexadd") + + def RemoveVertex(self, coords): + """Remove vertex from the selected line on position 'coords'""" + return self.__ModifyVertex(coords, "vertexdel") + def __ModifyVertex(self, coords, action): + + try: + line = self.driver.selected[0] + except: + return False + + command = ["v.edit", "--q", + "map=%s" % self.map, + "tool=%s" % action, + "ids=%s" % line, + "coords=%f,%f" % (float(coords[0]),float(coords[1])), + "thresh=%f" % self.threshold] + + # run the command + vedit = cmd.Command(cmd=command) + + # redraw map + self.driver.ReDrawMap(self.map) + + return True + class VDigit(AbstractDigit): """ Prototype of digitization class based on v.digit reimplementation @@ -261,9 +338,12 @@ """ def __init__(self, map, mapwindow): self.mapwindow = mapwindow - self.ids = {} # dict[g6id] = [DCid] - self.highlighted = [] # list of highlighted objects (g6id) + Digit.threshold = self.GetThreshold() + + self.ids = {} # dict[g6id] = [pdcId] + self.selected = [] # list of selected objects (grassId!) + g6lib.G_gisinit('') name, mapset = map.split('@') @@ -292,6 +372,18 @@ if self.cats: g6lib.Vect_destroy_cats_struct(self.cats) + def GetThreshold(self): + """Return threshold in map units""" + if Digit.settings["snapping"][1] == "screen pixels": + # pixel -> cell + threshold = self.mapwindow.Distance(beginpt=(0,0), + endpt=(Digit.settings["snapping"][0],0))[0] + else: + threshold = Digit.settings["snapping"][0] + + Debug.msg(4, "DisplayDriver.GetThreshold(): thresh=%f" % threshold) + return threshold + def __SetPen(self, line, symbol): # see include/vect/dig_defines.h # define GV_POINT 0x01 @@ -303,7 +395,7 @@ # define GV_AREA 0x40 # define GV_VOLUME 0x80 - if line in self.highlighted: + if line in self.selected: symbol = "symbolHighlight" width = Digit.settings["lineWidth"][0] @@ -314,29 +406,94 @@ else: self.mapwindow.pen = self.mapwindow.polypen = None - def SetHighlighted(self, ids): - """Set highlighted objects in PseudoDC + def SetSelected(self, pdcId): + """Set selected objects (their ids) in PseudoDC - For disable highlighting set ids=[] + For deseleids=[] """ # reset - self.highlighted = [] + self.selected = [] - for line in ids: - self.highlighted.append(line) + for line in pdcId: + self.selected.append(line) - Debug.msg(4, "DisplayDriver.SetHightlighted(): dcIds=%s, lineIds=%s" % \ - (ids, self.highlighted)) + Debug.msg(4, "DisplayDriver.SetSelected(): pdcId=%s, grassId=%s" % \ + (pdcId, self.selected)) - def SelectLinesByBox(self, rect): - """Alternative method for selecting vector feature - in the map by given bounding box. + 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 + + 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, node1, node2, vertex1, ...] + if minIdx == 0: + finalIdx = 1 + elif minIdx == npoints - 1: + finalIdx = 2 + else: + finalIdx = minIdx + 1 + + selectedId.append(self.ids[line][finalIdx]) + + return selectedId + + def SelectLinesByBox(self, rect, onlyType=None): + """Select vector features by given bounding box. + rect = ((x1, y1), (x2, y2)) - This method should be in the future reimplemented using - PseudoDC.FindObjectInsideBBox()""" + Number of selected features can be decreased by 'onlyType' + ('None' for no types) + """ - type = 255 # all types (see include/vect/dig_defines.h) + 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() @@ -355,20 +512,42 @@ 0, None, type, list) - self.highligted = [] + self.selected = [] for idx in range(list.n_values): line = g6lib.intArray_getitem(list.value, idx) - if line not in self.highlighted: - self.highlighted.append(line) + 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.highlighted)) + (rect, list.n_values, self.selected)) g6lib.Vect_destroy_line_struct(bbox) g6lib.Vect_destroy_list(list) - return self.highlighted - + 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, Digit.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 @@ -588,16 +767,6 @@ sizer = wx.StaticBoxSizer(box, wx.VERTICAL) flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5) flexSizer.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), - value=str(Digit.settings["snapping"][0]), min=1, max=1e6) - self.snappingUnit = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(125, -1), - choices=["screen pixels", "map units"]) - self.snappingUnit.SetValue(Digit.settings["snapping"][1]) - 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) # 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), @@ -614,6 +783,33 @@ border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) # + # snapping section + # + 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) + # 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(Digit.settings["snapping"][0]), min=1, max=1e6) + self.snappingUnit = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(125, -1), + choices=["screen pixels", "map units"]) + self.snappingUnit.SetValue(Digit.settings["snapping"][1]) + 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) + vertexSizer = wx.BoxSizer(wx.VERTICAL) + self.snapVertex = wx.CheckBox(parent=panel, id=wx.ID_ANY, + label=_("Snap also to vertex")) + self.snapVertex.SetValue(Digit.settings["snapToVertex"]) + vertexSizer.Add(item=self.snapVertex, 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) + border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) + + # # attributes # box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Digitize new feature")) @@ -720,26 +916,33 @@ def UpdateSettings(self): """Update Digit.settings""" + # symbology + for key, (enabled, color) in self.symbology.iteritems(): + if enabled: + Digit.settings[key] = (enabled.IsChecked(), color.GetColour()) + else: + Digit.settings[key] = (None, color.GetColour()) + # display + Digit.settings["lineWidth"] = (int(self.lineWidthValue.GetValue()), + self.lineWidthUnit.GetValue()) + + # snapping + Digit.settings["snapping"] = (int(self.snappingValue.GetValue()), # value + self.snappingUnit.GetValue()) # unit + Digit.settings["snapToVertex"] = self.snapVertex.IsChecked() + + # digitize new feature + Digit.settings["addRecord"] = self.addRecord.IsChecked() + Digit.settings["layer"] = int(self.layer.GetValue()) + if Digit.settings["categoryMode"] == "No category": + Digit.settings["category"] = None + else: + Digit.settings["category"] = int(self.category.GetValue()) + Digit.settings["categoryMode"] = self.categoryMode.GetValue() + + # threshold try: - # symbology - for key, (enabled, color) in self.symbology.iteritems(): - if enabled: - Digit.settings[key] = (enabled.IsChecked(), color.GetColour()) - else: - Digit.settings[key] = (None, color.GetColour()) - # display - Digit.settings["snapping"] = (int(self.snappingValue.GetValue()), # value - self.snappingUnit.GetValue()) # unit - Digit.settings["lineWidth"] = (int(self.lineWidthValue.GetValue()), - self.lineWidthUnit.GetValue()) - # digitize new feature - Digit.settings["addRecord"] = self.addRecord.IsChecked() - Digit.settings["layer"] = int(self.layer.GetValue()) - if Digit.settings["categoryMode"] == "No category": - Digit.settings["category"] = None - else: - Digit.settings["category"] = int(self.category.GetValue()) - Digit.settings["categoryMode"] = self.categoryMode.GetValue() + Digit.threshold = Digit.driver.GetThreshold() except: pass Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-10 20:05:12 UTC (rev 950) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-11 15:14:06 UTC (rev 951) @@ -142,7 +142,6 @@ # # Flags # - self.render = True # re-render the map from GRASS or just redraw image self.resize = False # indicates whether or not a resize event has taken place self.dragimg = None # initialize variable for map panning @@ -400,7 +399,6 @@ # update map display if self.img and self.Map.width + self.Map.height > 0: # scale image during resize self.img = self.img.Scale(self.Map.width, self.Map.height) - self.render = False self.UpdateMap() # re-render image on idle @@ -413,7 +411,6 @@ """ if self.resize: - self.render = True self.UpdateMap() event.Skip() @@ -457,22 +454,32 @@ return img - def UpdateMap(self): + def UpdateMap(self, render=True, redrawAll=True, removeId=[]): """ Updates the canvas anytime there is a change to the underlying images or to the geometry of the canvas. """ Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s" % \ - (self.render)) - if self.render: + (render)) + + if render: # render new map images self.Map.width, self.Map.height = self.GetClientSize() - self.mapfile = self.Map.Render(force=self.render) + self.mapfile = self.Map.Render(force=True) self.img = self.GetImage() self.resize = False - if not self.img: + # paint images to PseudoDC + if len(removeId) > 0: + for id in removeId: + self.pdc.ClearId(id) + self.pdc.RemoveId(id) + else: + self.pdc.Clear() + self.pdc.RemoveAll() + + if not self.img or redrawAll == False: return try: @@ -480,10 +487,7 @@ except: return - # paint images to PseudoDC - self.pdc.Clear() - self.pdc.RemoveAll() - + self.Draw(self.pdc, self.img, drawid=id) # draw map image background self.ovldict = self.GetOverlay() # list of decoration overlay images if self.ovldict != {}: # draw scale and legend overlays @@ -599,8 +603,8 @@ if not polycoords: # alternative coordinates polycoords = self.polycoords - Debug.msg (4, "BufferedWindow.DrawLines(): coords=%s" % \ - polycoords) + #Debug.msg (4, "BufferedWindow.DrawLines(): coords=%s" % \ + # polycoords) if len(polycoords) > 0: self.plineid = wx.NewId() @@ -645,7 +649,6 @@ # zoom self.Zoom(begin, end, zoomtype) # redraw map - self.render=True self.UpdateMap() return @@ -709,10 +712,12 @@ Debug.msg (5, "BufferedWindow.OnLeftDown(): use=%s" % \ self.mouse["use"]) + self.mouse['begin'] = event.GetPositionTuple()[:] + if self.mouse["use"] in ["measure", "profile"]: # measure || profile if len(self.polycoords) == 0: - self.mouse['begin'] = event.GetPositionTuple()[:] + self.mouse['end'] = self.mouse['begin'] self.polycoords.append(self.mouse['begin']) self.ClearLines() @@ -722,7 +727,6 @@ elif self.mouse["use"] == "pointer" and self.parent.digittoolbar: # digitization digit = self.parent.digittoolbar - self.mouse['begin'] = event.GetPositionTuple()[:] east, north = self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]) @@ -770,7 +774,6 @@ executeCommand = cmd.Command(cmd=["db.execute", "--q", "input=%s" % sqlfile.name]) - self.render=True self.UpdateMap() # redraw map elif digit.type in ["line", "boundary"]: @@ -781,9 +784,12 @@ elif digit.action == "deleteLine": # delete selected feature # -> unselect selected feature - # Digit.driver.SetHighlighted([]) + # Digit.driver.SetSelected([]) pass - elif digit.action == "moveLine": + elif digit.action in ["moveLine", "moveVertex"]: + self.moveBegin = [0,0] + self.modeIds = [] + elif digit.action == "splitLine": pass elif digit.action == "displayAttributes": qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width) @@ -803,7 +809,7 @@ action="add") if updateRecordDlg.mapInfo: # highlight feature & re-draw map - Digit.driver.SetHighlighted(updateRecordDlg.selectedLines) + Digit.driver.SetSelected(updateRecordDlg.selectedLines) self.UpdateMap() if updateRecordDlg.ShowModal() == wx.ID_OK: @@ -814,11 +820,11 @@ "--q", "input=%s" % sqlfile.name]) # unselect & re-draw - Digit.driver.SetHighlighted([]) + Digit.driver.SetSelected([]) self.UpdateMap() else: # get decoration id - self.lastpos = self.mouse['begin'] = event.GetPositionTuple()[:] + self.lastpos = self.mouse['begin'] idlist = self.pdc.FindObjects(x=self.lastpos[0], y=self.lastpos[1], radius=self.hitradius) if idlist != []: @@ -841,7 +847,6 @@ self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype) # redraw map - self.render=True self.UpdateMap() elif self.mouse["use"] == "query": @@ -864,12 +869,27 @@ # digitization digit = self.parent.digittoolbar self.mouse['end'] = event.GetPositionTuple()[:] - if digit.action in ["deleteLine", "moveLine"]: - highlight = Digit.driver.SelectLinesByBox((self.Pixel2Cell(self.mouse['begin'][0],self.mouse['begin'][1]), - self.Pixel2Cell(self.mouse['end'][0], self.mouse['end'][1]))) - - self.UpdateMap() - + if digit.action in ["deleteLine", "moveLine", "moveVertex"]: + if digit.action == "moveVertex": + Digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], + self.mouse['begin'][1]), + onlyType="line") + self.moveIds = Digit.driver.GetSelectedVertex(self.mouse['begin']) + else: # moveLine + Digit.driver.SelectLinesByBox((self.Pixel2Cell(self.mouse['begin'][0], + self.mouse['begin'][1]), + self.Pixel2Cell(self.mouse['end'][0], + self.mouse['end'][1]))) + self.moveIds = Digit.driver.GetSelected(grassId=False) + if len(self.moveIds) > 0: + self.UpdateMap(render=False) + if digit.action in ["moveLine", "moveVertex"]: + self.UpdateMap(render=False, redrawAll=False, removeId=self.moveIds) + + if digit.action in ["splitLine", "addVertex", "removeVertex"]: + Digit.driver.SetSelected([]) + Digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]), onlyType="line") + self.UpdateMap(render=False) elif self.dragid != None: # end drag of overlay decoration self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid) @@ -1007,37 +1027,34 @@ # clean up saved positions self.polycoords = [] - - # redraw map - self.render=True - self.UpdateMap() elif digit.action == "deleteLine": Digit.DeleteSelectedLines() - Digit.driver.SetHighlighted([]) - self.UpdateMap() elif digit.action == "moveLine": - #Digit.MoveSelectedLines() - Digit.driver.SetHighlighted([]) - self.UpdateMap() + #if Digit.driver.GetSelected(): + # pixel -> cell + move = [self.Distance((0,0), (self.moveBegin[0], 0))[0], + self.Distance((0,0), (0, self.moveBegin[1]))[0]] # TODO d.measure + # ES -> EN + if self.moveBegin[0] < 0.0: + move[0] *= -1.0 + if self.moveBegin[1] > 0.0: + move[1] *= -1.0 + Digit.MoveSelectedLines(move) + del self.moveBegin + del self.moveIds + elif digit.action == "splitLine": + Digit.SplitLine(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) + elif digit.action == "addVertex": + Digit.AddVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) + elif digit.action == "removeVertex": + Digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) + + Digit.driver.SetSelected([]) + self.UpdateMap(render=False) + event.Skip() - def OnMouseMoving(self, event): - """Motion event and no mouse buttons were pressed""" - digit = self.parent.digittoolbar - if self.mouse["use"] == "pointer" and \ - digit and \ - digit.action == "addLine" and \ - digit.type in ["line", "boundary"]: - self.mouse['end'] = event.GetPositionTuple()[:] - Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \ - (self.mouse['end'][0], self.mouse['end'][1])) - if len(self.polycoords) > 0: - # draw mouse moving - self.MouseDraw() - - event.Skip() - def OnMiddleDown(self, event): """Middle mouse button pressed""" digit = self.parent.digittoolbar @@ -1049,11 +1066,40 @@ self.mouse['begin'] = self.polycoords[-1] self.ClearLines() self.DrawLines() - elif digit.action in ["deleteLine", "moveLine"]: + elif digit.action in ["deleteLine", "moveLine", "splitLine", "addVertex", "removeVertex", "moveVertex"]: # unselected selected features - Digit.driver.SetHighlighted([]) + Digit.driver.SetSelected([]) + if digit.action in ["moveLine", "moveVertex"]: + del self.moveBegin + del self.moveIds self.UpdateMap() + def OnMouseMoving(self, event): + """Motion event and no mouse buttons were pressed""" + digit = self.parent.digittoolbar + if self.mouse["use"] == "pointer" and digit: + self.mouse['end'] = event.GetPositionTuple()[:] + Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \ + (self.mouse['end'][0], self.mouse['end'][1])) + if digit.action == "addLine" and \ + digit.type in ["line", "boundary"]: + if len(self.polycoords) > 0: + # draw mouse moving + self.MouseDraw() + elif digit.action in ["moveLine", "moveVertex"] 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 + self.moveBegin[1] += dy + for id in self.moveIds: + print "#", id, dx, dy + self.pdc.TranslateId(id, dx, dy) + + self.Refresh() # TODO: use RefreshRect() + self.mouse['begin'] = self.mouse['end'] + + event.Skip() + def ClearLines(self): """ Clears lines drawn for measurement and profiling @@ -1147,7 +1193,6 @@ self.Map.region['s'] = zoom[1] self.Map.region['e'] = zoom[2] self.Map.region['w'] = zoom[3] - self.render=True self.UpdateMap() def ZoomHistory(self, n,s,e,w): @@ -1329,12 +1374,12 @@ def Distance(self, beginpt, endpt): """Calculete distance""" - x1,y1 = beginpt - x2,y2 = endpt - east = (x2-x1) * self.Map.region["ewres"] - north = (y2-y1) * self.Map.region["nsres"] + x1, y1 = beginpt + x2, y2 = endpt + dEast = (x2-x1) * self.Map.region["ewres"] + dNorth = (y2-y1) * self.Map.region["nsres"] - return math.sqrt(math.pow((east),2) + math.pow((north),2)) + return (math.sqrt(math.pow((dEast),2) + math.pow((dNorth),2)), (dEast, dNorth)) class MapFrame(wx.Frame): """ @@ -1588,7 +1633,6 @@ Rerender button clicked """ Debug.msg(3, "BufferedWindow.ReRender():") - self.render = True self.MapWindow.UpdateMap() def Pointer(self, event): @@ -1880,7 +1924,7 @@ Calculate map distance from screen distance and print to output window """ - dist = self.MapWindow.Distance(beginpt, endpt) + dist, (north, east) = self.MapWindow.Distance(beginpt, endpt) dist = round(dist, 3) d, dunits = self.FormatDist(dist) Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-10 20:05:12 UTC (rev 950) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-11 15:14:06 UTC (rev 951) @@ -300,17 +300,27 @@ self.parent.RemoveToolbar ("digit") def OnMoveVertex(self, event): - pass + Debug.msg(4, "Digittoolbar.OnMoveVertex():") + self.action = "moveVertex" + self.parent.MapWindow.mouse['box'] = 'point' def OnAddVertex(self, event): - pass + Debug.msg(4, "Digittoolbar.OnAddVertex():") + self.action = "addVertex" + self.parent.MapWindow.mouse['box'] = 'point' + def OnRemoveVertex(self, event): - pass + Debug.msg(4, "Digittoolbar.OnRemoveVertex():") + self.action = "removeVertex" + self.parent.MapWindow.mouse['box'] = 'point' + def OnSplitLine(self, event): - pass - + Debug.msg(4, "Digittoolbar.OnSplitLine():") + self.action = "splitLine" + self.parent.MapWindow.mouse['box'] = 'point' + def OnEditLine(self, event): pass Modified: trunk/grassaddons/gui/icons/icon.py =================================================================== --- trunk/grassaddons/gui/icons/icon.py 2007-07-10 20:05:12 UTC (rev 950) +++ trunk/grassaddons/gui/icons/icon.py 2007-07-11 15:14:06 UTC (rev 951) @@ -217,13 +217,13 @@ "digAddPoint": MetaIcon (img=icons_img["digAddPoint"], label="Digitize new point", desc="Left: new point"), "digAddLine" : MetaIcon (img=icons_img["digAddLine"], label="Digitize new line", - desc="Left: new point - Middle: undo last point - Right: close line"), + desc="Left: new point; Middle: undo last point; Right: close line"), "digAddBoundary": MetaIcon (img=icons_img["digAddBoundary"], label="Digitize new boundary", - desc="Left: new point - Middle: undo last point - Right: close line"), + desc="Left: new point; Middle: undo last point; Right: close line"), "digAddCentroid": MetaIcon (img=icons_img["digAddCentroid"], label="Digitize new centroid", desc="Left: new point"), "digAddVertex": MetaIcon (img=icons_img["digAddVertex"], label="Add new vertex", - desc="Not implemented yet"), + desc="Left: Select; Middle: Unselect; Right: Confirm"), "digCopyCats": MetaIcon (img=icons_img["digCopyCats"], label="Copy categories", desc="Not implemented yet"), "digDeleteLine": MetaIcon (img=icons_img["digDeleteLine"], label="Delete line", @@ -237,13 +237,13 @@ "digMoveLine": MetaIcon (img=icons_img["digMoveLine"], label="Move line", desc="Left: Select; Middle: Unselect; Right: Confirm"), "digMoveVertex": MetaIcon (img=icons_img["digMoveVertex"], label="Move vertex", - desc="Not implemented yet"), + desc="Left: Select; Middle: Unselect; Right: Confirm"), "digRemoveVertex": MetaIcon (img=icons_img["digRemoveVertex"], label="Remove vertex", - desc="Not implemented yet"), + desc="Left: Select; Middle: Unselect; Right: Confirm"), "digSettings": MetaIcon (img=icons_img["digSettings"], label="Settings", desc="Settings dialog for digitization tool"), "digSplitLine": MetaIcon (img=icons_img["digSplitLine"], label="Split line", - desc="Not implemented yet"), + desc="Left: Select; Middle: Unselect; Right: Confirm"), "digExit" : MetaIcon (img=icons_img["digExit"], label="Quit digitization tool"), # analyze raster "analyze" : MetaIcon (img=icons_img["analyze"], label="Analyze map"), From ullah at grass.itc.it Wed Jul 11 19:56:08 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Wed Jul 11 19:56:09 2007 Subject: [grass-addons] r952 - trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages Message-ID: <200707111756.l6BHu8rT029928@grass.itc.it> Author: ullah Date: 2007-07-11 19:56:02 +0200 (Wed, 11 Jul 2007) New Revision: 952 Modified: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages Log: Modified r.villages so that only "outmap" needs to be specified instead of a "prefix" Modified: trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages =================================================================== --- trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages 2007-07-11 15:14:06 UTC (rev 951) +++ trunk/grassaddons/LandDyn/devs_landcover_scripts/r.villages/r.villages 2007-07-11 17:56:02 UTC (rev 952) @@ -43,10 +43,10 @@ #%END #%option -#% key: prfx +#% key: output #% type: string #% gisprompt: string -#% description: prefix for output map (will be put before 'final_landcover') +#% description: name for output map #% answer: year1 #% required : yes #%END @@ -74,14 +74,13 @@ val=$GIS_OPT_val -prfx=$GIS_OPT_prfx +#setting map names -outmap=$prfx"final_landcover" +outmap=$GIS_OPT_output +temp_villages=$outmap"_temporary_village_reclass" -temp_villages=$prfx"_temporary_village_reclass" - #setting initial conditions of map area g.region rast=$inmap From bundala at grass.itc.it Wed Jul 11 23:31:54 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Wed Jul 11 23:31:55 2007 Subject: [grass-addons] r953 - trunk/grassaddons/v.generalize Message-ID: <200707112131.l6BLVsh1032688@grass.itc.it> Author: bundala Date: 2007-07-11 23:31:49 +0200 (Wed, 11 Jul 2007) New Revision: 953 Modified: trunk/grassaddons/v.generalize/description.html trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/point.c trunk/grassaddons/v.generalize/point.h trunk/grassaddons/v.generalize/smoothing.c Log: Bugfix: Calculation of centroids, preservation of points in distance weighting; Introduced new parameter: slide (used in McMasters' Algorithms), new algorithm: McMaster's Sliding Averaging Algorithm, new parameter in hermite interpolation: angle_tresh - minimal angle between two consecutive segments (used for reducing the number of points) and some minor changes in description.html Modified: trunk/grassaddons/v.generalize/description.html =================================================================== --- trunk/grassaddons/v.generalize/description.html 2007-07-11 17:56:02 UTC (rev 952) +++ trunk/grassaddons/v.generalize/description.html 2007-07-11 21:31:49 UTC (rev 953) @@ -29,6 +29,7 @@ v.generalize contains following line simplification algorithms
    • Douglas-Peucker Algorithm
    • +
    • "Douglas-Peucker Reduction Algorithm"
    • Lang Algorithm
    • Vertex Reduction
    • Reumann-Witkam Algorithm
    • @@ -40,7 +41,7 @@

      --> -Different algortihms requires different parameters, but all the algorithms have +Different algorithms require different parameters, but all the algorithms have one parameter in common. It is threshold parameter. In general, the degree of simplification increases with the increasing value of threshold. @@ -92,10 +93,13 @@
      • Boyle's Forward-Looking Algorithm - Works by taking the average of look_ahead consecutive points
      • . Input parameters: input, look_ahead. +
      • McMaster's Sliding Averaging Algorithm - Input Parameters: input, slide, look_ahead. + The new position of each point is the average of the look_ahead points around. Paremeter slide + is used for linear interpolation between old and new position (see below).
      • McMaster's Distance-Weighting Algorithm - Works by taking the weighted average of look_ahead consecutive points - where the weight is the distance from the point to the currently smoothed point. And parameter threshold is used + where the weight is the reciprocal of the distance from the point to the currently smoothed point. And parameter slide is used for linear interpolation between the original position of the point and newly computed position where value 0 means the original position. - Input parameters: input, threshold, look_ahead. + Input parameters: input, slide, look_ahead.
      • Chaiken's Algorithm - "Inscribes" a line touching the original line such that the points on this new line are at least threshold apart. Input parameters: input, threshold. This algorithm @@ -103,7 +107,9 @@
      • Hermite Interpolation - This algorithm takes the points of the given line as the control points of hermite cubic spline and approximates this spline by the points approximatelly threshold apart. This method has excellent results for the small values of threshold, but in this case it produces - a huge number of new points and some simplification is usually needed. Input parameters: input, threshold.
      • + a huge number of new points and some simplification is usually needed. Input parameters: input, threshold, angle_thresh. + Angle_thresh is used for reducing the number of the outputed points. It denotes the minimal + angle (in degrees) between two consecutive segements of line.
      • Snakes is the method of minimization of the "energy" of the line. This method preserves the general characteristcs of the lines but smooths the "sharp corners" of the line. Input parameters input, alfa, beta. This algorithm works very well for small values of alfa and beta (between 0 and 5). These @@ -118,10 +124,15 @@ the line which "inscribes" given line. Moreover this line always touches/intersects the centre of the line segment between two consecutive points. For more iterations, the property above does not hold, but the computed lines are very similar to the Bezier Splines. The disadvantage of these -two algorithm is that they increase the number of point. +two algorithm is that they increase the number of points. However, Hermite Interpolation can be used +as another simplification algorithm. To achieve this, it is necessary to set angle_thresh to higher values (15 or so).

        -Note that Boyle's, McMaster's and Snakes algorithm are sometime used in the signal processing to smooth the signals. +One restriction on both McMasters' Algorithms is that look_ahead parameter must be odd. Also +note that these algorithms have no effect if look_ahead = 1. +

        +

        +Note that Boyle's, McMasters' and Snakes algorithm are sometime used in the signal processing to smooth the signals. More importantly, these algorithms never change the number of points on the lines. i.e they only translate the points, they do not insert any new points.

        Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-11 17:56:02 UTC (rev 952) +++ trunk/grassaddons/v.generalize/main.c 2007-07-11 21:31:49 UTC (rev 953) @@ -33,6 +33,7 @@ #define HERMITE 7 #define SNAKES 8 #define DOUGLAS_REDUCTION 9 +#define SLIDING_AVERAGING 10 int main(int argc, char *argv[]) { @@ -44,11 +45,12 @@ struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out, *thresh_opt, *method_opt, *look_ahead_opt; struct Option *iterations_opt, *cat_opt, *alfa_opt, *beta_opt, *type_opt; - struct Option *field_opt, *where_opt, *reduction_opt; + struct Option *field_opt, *where_opt, *reduction_opt, *slide_opt; + struct Option *angle_thresh_opt; struct Flag *ca_flag; int with_z; int total_input, total_output; /* Number of points in the input/output map respectively */ - double thresh, alfa, beta, reduction; + double thresh, alfa, beta, reduction, slide, angle_thresh; int method; int look_ahead, iterations; int chcat; @@ -81,7 +83,7 @@ method_opt->required = YES; method_opt->multiple = NO; method_opt->options = - "douglas,douglas_reduction,lang,reduction,reumann,boyle,distance_weighting,chaiken,hermite,snakes"; + "douglas,douglas_reduction,lang,reduction,reumann,boyle,sliding_averaging,distance_weighting,chaiken,hermite,snakes"; method_opt->answer = "douglas"; method_opt->descriptions = _("douglas;Douglas-Peucker Algorithm;" "douglas_reduction;Douglas-Peucker Algorithm with reduction parameter;" @@ -89,6 +91,7 @@ "reduction;Vertex Reduction Algorithm eliminates points close to each other;" "reumann;Reumann-Witkam Algorithm;" "boyle;Boyle's Forward-Looking Algorithm;" + "sliding_averaging;McMaster's Sliding Averaging Algorithm;" "distance_weighting;McMaster's Distance-Weighting Algorithm;" "chaiken;Chaiken's Algorithm;" "hermite;Interpolation by Cubic Hermite Splines;" @@ -120,6 +123,24 @@ _ ("Percentage of the points in the output of 'douglas_reduction' algorithm"); + slide_opt = G_define_option(); + slide_opt->key = "slide"; + slide_opt->type = TYPE_DOUBLE; + slide_opt->required = YES; + slide_opt->answer = "0.5"; + slide_opt->options = "0-1"; + slide_opt->description = + _("Slide of computed point toward the original point"); + + angle_thresh_opt = G_define_option(); + angle_thresh_opt->key = "angle_thresh"; + angle_thresh_opt->type = TYPE_DOUBLE; + angle_thresh_opt->required = YES; + angle_thresh_opt->answer = "3"; + angle_thresh_opt->options = "0-180"; + angle_thresh_opt->description = + _("Minimum angle between two consecutive segments in Hermite method"); + alfa_opt = G_define_option(); alfa_opt->key = "alfa"; alfa_opt->type = TYPE_DOUBLE; @@ -160,6 +181,8 @@ beta = atof(beta_opt->answer); reduction = atof(reduction_opt->answer); iterations = atoi(iterations_opt->answer); + slide = atof(slide_opt->answer); + angle_thresh = atof(angle_thresh_opt->answer); mask_type = type_mask(type_opt); G_debug(3, "Method: %s", method_opt->answer); @@ -186,6 +209,12 @@ method = SNAKES; else if (strcmp(s, "douglas_reduction") == 0) method = DOUGLAS_REDUCTION; + else if (strcmp(s, "sliding_averaging") == 0) + method = SLIDING_AVERAGING; + else { + G_fatal_error(_("Unknown method")); + exit(EXIT_FAILURE); + }; /* simplification or smoothing? */ @@ -289,14 +318,17 @@ case BOYLE: boyle(Points, look_ahead, with_z); break; + case SLIDING_AVERAGING: + sliding_averaging(Points, slide, look_ahead, with_z); + break; case DISTANCE_WEIGHTING: - distance_weighting(Points, thresh, look_ahead, with_z); + distance_weighting(Points, slide, look_ahead, with_z); break; case CHAIKEN: chaiken(Points, thresh, with_z); break; case HERMITE: - hermite(Points, thresh, with_z); + hermite(Points, thresh, angle_thresh, with_z); break; case SNAKES: snakes(Points, alfa, beta, with_z); @@ -323,7 +355,7 @@ /* calculate new centroids */ Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); - n_areas = Vect_get_num_areas(&In); + n_areas = Vect_get_num_areas(&Out); for (i = 1; i <= n_areas; i++) { Vect_get_area_cats(&In, i, Cats); ret = Vect_get_point_in_area(&Out, i, &x, &y); Modified: trunk/grassaddons/v.generalize/point.c =================================================================== --- trunk/grassaddons/v.generalize/point.c 2007-07-11 17:56:02 UTC (rev 952) +++ trunk/grassaddons/v.generalize/point.c 2007-07-11 21:31:49 UTC (rev 953) @@ -92,6 +92,13 @@ (a.z - b.z) * (a.z - b.z); }; +inline double point_angle_between(POINT a, POINT b, POINT c) +{ + point_subtract(b, a, &a); + point_subtract(c, b, &b); + return acos(point_dot(a, b) / sqrt(point_dist2(a) * point_dist2(b))); +}; + POINT_LIST *point_list_new(POINT p) { POINT_LIST *pl; @@ -131,8 +138,9 @@ cur = cur->next; }; - if (0 > dig_alloc_points(Points, length)) - return (-1); + if (length != Points->n_points) + if (0 > dig_alloc_points(Points, length)) + return (-1); Points->n_points = length; @@ -157,3 +165,11 @@ p = n; }; }; + +extern void point_list_delete_next(POINT_LIST * p) +{ + POINT_LIST *t = p->next; + p->next = p->next->next; + G_free(t); + return; +}; Modified: trunk/grassaddons/v.generalize/point.h =================================================================== --- trunk/grassaddons/v.generalize/point.h 2007-07-11 17:56:02 UTC (rev 952) +++ trunk/grassaddons/v.generalize/point.h 2007-07-11 21:31:49 UTC (rev 953) @@ -54,6 +54,8 @@ extern inline double point_dist(POINT a, POINT b); /* squared distance between two points */ extern inline double point_dist_square(POINT a, POINT b); +/* angle in radians between vectors ab and bc */ +extern inline double point_angle_between(POINT a, POINT b, POINT c); /* creates empty list of points */ extern POINT_LIST *point_list_new(POINT p); /* insert new value to the list just after the l. i.e l->next.p = p */ @@ -64,4 +66,6 @@ extern int point_list_copy_to_line_pnts(POINT_LIST l, struct line_pnts *Points); /*free the momory occupied by the list at l.next */ extern void point_list_free(POINT_LIST l); +/*delete the p->next element and set the pointers appropriatelly */ +extern void point_list_delete_next(POINT_LIST * p); #endif Modified: trunk/grassaddons/v.generalize/smoothing.c =================================================================== --- trunk/grassaddons/v.generalize/smoothing.c 2007-07-11 17:56:02 UTC (rev 952) +++ trunk/grassaddons/v.generalize/smoothing.c 2007-07-11 21:31:49 UTC (rev 953) @@ -66,6 +66,70 @@ }; +/* mcmaster's sliding averaging algorithm. Return the number of points + * in the output line. This equals to the number of points in the + * input line */ +int sliding_averaging(struct line_pnts *Points, double slide, int look_ahead, + int with_z) +{ + + int n, half, i; + double sc; + POINT p, tmp, s; + POINT *res; + n = Points->n_points; + half = look_ahead / 2; + + if (look_ahead % 2 == 0) { + G_fatal_error(_("Look ahead parameter must be odd")); + return n; + }; + + if (look_ahead >= n || look_ahead == 1) + return n; + + res = G_malloc(sizeof(POINT) * n); + if (!res) { + G_fatal_error(_("Out of memory")); + return n; + }; + + sc = (double)1.0 / (double)look_ahead; + + point_assign(Points, 0, with_z, &p); + for (i = 1; i < look_ahead; i++) { + point_assign(Points, i, with_z, &tmp); + point_add(p, tmp, &p); + }; + + /* and calculate the average of remaining points */ + for (i = half; i + half < n; i++) { + point_assign(Points, i, with_z, &s); + point_scalar(s, 1.0 - slide, &s); + point_scalar(p, sc * slide, &tmp); + point_add(tmp, s, &res[i]); + if (i + half + 1 < n) { + point_assign(Points, i - half, with_z, &tmp); + point_subtract(p, tmp, &p); + point_assign(Points, i + half + 1, with_z, &tmp); + point_add(p, tmp, &p); + }; + }; + + + for (i = half; i + half < n; i++) { + Points->x[i] = res[i].x; + Points->y[i] = res[i].y; + Points->z[i] = res[i].z; + }; + + G_free(res); + return Points->n_points; + +}; + +/* mcmaster's distance weighting algorithm. Return the number + * of points in the output line which equals to Points->n_points */ int distance_weighting(struct line_pnts *Points, double slide, int look_ahead, int with_z) { @@ -77,7 +141,7 @@ n = Points->n_points; if (look_ahead % 2 == 0) { - G_warning(_("Look ahead parameter must be odd")); + G_fatal_error(_("Look ahead parameter must be odd")); return n; }; @@ -118,15 +182,13 @@ next++; }; - for (i = 0; i < next; i++) { - Points->x[i] = res[i].x; - Points->y[i] = res[i].y; - Points->z[i] = res[i].z; + for (i = half; i + half < n; i++) { + Points->x[i] = res[i - half].x; + Points->y[i] = res[i - half].y; + Points->z[i] = res[i - half].z; }; G_free(res); - - points_copy_last(Points, next); return Points->n_points; }; @@ -199,7 +261,7 @@ void refine_tangent(POINT * p) { double l = point_dist2(*p); - point_scalar(*p, 1 / sqrt(sqrt(sqrt(l))), p); + point_scalar(*p, (double)1.0 / sqrt(sqrt(sqrt(l))), p); return; }; @@ -207,9 +269,10 @@ * interpolates by steps of length step * returns the number of point in result */ -int hermite(struct line_pnts *Points, double step, int with_z) +int hermite(struct line_pnts *Points, double step, double angle_thresh, + int with_z) { - POINT_LIST head, *last; + POINT_LIST head, *last, *point; POINT p0, p1, t0, t1, tmp, res; double length, next, length_begin, l; double s; @@ -224,8 +287,11 @@ return 1; }; + /* convert degrees=>radians */ + angle_thresh *= M_PI / 180.0; + head.next = NULL; - last = &head; + point = last = &head; /* length of p[0]..p[i+1] */ i = 0; @@ -284,6 +350,17 @@ next += step; }; + /* if the angle between 2 vectors is less then eps, remove the + * middle point */ + if (point->next && point->next->next && point->next->next->next) { + if (point_angle_between + (point->next->p, point->next->next->p, + point->next->next->next->p) < angle_thresh) { + point_list_delete_next(point->next); + } + else + point = point->next; + }; }; From landa at grass.itc.it Thu Jul 12 15:12:10 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Thu Jul 12 15:12:12 2007 Subject: [grass-addons] r954 - trunk/grassaddons/gui/gui_modules Message-ID: <200707121312.l6CDCAWI010571@grass.itc.it> Author: landa Date: 2007-07-12 15:12:10 +0200 (Thu, 12 Jul 2007) New Revision: 954 Modified: trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/toolbars.py Log: Minor fixes in digit tool Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-07-11 21:31:49 UTC (rev 953) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-07-12 13:12:10 UTC (rev 954) @@ -245,22 +245,32 @@ def MoveSelectedLines(self, move): """Move selected vector features""" + return self.__MoveFeature("move", None, move) + def MoveSelectedVertex(self, coords, move): + """Move selected vertex of the line""" + return self.__MoveFeature("vertexmove", coords, move) + + def __MoveFeature(self, tool, coords, move): + """Move selected vector feature or vertex""" + if not self.driver.selected: return False Debug.msg(4, "Digit.MoveSelectedLines(): ids=%s, move=%s" % \ (self.driver.selected, move)) - print "#", move - ids = ",".join(["%d" % v for v in self.driver.selected]) - command = ["v.edit", "--q", + command = ["v.edit", "--q", "-s", # snap "map=%s" % self.map, - "tool=move", + "tool=%s" % tool, "ids=%s" % ids, - "move=%f,%f" % (float(move[0]),float(move[1]))] + "move=%f,%f" % (float(move[0]),float(move[1])), + "thresh=%f" % Digit.threshold] + if tool == "vertexmove": + command.append("coords=%f,%f" % (float(coords[0]), float(coords[1]))) + # run the command vedit = cmd.Command(cmd=command) @@ -466,16 +476,14 @@ minDist = dist minIdx = idx - # [line, node1, node2, vertex1, ...] + # [line, vertex1, ..., node1, node2] if minIdx == 0: - finalIdx = 1 + selectedId.append(self.ids[line][-2]) elif minIdx == npoints - 1: - finalIdx = 2 + selectedId.append(self.ids[line][-1]) else: - finalIdx = minIdx + 1 + selectedId.append(self.ids[line][minIdx]) - selectedId.append(self.ids[line][finalIdx]) - return selectedId def SelectLinesByBox(self, rect, onlyType=None): @@ -512,7 +520,6 @@ 0, None, type, list) - self.selected = [] for idx in range(list.n_values): line = g6lib.intArray_getitem(list.value, idx) if line not in self.selected: @@ -539,6 +546,7 @@ elif onlyType == "point": type = g6lib.GV_POINTS + line = g6lib.Vect_find_line(self.mapInfo, point[0], point[1], 0, type, Digit.threshold, 0, 0) Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-11 21:31:49 UTC (rev 953) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-12 13:12:10 UTC (rev 954) @@ -782,13 +782,11 @@ self.mouse['begin'] = self.polycoords[-1] self.DrawLines() elif digit.action == "deleteLine": - # delete selected feature - # -> unselect selected feature - # Digit.driver.SetSelected([]) pass elif digit.action in ["moveLine", "moveVertex"]: - self.moveBegin = [0,0] - self.modeIds = [] + self.moveBegin = [0, 0] + self.moveCoords = self.mouse['begin'] + self.moveIds = [] elif digit.action == "splitLine": pass elif digit.action == "displayAttributes": @@ -871,23 +869,26 @@ self.mouse['end'] = event.GetPositionTuple()[:] if digit.action in ["deleteLine", "moveLine", "moveVertex"]: if digit.action == "moveVertex": - Digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], + self.moveIds = Digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]), onlyType="line") - self.moveIds = Digit.driver.GetSelectedVertex(self.mouse['begin']) - else: # moveLine - Digit.driver.SelectLinesByBox((self.Pixel2Cell(self.mouse['begin'][0], - self.mouse['begin'][1]), - self.Pixel2Cell(self.mouse['end'][0], - self.mouse['end'][1]))) - self.moveIds = Digit.driver.GetSelected(grassId=False) + + else: # moveLine | deleteLine + self.moveIds = Digit.driver.SelectLinesByBox((self.Pixel2Cell(self.mouse['begin'][0], + self.mouse['begin'][1]), + self.Pixel2Cell(self.mouse['end'][0], + self.mouse['end'][1]))) if len(self.moveIds) > 0: self.UpdateMap(render=False) if digit.action in ["moveLine", "moveVertex"]: self.UpdateMap(render=False, redrawAll=False, removeId=self.moveIds) - - if digit.action in ["splitLine", "addVertex", "removeVertex"]: - Digit.driver.SetSelected([]) + # get pseudoDC id of objects which should be redrawn + if digit.action == "moveLine": + self.moveIds = Digit.driver.GetSelected(grassId=False) + else: + self.moveIds = Digit.driver.GetSelectedVertex(self.Pixel2Cell(self.mouse['begin'][0], + self.mouse['begin'][1])) + elif digit.action in ["splitLine", "addVertex", "removeVertex"]: Digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]), onlyType="line") self.UpdateMap(render=False) elif self.dragid != None: @@ -1029,8 +1030,7 @@ self.polycoords = [] elif digit.action == "deleteLine": Digit.DeleteSelectedLines() - elif digit.action == "moveLine": - #if Digit.driver.GetSelected(): + elif digit.action in ["moveLine", "moveVertex"] and hasattr(self, "moveBegin"): # pixel -> cell move = [self.Distance((0,0), (self.moveBegin[0], 0))[0], self.Distance((0,0), (0, self.moveBegin[1]))[0]] # TODO d.measure @@ -1039,9 +1039,14 @@ move[0] *= -1.0 if self.moveBegin[1] > 0.0: move[1] *= -1.0 + + if digit.action == "moveLine": + Digit.MoveSelectedLines(move) + else: # moveVertex + Digit.MoveSelectedVertex(self.Pixel2Cell (self.moveCoords[0], self.moveCoords[1]),move) - Digit.MoveSelectedLines(move) del self.moveBegin + del self.moveCoords del self.moveIds elif digit.action == "splitLine": Digit.SplitLine(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) @@ -1069,8 +1074,9 @@ elif digit.action in ["deleteLine", "moveLine", "splitLine", "addVertex", "removeVertex", "moveVertex"]: # unselected selected features Digit.driver.SetSelected([]) - if digit.action in ["moveLine", "moveVertex"]: + if digit.action in ["moveLine", "moveVertex"] and hasattr(self, "moveBegin"): del self.moveBegin + del self.moveCoords del self.moveIds self.UpdateMap() @@ -1091,10 +1097,10 @@ dy = self.mouse['end'][1] - self.mouse['begin'][1] self.moveBegin[0] += dx self.moveBegin[1] += dy - for id in self.moveIds: - print "#", id, dx, dy - self.pdc.TranslateId(id, dx, dy) - + if len(self.moveIds) > 0: + # draw lines on new position + for id in self.moveIds: + self.pdc.TranslateId(id, dx, dy) self.Refresh() # TODO: use RefreshRect() self.mouse['begin'] = self.mouse['end'] Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-11 21:31:49 UTC (rev 953) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-12 13:12:10 UTC (rev 954) @@ -187,9 +187,6 @@ # list of available vector maps self.UpdateListOfLayers(updateTool=True) - # additional bindings - self.parent.Bind(wx.EVT_COMBOBOX, self.OnSelectMap, self.comboid) - # realize toolbar for row in range(0, numOfRows): self.toolbar[row].Realize() @@ -358,12 +355,11 @@ selected map layer activated for editing. """ if self.layerSelectedID: # deactive map layer for editing - # TODO - pass + self.StopEditing(self.layers[self.layerSelectedID]) # select the given map layer for editing - layerSelectedID = self.combo.GetCurrentSelection() - self.StartEditing(self.layers[layerSelectedID]) + self.layerSelectedID = self.combo.GetCurrentSelection() + self.StartEditing(self.layers[self.layerSelectedID]) def StartEditing (self, layerSelected): """ @@ -445,8 +441,11 @@ #self.combo.Destroy() self.combo = wx.ComboBox(self.toolbar[0], id=wx.ID_ANY, value=value, - choices=layerNameList, size=(150, -1)) + choices=layerNameList, size=(150, -1), style=wx.CB_READONLY) + # additional bindings + self.parent.Bind(wx.EVT_COMBOBOX, self.OnSelectMap, self.comboid) + self.comboid = self.toolbar[0].InsertControl(0, self.combo) self.toolbar[0].Realize() From ullah at grass.itc.it Thu Jul 12 21:58:19 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 12 21:58:21 2007 Subject: [grass-addons] r955 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200707121958.l6CJwJBP016413@grass.itc.it> Author: ullah Date: 2007-07-12 21:58:13 +0200 (Thu, 12 Jul 2007) New Revision: 955 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: Fixed bug in soildepths and changed naming system to be consistent between all iterations to avoid "map not found" errors Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-12 13:12:10 UTC (rev 954) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-12 19:58:13 UTC (rev 955) @@ -44,7 +44,7 @@ #% key: prefx #% type: string #% description: Prefix for all output maps -#% answer: usped +#% answer: usped_ #% required : yes #% guisection: Input #%end @@ -323,54 +323,52 @@ echo "The following temporary files will be created:" echo "" -neighbors=$prefx".neighbors"$num +neighbors=$prefx"neighbors"$num echo "neighbors=$neighbors" -tempsmoothdz=$prefx".tempsmoothdz"$num +tempsmoothdz=$prefx"tempsmoothdz"$num echo "tempsmoothdz=$tempsmoothdz" -smoothdz=$prefx"_smoothdz"$num -echo "smoothdz=$smoothdz" -tempsmoothdz=$prefx".tempsmoothdz"$num +tempsmoothdz=$prefx"tempsmoothdz"$num echo "temsmoothpdz=$tempsmoothdz" -flowacc=$prefx".flowacc"$num +flowacc=$prefx"flowacc"$num echo "flowacc=$flowacc" -slope=$prefx".slope"$num +slope=$prefx"slope"$num echo "slope=$slope" -aspect=$prefx".aspect"$num +aspect=$prefx"aspect"$num echo "aspect=$aspect" -pc=$prefx".pc1" +pc=$prefx"pc1" echo "pc=$pc" -tc=$prefx".tc1" +tc=$prefx"tc1" echo "tc=$tc" -meancurv=$prefx".meancurv"$num +meancurv=$prefx"meancurv"$num echo "meancurv=$meancurv" -rate=$prefx".rate"$num +rate=$prefx"rate"$num echo "rate=$rate" -sflowtopo=$prefx".sflowtopo"$num +sflowtopo=$prefx"sflowtopo"$num echo "sflowtopo=$sflowtopo" -qsx=$prefx".qsx"$num +qsx=$prefx"qsx"$num echo "qsx=$qsx" -qsy=$prefx".qsy"$num +qsy=$prefx"qsy"$num echo "qsy=$qsy" -qsxdx=$prefx".qsx.dx"$num +qsxdx=$prefx"qsx_dx"$num echo "qsxdx=$qsxdx" -qsydy=$prefx".qsy.dy"$num +qsydy=$prefx"qsy_dy"$num echo "qsydy=$qsydy" -m=$prefx".m"$num +m=$prefx"m"$num echo "m=$m" -n=$prefx".n"$num +n=$prefx"n"$num echo "n=$n" -erdep=$prefx".erosdep"$num +erdep=$prefx"erosdep"$num echo "erdep=$erdep" echo "" - +smoothdz=$prefx"smoothdz"$num new_soil=$prefx$outsoil$num new_dem=$prefx$outdem$num -initsoil=$prefx"_initsoil" +initsoil=$prefx"initsoil" - +echo "The new net erosion/deposition map for this iteration will be called $smoothdz" 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" @@ -699,8 +697,7 @@ echo "Calculating new soil depths keeping bedrock elevations static" -new_bdrk=$initbdrk -r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" +r.mapcalc "$new_soil=if (($new_dem - $initbdrk) < 0, 0, ($new_dem - $initbdrk))" else @@ -733,8 +730,8 @@ #r.mapcalc "$new_soil=if (($smoothdz - $initbdrk) < 0, 0, ($smoothdz - $initbdrk))" #grabsomestats -tmperosion=$prfx"_tmperosion1" -tmpdep=$prfx"_tmpdep1" +tmperosion=$prfx"tmperosion"$num +tmpdep=$prfx"tmpdep"$num r.mapcalc "$tmperosion=if($smoothdz < 0, $smoothdz, null())" r.mapcalc "$tmpdep=if($smoothdz > 0, $smoothdz, null())" @@ -745,7 +742,7 @@ g.remove --quiet rast=$tmperosion,$tmpdep -txtout=$prefx"_erdep_stats.txt" +txtout=$prefx"erdep_stats.txt" echo "outputing stats to textfile: $txtout" @@ -808,56 +805,58 @@ step=$(($step+1)) # here is how we are controlling the iteration loop -old_dem=$prefx"_new_dem"$laststep +old_dem=$prefx$outdem$laststep echo "The following temporary files will be created:" echo "" -neighbors=$prefx".neighbors"$step +neighbors=$prefx"neighbors"$step echo "neighbors=$neighbors" -tempsmoothdz=$prefx".tempsmoothdz"$step +tempsmoothdz=$prefx"tempsmoothdz"$step echo "tempsmoothdz=$tempsmoothdz" -temp2smoothdz=$prefx".temp2smoothdz"$step +temp2smoothdz=$prefx"temp2smoothdz"$step echo "temp2smoothdz=$temp2smoothdz" -smoothdz=$prefx"_smoothdz"$step -echo "smoothdz=$smoothdz" -flowacc=$prefx".flowacc"$step +flowacc=$prefx"flowacc"$step echo "flowacc=$flowacc" -slope=$prefx".slope"$step +slope=$prefx"slope"$step echo "slope=$slope" -aspect=$prefx".aspect"$step +aspect=$prefx"aspect"$step echo "aspect=$aspect" -pc=$prefx".pc"$step +pc=$prefx"pc"$step echo "pc=$pc" -tc=$prefx".tc"$step +tc=$prefx"tc"$step echo "tc=$tc" -meancurv=$prefx".meancurv"$step +meancurv=$prefx"meancurv"$step echo "meancurv=$meancurv" -rate=$prefx".rate"$step +rate=$prefx"rate"$step echo "rate=$rate" -sflowtopo=$prefx".sflowtopo"$step +sflowtopo=$prefx"sflowtopo"$step echo "sflowtopo=$sflowtopo" -qsx=$prefx".qsx"$step +qsx=$prefx"qsx"$step echo "qsx=$qsx" -qsy=$prefx".qsy"$step +qsy=$prefx"qsy"$step echo "qsy=$qsy" -qsxdx=$prefx".qsx.dx"$step +qsxdx=$prefx"qsx_dx"$step echo "qsxdx=$qsxdx" -qsydy=$prefx".qsy.dy"$step +qsydy=$prefx"qsy_dy"$step echo "qsydy=$qsydy" -m=$prefx".m"$step +m=$prefx"m"$step echo "m=$m" -n=$prefx".n"$step +n=$prefx"n"$step echo "n=$n" -erdep=$prefx".erosdep"$step +erdep=$prefx"erosdep"$step echo "erdep=$erdep" -old_bdrk=$prefx"_new_bdrk"$laststep + +old_bdrk=$prefx$outbdrk$laststep echo "old_bdrk=$old_bdrk" -old_soil=$prefx"_new_soil"$laststep +old_soil=$prefx$outsoil$laststep echo "old_soil=$old_soil" echo "" +smoothdz=$prefx"smoothdz"$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 dem for this iteration will be called $new_dem" echo "The new soil depth map for this iteration will be called $new_soil" @@ -951,8 +950,6 @@ echo "" -initbdrk - if [ "$GIS_FLAG_w" -eq 1 -a "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_r" -eq 0 ]; then echo "" @@ -1072,7 +1069,7 @@ echo "*************************" echo "" -lastsmooth=$prefx"_smoothdz"$laststep +lastsmooth=$prefx"smoothdz"$laststep if [ "$GIS_FLAG_y" -eq 1 ]; then echo "" @@ -1135,7 +1132,7 @@ echo "Calculating new soil depths keeping bedrock elevations static" -new_bdrk=$old_bdrk +new_bdrk=$initbdrk r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" else From ullah at grass.itc.it Fri Jul 13 01:08:15 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Fri Jul 13 01:08:16 2007 Subject: [grass-addons] r956 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200707122308.l6CN8Foa018096@grass.itc.it> Author: ullah Date: 2007-07-13 01:08:09 +0200 (Fri, 13 Jul 2007) New Revision: 956 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: Changed cleanup section to accept new filename structure and therefore actually clean up the interim maps... Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-12 19:58:13 UTC (rev 955) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-12 23:08:09 UTC (rev 956) @@ -665,17 +665,17 @@ fi -echo "0% 104 034 139" > $TMP1 -echo "-5 violet" >> $TMP1 -echo "-3 aqua" >> $TMP1 -echo "-1 cyan" >> $TMP1 -echo "-0.5 green" >> $TMP1 +echo "100% 255 000 255" > $TMP1 +echo "5 violet" >> $TMP1 +echo "3 aqua" >> $TMP1 +echo "1 cyan" >> $TMP1 +echo "0.5 green" >> $TMP1 echo "0 white" >> $TMP1 -echo "0.5 yellow" >> $TMP1 -echo "1 orange" >> $TMP1 -echo "3 red" >> $TMP1 -echo "5 255 000 255" $TMP1 -echo "100% 255 000 255" >> $TMP1 +echo "-0.5 yellow" >> $TMP1 +echo "-1 orange" >> $TMP1 +echo "-3 red" >> $TMP1 +echo "-5 255 000 255" $TMP1 +echo "0% 104 034 139" >> $TMP1 echo "end" >> $TMP1 @@ -1100,18 +1100,17 @@ echo "creating temporary file to code colors" fi - -echo "0% 104 034 139" > $TMP1 -echo "-5 violet" >> $TMP1 -echo "-3 aqua" >> $TMP1 -echo "-1 cyan" >> $TMP1 -echo "-0.5 green" >> $TMP1 +echo "100% 255 000 255" > $TMP1 +echo "5 violet" >> $TMP1 +echo "3 aqua" >> $TMP1 +echo "1 cyan" >> $TMP1 +echo "0.5 green" >> $TMP1 echo "0 white" >> $TMP1 -echo "0.5 yellow" >> $TMP1 -echo "1 orange" >> $TMP1 -echo "3 red" >> $TMP1 -echo "5 255 000 255" $TMP1 -echo "100% 255 000 255" >> $TMP1 +echo "-0.5 yellow" >> $TMP1 +echo "-1 orange" >> $TMP1 +echo "-3 red" >> $TMP1 +echo "-5 255 000 255" $TMP1 +echo "0% 104 034 139" >> $TMP1 echo "end" >> $TMP1 @@ -1217,34 +1216,34 @@ fi -g.mlist type=rast sep=, pattern=$prefx"_smoothdz*" > $TMP2 +g.mlist type=rast sep=, pattern=$prefx"smoothdz*" > $TMP2 liststring=`cat $TMP2` echo "Any selected statistics will be performed using the following smoothdz files: $liststring" if [ "$GIS_FLAG_c" -eq 1 ]; then -r.series --q input=$liststring output=$prefx"_cum_erdep" method=sum +r.series --q input=$liststring output=$prefx"cum_erdep" method=sum fi 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 fi if [ "$GIS_FLAG_t" -eq 1 ]; then -r.series --q input=$liststring output=$prefx"_sdev_erdep" method=stddev +r.series --q input=$liststring output=$prefx"sdev_erdep" method=stddev fi if [ "$GIS_FLAG_x" -eq 1 ]; then -r.series --q input=$liststring output=$prefx"_max_erdep" method=maximum +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 +r.series --q input=$liststring output=$prefx"min_erdep" method=minimum fi @@ -1256,7 +1255,7 @@ exit 1 fi -g.mlist type=rast sep=, pattern=$prefx"_new_soil*" > $TMP3 +g.mlist type=rast sep=, pattern=$prefx$outsoil"*" > $TMP3 liststring2=`cat $TMP3` @@ -1264,23 +1263,23 @@ if [ "$GIS_FLAG_s" -eq 1 ]; then -r.series --q input=$liststring2 output=$prefx"_ave_soil" 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_soil" 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_soil" 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_soil" method=minimum +r.series --q input=$liststring2 output=$prefx"min_"$outsoil method=minimum fi \rm -f $TMP2 $TMP2.sort \rm -f $TMP3 $TMP3.sort @@ -1299,25 +1298,24 @@ echo "" echo "Cleaning up..." -g.mremove -f --q rast=$prefx".neighbors*" -g.mremove -f --q rast=$prefx".smoothdz*" -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".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".m*" -g.mremove -f --q rast=$prefx".n*" +g.mremove -f --q rast=$prefx"neighbors*" +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"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"m*" +g.mremove -f --q rast=$prefx"n*" echo "" echo "Done" @@ -1326,12 +1324,12 @@ if [ "$GIS_FLAG_n" -eq 1 ]; then - g.mremove --q rast=$prefx"_smoothdz*" + g.mremove --q rast=$prefx"smoothdz*" fi if [ "$GIS_FLAG_l" -eq 1 ]; then - g.mremove --q rast=$prefx"_new_soil*" + g.mremove --q rast=$prefx$outsoil"*" fi if [ "$GIS_FLAG_z" -eq 1 ]; then From maldacker at grass.itc.it Fri Jul 13 17:33:50 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Fri Jul 13 17:33:51 2007 Subject: [grass-addons] r957 - trunk/grassaddons/v.path.obstacles Message-ID: <200707131533.l6DFXobq030379@grass.itc.it> Author: maldacker Date: 2007-07-13 17:33:13 +0200 (Fri, 13 Jul 2007) New Revision: 957 Modified: trunk/grassaddons/v.path.obstacles/main.c trunk/grassaddons/v.path.obstacles/visibility.c Log: added support for points Modified: trunk/grassaddons/v.path.obstacles/main.c =================================================================== --- trunk/grassaddons/v.path.obstacles/main.c 2007-07-12 23:08:09 UTC (rev 956) +++ trunk/grassaddons/v.path.obstacles/main.c 2007-07-13 15:33:13 UTC (rev 957) @@ -21,6 +21,7 @@ void load_lines( struct Map_info * map, struct Point ** points, int * num_points, struct Line ** lines, int * num_lines ); void count( struct Map_info * map, int * num_points, int * num_lines); +void process_point( struct line_pnts * sites, struct Point ** points, int * index_point, int cat); void process_line( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat); void process_boundary( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat); @@ -109,7 +110,7 @@ type = Vect_read_line( map, sites, cats, i); - if ( type != GV_LINE && type != GV_BOUNDARY) + if ( type != GV_LINE && type != GV_BOUNDARY && type != GV_POINT) continue; if ( type == GV_LINE ) @@ -122,6 +123,10 @@ index_point+= sites->n_points-1; index_line+= sites->n_points-1; } + else if ( type == GV_POINT ) + { + index_point++; + } } @@ -158,7 +163,7 @@ while( ( type = Vect_read_next_line( map, sites, cats) ) > -1 ) { - if ( type != GV_LINE && type != GV_BOUNDARY) + if ( type != GV_LINE && type != GV_BOUNDARY && type != GV_POINT) continue; Vect_cat_get (cats, 1, &cat); @@ -169,12 +174,31 @@ process_line(sites, points, &index_point, lines, &index_line, -1); else if ( type == GV_BOUNDARY ) process_boundary(sites, points, &index_point, lines, &index_line, cat++); - //else if ( type == GV_POINT ) + else if ( type == GV_POINT ) + process_point( sites, points, &index_point, -1); } } +void process_point( struct line_pnts * sites, struct Point ** points, int * index_point, int cat) +{ + G_message("Processing a point"); + (*points)[*index_point].x = sites->x[0]; + (*points)[*index_point].y = sites->y[0]; + (*points)[*index_point].cat = cat; + + (*points)[*index_point].line1 = NULL; + (*points)[*index_point].line2 = NULL; + + (*points)[*index_point].left_brother = NULL; + (*points)[*index_point].right_brother = NULL; + (*points)[*index_point].father = NULL; + (*points)[*index_point].rightmost_son = NULL; + + (*index_point)++; +} + /** extract all segments from the line */ void process_line( struct line_pnts * sites, struct Point ** points, int * index_point, struct Line ** lines, int * index_line, int cat) Modified: trunk/grassaddons/v.path.obstacles/visibility.c =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-12 23:08:09 UTC (rev 956) +++ trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-13 15:33:13 UTC (rev 957) @@ -74,9 +74,13 @@ */ void handle( struct Point* p, struct Point* q, struct Map_info * out ) { - if ( q == other1(p) ) + + if ( segment1(q) == NULL && segment2(q) == NULL && before(p,q, p->vis )) { - + report(p,q,out); + } + else if ( q == other1(p) ) + { if ( segment1(q) == segment1(p) && segment2(q) != NULL && left_turn(p,q, other2(q))) { p->vis = segment2(q); @@ -95,7 +99,6 @@ } else if ( q == other2(p)) { - if ( segment1(q) == segment2(p) && segment2(q) != NULL && left_turn(p,q, other2(q))) { p->vis = segment2(q); @@ -109,37 +112,37 @@ p->vis = q->vis; } - report(p, q, out ); } else if ( segment1(q) == p->vis && segment1(q) != NULL) { - + if ( segment2(q) != NULL && left_turn(p, q, other2(q))) p->vis = segment2(q); else p->vis = q->vis ; - + // check that p and q are not on the same boundary and that the edge pq is inside the boundary if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) report( p,q, out ); } else if ( segment2(q) == p->vis && segment2(q) != NULL ) { + if ( segment1(q) != NULL && left_turn(p, q, other1(q) )) p->vis = segment1(q); else p->vis = q->vis; - + // check that p and q are not on the same boundary and that the edge pq is inside the boundary if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) report( p,q, out ); } else if ( before(p,q, p->vis ) ) { - if ( segment2(q) == NULL) + if ( segment2(q) == NULL ) p->vis = segment1(q); - else if ( segment1(q) == NULL ) + else if ( segment1(q) == NULL) p->vis = segment2(q); else if ( left_turn(p, q, other1(q) ) && !left_turn( p, q, other2(q))) p->vis = segment1(q); @@ -149,7 +152,7 @@ p->vis = segment1(q); else p->vis = segment2(q); - + // check that p and q are not on the same boundary and that the edge pq is inside the boundary if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) report(p,q,out); From bundala at grass.itc.it Sat Jul 14 00:02:18 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Sat Jul 14 00:02:20 2007 Subject: [grass-addons] r958 - trunk/grassaddons/v.generalize Message-ID: <200707132202.l6DM2IpI003399@grass.itc.it> Author: bundala Date: 2007-07-14 00:02:14 +0200 (Sat, 14 Jul 2007) New Revision: 958 Modified: trunk/grassaddons/v.generalize/description.html trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/misc.c Log: Added type: boundary, areas of area less than threshold are now removed (if simplification is selected), another bug in description.html fixed Modified: trunk/grassaddons/v.generalize/description.html =================================================================== --- trunk/grassaddons/v.generalize/description.html 2007-07-13 15:33:13 UTC (rev 957) +++ trunk/grassaddons/v.generalize/description.html 2007-07-13 22:02:14 UTC (rev 958) @@ -45,6 +45,10 @@ one parameter in common. It is threshold parameter. In general, the degree of simplification increases with the increasing value of threshold. +If some line is simplified and hence becomes shorter than threshold then it is +removed. Also, if type contains area and a simplification algorithm is selected, +the areas of area less than threshold are also removed. +

        DETAIL DESCRIPTION

        • Douglas-Peucker - "Quicksort" of line simplification, the most widely used @@ -78,9 +82,9 @@ v.generalize input=in output=out method=douglas_reduction threshold=eps reduction=0
  • However, in this case, the first method is faster. Also observe that -douglas_reduction never outputs less vertices than douglas. And that, +douglas_reduction never outputs more vertices than douglas. And that, in general, douglas is more efficient than douglas_reduction. -Also, the effect of +More importantly, the effect of
     v.generalize input=in output=out method=douglas_reduction threshold=0 reduction=X
     
    @@ -154,4 +158,4 @@
    Wolf Bergenheim, Mentor -

    Last changed: $Date: 2007/07/07 21:38:06 $ +

    Last changed: $Date: 2007/13/07 23:58:37 $ Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-13 15:33:13 UTC (rev 957) +++ trunk/grassaddons/v.generalize/main.c 2007-07-13 22:02:14 UTC (rev 958) @@ -74,8 +74,8 @@ map_out = G_define_standard_option(G_OPT_V_OUTPUT); type_opt = G_define_standard_option(G_OPT_V_TYPE); - type_opt->options = "line,boundary"; - type_opt->answer = "line,boundary"; + type_opt->options = "line,boundary,area"; + type_opt->answer = "line,boundary,area"; method_opt = G_define_option(); method_opt->key = "method"; @@ -220,6 +220,7 @@ /* simplification or smoothing? */ switch (method) { case DOUGLAS: + case DOUGLAS_REDUCTION: case LANG: case VERTEX_REDUCTION: case REUMANN: @@ -355,8 +356,12 @@ /* calculate new centroids */ Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); + n_areas = Vect_get_num_areas(&Out); for (i = 1; i <= n_areas; i++) { + /* skip dead area */ + if (!Vect_area_alive(&Out, i)) + continue; Vect_get_area_cats(&In, i, Cats); ret = Vect_get_point_in_area(&Out, i, &x, &y); if (ret < 0) { @@ -368,14 +373,20 @@ Vect_write_line(&Out, GV_CENTROID, Points, Cats); }; + /* remove small areas */ + if (simplification && (mask_type & GV_AREA)) { + Vect_build_partial(&Out, GV_BUILD_CENTROIDS, NULL); + Vect_remove_small_areas(&Out, thresh, NULL, NULL, &slide); + }; + /* finally copy tables */ if (ca_flag->answer) Vect_copy_tables(&In, &Out, layer); Vect_build(&Out, stdout); - G_message("Number of vertices was reduced from %d to %d[%d%%]", total_input, - total_output, (total_output * 100) / total_input); + G_message(_("Number of vertices was reduced from %d to %d[%d%%]"), + total_input, total_output, (total_output * 100) / total_input); Vect_close(&In); Vect_close(&Out); Modified: trunk/grassaddons/v.generalize/misc.c =================================================================== --- trunk/grassaddons/v.generalize/misc.c 2007-07-13 15:33:13 UTC (rev 957) +++ trunk/grassaddons/v.generalize/misc.c 2007-07-13 22:02:14 UTC (rev 958) @@ -34,6 +34,8 @@ case 'b': res |= GV_BOUNDARY; break; + case 'a': + res |= GV_AREA; }; return res; }; From bundala at grass.itc.it Mon Jul 16 22:24:33 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Mon Jul 16 22:24:34 2007 Subject: [grass-addons] r959 - trunk/grassaddons/v.generalize Message-ID: <200707162024.l6GKOXb8022764@grass.itc.it> Author: bundala Date: 2007-07-16 22:24:29 +0200 (Mon, 16 Jul 2007) New Revision: 959 Modified: trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/misc.c trunk/grassaddons/v.generalize/misc.h Log: Incorrect boundaries are removed, attributes of dropped features are not copied Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-13 22:02:14 UTC (rev 958) +++ trunk/grassaddons/v.generalize/main.c 2007-07-16 20:24:29 UTC (rev 959) @@ -55,11 +55,12 @@ int look_ahead, iterations; int chcat; int ret, layer; - int n_areas; + int n_areas, n_lines; double x, y; int simplification, mask_type; VARRAY *varray; char *s; + int left, right; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */ @@ -353,10 +354,30 @@ }; } + /* remove incorrect boundaries + * they may occur only if they were generalized */ + if (mask_type & GV_BOUNDARY) { + Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); + n_lines = Vect_get_num_lines(&Out); + for (i = 1; i <= n_lines; i++) { + type = Vect_read_line(&Out, Points, Cats, i); + if (type != GV_BOUNDARY) + continue; + Vect_get_line_areas(&Out, i, &left, &right); + if (left == 0 || right == 0) { + Vect_delete_line(&Out, i); + total_output -= Points->n_points; + }; + }; + }; - /* calculate new centroids */ + + /* calculate new centroids + * TODO: Don't fiddle with centroid if !(mask_type & GV_BOUNDARY) + * There's no reason to recalculate them as the ares + * are unchanged + */ Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); - n_areas = Vect_get_num_areas(&Out); for (i = 1; i <= n_areas; i++) { /* skip dead area */ @@ -379,12 +400,12 @@ Vect_remove_small_areas(&Out, thresh, NULL, NULL, &slide); }; + Vect_build(&Out, stdout); + /* finally copy tables */ if (ca_flag->answer) - Vect_copy_tables(&In, &Out, layer); + copy_tables_by_cats(&In, &Out); - Vect_build(&Out, stdout); - G_message(_("Number of vertices was reduced from %d to %d[%d%%]"), total_input, total_output, (total_output * 100) / total_input); Modified: trunk/grassaddons/v.generalize/misc.c =================================================================== --- trunk/grassaddons/v.generalize/misc.c 2007-07-13 22:02:14 UTC (rev 958) +++ trunk/grassaddons/v.generalize/misc.c 2007-07-16 20:24:29 UTC (rev 959) @@ -19,6 +19,7 @@ #include #include +#include #include #include "misc.h" @@ -70,3 +71,116 @@ *dist = d; return index; }; + +/* TODO: The collection of categories is horrible in current version! + * Rverything repeats many times. We need some data structure + * implementing set! */ +int copy_tables_by_cats(struct Map_info *In, struct Map_info *Out) +{ + /* this is the (mostly) code from v.extract, it should be move to + * some vector library (probably) */ + + int nlines, line, nfields; + int ttype, ntabs = 0; + struct field_info *IFi, *OFi; + struct line_cats *Cats; + struct line_pnts *Points; + int **ocats, *nocats, *fields; + int i; + int ret; + + /* Collect list of output cats */ + Points = Vect_new_line_struct(); + Cats = Vect_new_cats_struct(); + nfields = Vect_cidx_get_num_fields(In); + ocats = (int **)G_malloc(nfields * sizeof(int *)); + nocats = (int *)G_malloc(nfields * sizeof(int)); + fields = (int *)G_malloc(nfields * sizeof(int)); + for (i = 0; i < nfields; i++) { + nocats[i] = 0; + ocats[i] = + (int *)G_malloc(Vect_cidx_get_num_cats_by_index(In, i) * + sizeof(int)); + fields[i] = Vect_cidx_get_field_number(In, i); + } + nlines = Vect_get_num_lines(Out); + for (line = 1; line <= nlines; line++) { + Vect_read_line(Out, NULL, Cats, line); + for (i = 0; i < Cats->n_cats; i++) { + int f = 0, j; + for (j = 0; j < nfields; j++) { /* find field */ + if (fields[j] == Cats->field[i]) { + f = j; + break; + } + } + ocats[f][nocats[f]] = Cats->cat[i]; + nocats[f]++; + } + } + + /* Copy tables */ + G_message(_("Writing attributes ...\n")); + + /* Number of output tabs */ + for (i = 0; i < Vect_get_num_dblinks(In); i++) { + int j, f = -1; + + IFi = Vect_get_dblink(In, i); + + for (j = 0; j < nfields; j++) { /* find field */ + if (fields[j] == IFi->number) { + f = j; + break; + } + } + if (f >= 0 && nocats[f] > 0) + ntabs++; + } + + if (ntabs > 1) + ttype = GV_MTABLE; + else + ttype = GV_1TABLE; + + for (i = 0; i < nfields; i++) { + int ret; + + if (fields[i] == 0) + continue; + if (nocats[i] == 0) + continue; + /* if ( fields[i] == field && new_cat != -1 ) continue; */ + + G_message(_("Layer %d"), fields[i]); + /* Make a list of categories */ + IFi = Vect_get_field(In, fields[i]); + if (!IFi) { /* no table */ + G_message(_("No table.")); + continue; + } + + OFi = Vect_default_field_info(Out, IFi->number, IFi->name, ttype); + + ret = db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table, + OFi->driver, Vect_subst_var(OFi->database, + Out), + OFi->table, IFi->key, ocats[i], nocats[i]); + + if (ret == DB_FAILED) { + G_warning(_("Cannot copy table")); + } + else { + Vect_map_add_dblink(Out, OFi->number, OFi->name, OFi->table, + IFi->key, OFi->database, OFi->driver); + } + G_message(_("Done.")); + } + + for (i = 0; i < nfields; i++) + G_free(ocats[i]); + G_free(ocats); + G_free(nocats); + G_free(fields); + return 1; +}; Modified: trunk/grassaddons/v.generalize/misc.h =================================================================== --- trunk/grassaddons/v.generalize/misc.h 2007-07-13 22:02:14 UTC (rev 958) +++ trunk/grassaddons/v.generalize/misc.h 2007-07-16 20:24:29 UTC (rev 959) @@ -15,4 +15,8 @@ extern int get_furthest(struct line_pnts *Points, int a, int b, int with_z, double *dist); +/* copy attributes of In which appear in Out */ +/* returns 1 on success, 0 on failure */ +extern int copy_tables_by_cats(struct Map_info *In, struct Map_info *Out); + #endif From bundala at grass.itc.it Mon Jul 16 22:27:58 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Mon Jul 16 22:28:00 2007 Subject: [grass-addons] r960 - trunk/grassaddons/v.generalize Message-ID: <200707162027.l6GKRwst022857@grass.itc.it> Author: bundala Date: 2007-07-16 22:27:56 +0200 (Mon, 16 Jul 2007) New Revision: 960 Modified: trunk/grassaddons/v.generalize/Makefile Log: new Makefile (module needs to be compiled with some db stuff) Modified: trunk/grassaddons/v.generalize/Makefile =================================================================== --- trunk/grassaddons/v.generalize/Makefile 2007-07-16 20:24:29 UTC (rev 959) +++ trunk/grassaddons/v.generalize/Makefile 2007-07-16 20:27:56 UTC (rev 960) @@ -1,12 +1,14 @@ + MODULE_TOPDIR = ../.. -PGM = v.generalize +PGM=v.generalize -LIBES = $(VECTLIB) $(GISLIB) -DEPENDENCIES= $(VECTDEP) $(GISDEP) +LIBES = $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB) +DEPENDENCIES = $(VECTDEP) $(DBMIDEP) $(GISDEP) EXTRA_INC = $(VECT_INC) EXTRA_CFLAGS = $(VECT_CFLAGS) - + include $(MODULE_TOPDIR)/include/Make/Module.make -default: cmd +default: cmd + From maldacker at grass.itc.it Tue Jul 17 20:11:26 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Tue Jul 17 20:11:28 2007 Subject: [grass-addons] r961 - trunk/grassaddons/v.path.obstacles Message-ID: <200707171811.l6HIBQhB008477@grass.itc.it> Author: maldacker Date: 2007-07-17 20:11:13 +0200 (Tue, 17 Jul 2007) New Revision: 961 Added: trunk/grassaddons/v.path.obstacles/data_structures.c trunk/grassaddons/v.path.obstacles/data_structures.h Modified: trunk/grassaddons/v.path.obstacles/geometry.c trunk/grassaddons/v.path.obstacles/geometry.h trunk/grassaddons/v.path.obstacles/main.c trunk/grassaddons/v.path.obstacles/rotation_tree.c trunk/grassaddons/v.path.obstacles/visibility.c trunk/grassaddons/v.path.obstacles/visibility.h Log: changes in the vis initialisation function and the handle function Now the produced visibility graph is complete and there are no bugs ( well, with the files i've tested ) Added: trunk/grassaddons/v.path.obstacles/data_structures.c =================================================================== --- trunk/grassaddons/v.path.obstacles/data_structures.c (rev 0) +++ trunk/grassaddons/v.path.obstacles/data_structures.c 2007-07-17 18:11:13 UTC (rev 961) @@ -0,0 +1,159 @@ +/**************************************************************** + * MODULE: v.path.obstacles + * + * AUTHOR(S): Maximilian Maldacker + * + * + * COPYRIGHT: (C) 2002-2005 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 "data_structures.h" + + +struct Point * pop() +{ + stack_index--; + + return stack[stack_index+1]; +} + +struct Point * top() +{ + if ( stack_index > -1 ) + return stack[stack_index]; + else + return NULL; +} + +void push(struct Point * p) +{ + stack_index++; + stack[stack_index] = p; +} + +int empty_stack() +{ + return stack_index == -1; +} + +void init_stack(int size) +{ + stack_index = -1; + stack = ( struct Point * ) G_malloc( size * sizeof( struct Point ) ); +} + +/** compare the points along the x axis +*/ +int cmp_points(struct Point * v1, struct Point* v2) +{ + struct Point *p1, *p2; + p1 = (struct Point*) v1; + p2 = (struct Point*) v2; + + if( p1->x < p2->x ) + return 1; + else if( p1->x > p2->x ) + return -1; + else if ( p1->y < p2->y ) + return 1; + else if ( p1->y > p2->y ) + return -1; + else + return 0; +} + +void quickSort( struct Point a[], int l, int r) +{ + int j; + + if( l < r ) + { + // divide and conquer + j = partition( a, l, r); + quickSort( a, l, j-1); + quickSort( a, j+1, r); + } + +} + + +int partition( struct Point a[], int l, int r) +{ + int i, j; + + struct Point t,pivot; + + pivot = a[l]; + i = l; j = r+1; + + while( 1) + { + do ++i; while( cmp_points(&a[i], &pivot) < 1 && i <= r ); + do --j; while( cmp_points(&a[j], &pivot) == 1 ); + + if( i >= j ) break; + + if ( a[i].line1 != NULL) + { + if ( a[i].line1->p1 == &a[i] ) a[i].line1->p1 = &a[j]; + else a[i].line1->p2 = &a[j]; + } + + if ( a[j].line1 != NULL ) + { + if(a[j].line1->p1 == &a[j] ) a[j].line1->p1 = &a[i]; + else a[j].line1->p2 = &a[i]; + } + + if ( a[i].line2 != NULL ) + { + if( a[i].line2->p1 == &a[i] ) a[i].line2->p1 = &a[j]; + else a[i].line2->p2 = &a[j]; + } + + if ( a[j].line2 != NULL ) + { + if(a[j].line2->p1 == &a[j] ) a[j].line2->p1 = &a[i]; + else a[j].line2->p2 = &a[i]; + } + + t = a[i]; a[i] = a[j]; a[j] = t; + + } + + if ( a[l].line1 != NULL ) + { + if(a[l].line1->p1 == &a[l] ) a[l].line1->p1 = &a[j]; + else a[l].line1->p2 = &a[j]; + } + + if ( a[j].line1 != NULL ) + { + if(a[j].line1->p1 == &a[j] ) a[j].line1->p1 = &a[l]; + else a[j].line1->p2 = &a[l]; + } + + if ( a[l].line2 != NULL ) + { + if( a[l].line2->p1 == &a[l] ) a[l].line2->p1 = &a[j]; + else a[l].line2->p2 = &a[j]; + } + + if ( a[j].line2 != NULL ) + { + if( a[j].line2->p1 == &a[j] ) a[j].line2->p1 = &a[l]; + else a[j].line2->p2 = &a[l]; + } + + t = a[l]; a[l] = a[j]; a[j] = t; + + + return j; +} + + Property changes on: trunk/grassaddons/v.path.obstacles/data_structures.c ___________________________________________________________________ Name: svn:eol-style + native Added: trunk/grassaddons/v.path.obstacles/data_structures.h =================================================================== --- trunk/grassaddons/v.path.obstacles/data_structures.h (rev 0) +++ trunk/grassaddons/v.path.obstacles/data_structures.h 2007-07-17 18:11:13 UTC (rev 961) @@ -0,0 +1,33 @@ +/**************************************************************** + * MODULE: v.path.obstacles + * + * AUTHOR(S): Maximilian Maldacker + * + * + * COPYRIGHT: (C) 2002-2005 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. + * + ****************************************************************/ + #ifndef DATA_STRUCTURES_H + #define DATA_STRUCTURES_H + + #include "rotation_tree.h" + +struct Point * pop(); +struct Point * top(); +void push(struct Point * p); +int empty_stack(); +void init_stack(); + +static int stack_index; +static struct Point ** stack; + +int cmp_points(struct Point * v1, struct Point* v2); +void quickSort( struct Point a[], int l, int r); +int partition( struct Point a[], int l, int r); + +#endif \ No newline at end of file Property changes on: trunk/grassaddons/v.path.obstacles/data_structures.h ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/grassaddons/v.path.obstacles/geometry.c =================================================================== --- trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-16 20:27:56 UTC (rev 960) +++ trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-17 18:11:13 UTC (rev 961) @@ -15,54 +15,21 @@ #include "geometry.h" -/** returns the square distance between point q and segment e +/** true if q lies nearer to p than segment e, i.e. pq and e don't intersect */ -double segment_sqdistance( struct Point * q, struct Line * e ) -{ - - double e2e1x = e->p1->x - e->p2->x ; - double e2e1y = e->p1->y - e->p2->y; - - double qe1x = q->x - e->p1->x; - double qe1y = q->y - e->p1->y; - - double qe2x = q->x - e->p2->x; - double qe2y = q->y - e->p2->y; - - double s = e2e1x * qe2x + e2e1y * qe2y; - double t; - - if ( s <= 0 ) - return qe2x * qe2x + qe2y * qe2y; - - t = e2e1x * e2e1x + e2e1y * e2e1y; - - if ( s >= t ) - return qe1x * qe1x + qe1y * qe1y; - - return qe2x * qe2x + qe2y * qe2y - s * s / t ; - -} - -/** true if q lies nearer to p than segment e -*/ int before( struct Point * p, struct Point * q, struct Line * e ) { - /* first determine the square distance between p and e */ + double x1, y1, z1, x2, y2, z2; + int status; if ( e == NULL ) return 1; - - double e_distance = segment_sqdistance(p, e); - double pqx = q->x - p->x; - double pqy = q->y - p->y; - double pq_distance = pqx*pqx + pqy*pqy; - return pq_distance <= e_distance ; + status = Vect_segment_intersection (p->x, p->y, 0, q->x, q->y, 0, e->p1->x, e->p1->y, 0, e->p2->x, e->p2->y, 0, &x1, &y1, &z1, &x2, &y2, &z2, 0) == 0; + + return status; } - - /** returns true if p3 is left of the directed line p1p2 */ int left_turn( struct Point * p1, struct Point * p2, struct Point * p3 ) @@ -89,18 +56,12 @@ */ int in_between( struct Point * p, struct Line * e ) { - int a = e->p1->x < p->x && e->p2->x > p->x ; - int b = e->p2->x < p->x && e->p1->x > p->x; + int a = e->p1->x <= p->x && e->p2->x >= p->x ; + int b = e->p2->x <= p->x && e->p1->x >= p->x; return a || b; } -/** returns true if p is above the segment e ( y axis ) -*/ -int below( struct Point * p, struct Line * e ) -{ - return e->p1->y < p->y || e->p2->y < p->y ; -} /** tests if the point (x, y ) is inside the boundary of p */ @@ -125,3 +86,25 @@ return c; } +/** returns 1 if the segment intersect with the half line starting from p pointing downards + x and y are the intersection point +*/ +int segment_intersect( struct Line * line, struct Point * p, double * x, double * y ) +{ + struct Point * p1 = line->p1; + struct Point * p2 = line->p2; + double t; + + if ( in_between(p, line ) ) + { + t = ( p->x - p1->x ) / ( p2->x - p1->x ); + + *x = p->x; + *y = p1->y + t * ( p2->y - p1->y ); + + return 1; + } + else + return -1; + +} \ No newline at end of file Modified: trunk/grassaddons/v.path.obstacles/geometry.h =================================================================== --- trunk/grassaddons/v.path.obstacles/geometry.h 2007-07-16 20:27:56 UTC (rev 960) +++ trunk/grassaddons/v.path.obstacles/geometry.h 2007-07-17 18:11:13 UTC (rev 961) @@ -24,12 +24,11 @@ #include "rotation_tree.h" int point_inside( struct Point * p, double x, double y ); -int below( struct Point * p, struct Line * e ); int in_between( struct Point * p, struct Line * e ); int left_turn( struct Point * p1, struct Point * p2, struct Point * p3 ); int before( struct Point * p, struct Point * q, struct Line * e ); -double segment_sqdistance( struct Point * q, struct Line * e ); +int segment_intersect( struct Line * line, struct Point * p, double * x, double * y ); #endif Modified: trunk/grassaddons/v.path.obstacles/main.c =================================================================== --- trunk/grassaddons/v.path.obstacles/main.c 2007-07-16 20:27:56 UTC (rev 960) +++ trunk/grassaddons/v.path.obstacles/main.c 2007-07-17 18:11:13 UTC (rev 961) @@ -102,9 +102,7 @@ sites = Vect_new_line_struct(); cats = Vect_new_cats_struct(); - - G_message("N lines %d", map->plus.n_lines); - + for( i = 1; i <= map->plus.n_lines ; i++ ) { @@ -157,7 +155,6 @@ *points = G_malloc( *num_points * sizeof( struct Point )); *lines = G_malloc( *num_lines * sizeof( struct Line )); - G_message("We have %d points and %d segments", *num_points, *num_lines ); while( ( type = Vect_read_next_line( map, sites, cats) ) > -1 ) @@ -168,8 +165,6 @@ Vect_cat_get (cats, 1, &cat); - G_message("For now %d and %d", index_point, index_line ); - if ( type == GV_LINE ) process_line(sites, points, &index_point, lines, &index_line, -1); else if ( type == GV_BOUNDARY ) @@ -183,7 +178,6 @@ void process_point( struct line_pnts * sites, struct Point ** points, int * index_point, int cat) { - G_message("Processing a point"); (*points)[*index_point].x = sites->x[0]; (*points)[*index_point].y = sites->y[0]; (*points)[*index_point].cat = cat; Modified: trunk/grassaddons/v.path.obstacles/rotation_tree.c =================================================================== --- trunk/grassaddons/v.path.obstacles/rotation_tree.c 2007-07-16 20:27:56 UTC (rev 960) +++ trunk/grassaddons/v.path.obstacles/rotation_tree.c 2007-07-17 18:11:13 UTC (rev 961) @@ -55,8 +55,10 @@ else { left = q->left_brother; + p->left_brother = left; left->right_brother = p; + p->right_brother = q; q->left_brother = p; } @@ -77,7 +79,8 @@ r->left_brother = l; if ( f->rightmost_son == p ) - f->rightmost_son = NULL; + //f->rightmost_son = NULL; + f->rightmost_son = l; p->father = NULL; p->left_brother = NULL; Modified: trunk/grassaddons/v.path.obstacles/visibility.c =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-16 20:27:56 UTC (rev 960) +++ trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-17 18:11:13 UTC (rev 961) @@ -26,46 +26,32 @@ int i; int j; - int current = -1; - double current_distance = PORT_DOUBLE_MAX; - double s; + double current_distance; + double x,y; + for ( i = 0 ; i < num_points ; i++ ) { + current_distance = PORT_DOUBLE_MAX; + points[i].vis = NULL; + for ( j = 0 ; j < num_lines ; j++ ) { - if ( &lines[j] == segment1( &points[i]) || &lines[j] == segment2( &points[i])) continue; /* if it's directly below, compute its distance to the last smallest found */ - if ( below( &points[i], &lines[j] ) && in_between( &points[i], &lines[j] ) ) - { + if ( segment_intersect(&lines[j], &points[i], &x, &y) != -1 && y < points[i].y && (points[i].y - y) < current_distance) + { - s = segment_sqdistance( &points[i], &lines[j]); - - - if( s < current_distance) - { - current = j; - current_distance = s; - } + points[i].vis = &lines[j]; + current_distance = points[i].y - y; } } - - if ( current == -1 ) - { - points[i].vis = NULL; - } - else - { - points[i].vis = &lines[current]; - } - - current = -1; - current_distance = PORT_DOUBLE_MAX; + } + } @@ -73,14 +59,14 @@ /** for a pair (p, q) of points, add the edge pq if their are visibile to each other */ void handle( struct Point* p, struct Point* q, struct Map_info * out ) -{ - +{ if ( segment1(q) == NULL && segment2(q) == NULL && before(p,q, p->vis )) { report(p,q,out); } - else if ( q == other1(p) ) + else if ( segment1(p) != NULL && q == other1(p) ) { + /* we need to check if there is another segment at q so it can be set to the vis */ if ( segment1(q) == segment1(p) && segment2(q) != NULL && left_turn(p,q, other2(q))) { p->vis = segment2(q); @@ -90,15 +76,13 @@ p->vis = segment1(q); } else - { p->vis = q->vis; - } - report( p, q, out ); } - else if ( q == other2(p)) + else if ( segment2(p) != NULL && q == other2(p)) { + /* we need to check if there is another segment at q so it can be set to the vis */ if ( segment1(q) == segment2(p) && segment2(q) != NULL && left_turn(p,q, other2(q))) { p->vis = segment2(q); @@ -108,42 +92,43 @@ p->vis = segment1(q); } else - { p->vis = q->vis; - } - + report(p, q, out ); } else if ( segment1(q) == p->vis && segment1(q) != NULL) { - + /* we need to check if there is another segment at q so it can be set to the vis */ if ( segment2(q) != NULL && left_turn(p, q, other2(q))) p->vis = segment2(q); else p->vis = q->vis ; - // check that p and q are not on the same boundary and that the edge pq is inside the boundary + /* check that p and q are not on the same boundary and that the edge pq is inside the boundary*/ if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) report( p,q, out ); } else if ( segment2(q) == p->vis && segment2(q) != NULL ) { - + /* we need to check if there is another segment at q so it can be set to the vis */ if ( segment1(q) != NULL && left_turn(p, q, other1(q) )) p->vis = segment1(q); else p->vis = q->vis; - // check that p and q are not on the same boundary and that the edge pq is inside the boundary + /* check that p and q are not on the same boundary and that the edge pq is inside the boundary */ if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) report( p,q, out ); } else if ( before(p,q, p->vis ) ) { + /* if q only has one segment, then this is the new vis */ if ( segment2(q) == NULL ) p->vis = segment1(q); else if ( segment1(q) == NULL) p->vis = segment2(q); + + /* otherwise take the one with biggest slope*/ else if ( left_turn(p, q, other1(q) ) && !left_turn( p, q, other2(q))) p->vis = segment1(q); else if ( !left_turn(p, q, other1(q) ) && left_turn( p, q, other2(q))) @@ -153,7 +138,7 @@ else p->vis = segment2(q); - // check that p and q are not on the same boundary and that the edge pq is inside the boundary + /* check that p and q are not on the same boundary and that the edge pq is inside the boundary */ if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) report(p,q,out); } @@ -207,6 +192,7 @@ p_infinity->rightmost_son = NULL; init_stack(num_points); + /* sort points in decreasing x order*/ quickSort( points, 0, num_points-1 ); @@ -274,140 +260,3 @@ } -struct Point * pop() -{ - stack_index--; - - return stack[stack_index+1]; -} - -struct Point * top() -{ - return stack[stack_index]; -} - -void push(struct Point * p) -{ - stack_index++; - stack[stack_index] = p; -} - -int empty_stack() -{ - return stack_index == 0; -} - -void init_stack(int size) -{ - stack_index = 0; - stack = G_malloc( size * sizeof( struct Point ) ); -} - -/** compare the points along the x axis -*/ -int cmp_points(struct Point * v1, struct Point* v2) { - struct Point *p1, *p2; - p1 = (struct Point*) v1; - p2 = (struct Point*) v2; - - if( p1->x < p2->x ) - return 1; - else if( p1->x > p2->x ) - return -1; - else if ( p1->y < p2->y ) - return 1; - else if ( p1->y > p2->y ) - return -1; - else - return 0; -} - -void quickSort( struct Point a[], int l, int r) -{ - int j; - - if( l < r ) - { - // divide and conquer - j = partition( a, l, r); - quickSort( a, l, j-1); - quickSort( a, j+1, r); - } - -} - - -int partition( struct Point a[], int l, int r) -{ - int i, j; - - struct Point t,pivot; - - pivot = a[l]; - i = l; j = r+1; - - while( 1) - { - do ++i; while( cmp_points(&a[i], &pivot) < 1 && i <= r ); - do --j; while( cmp_points(&a[j], &pivot) == 1 ); - - if( i >= j ) break; - - if ( a[i].line1 != NULL) - { - if ( a[i].line1->p1 == &a[i] ) a[i].line1->p1 = &a[j]; - else a[i].line1->p2 = &a[j]; - } - - if ( a[j].line1 != NULL ) - { - if(a[j].line1->p1 == &a[j] ) a[j].line1->p1 = &a[i]; - else a[j].line1->p2 = &a[i]; - } - - if ( a[i].line2 != NULL ) - { - if( a[i].line2->p1 == &a[i] ) a[i].line2->p1 = &a[j]; - else a[i].line2->p2 = &a[j]; - } - - if ( a[j].line2 != NULL ) - { - if(a[j].line2->p1 == &a[j] ) a[j].line2->p1 = &a[i]; - else a[j].line2->p2 = &a[i]; - } - - t = a[i]; a[i] = a[j]; a[j] = t; - - } - - if ( a[l].line1 != NULL ) - { - if(a[l].line1->p1 == &a[l] ) a[l].line1->p1 = &a[j]; - else a[l].line1->p2 = &a[j]; - } - - if ( a[j].line1 != NULL ) - { - if(a[j].line1->p1 == &a[j] ) a[j].line1->p1 = &a[l]; - else a[j].line1->p2 = &a[l]; - } - - if ( a[l].line2 != NULL ) - { - if( a[l].line2->p1 == &a[l] ) a[l].line2->p1 = &a[j]; - else a[l].line2->p2 = &a[j]; - } - - if ( a[j].line2 != NULL ) - { - if( a[j].line2->p1 == &a[j] ) a[j].line2->p1 = &a[l]; - else a[j].line2->p2 = &a[l]; - } - - t = a[l]; a[l] = a[j]; a[j] = t; - - - return j; -} - Modified: trunk/grassaddons/v.path.obstacles/visibility.h =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.h 2007-07-16 20:27:56 UTC (rev 960) +++ trunk/grassaddons/v.path.obstacles/visibility.h 2007-07-17 18:11:13 UTC (rev 961) @@ -21,6 +21,7 @@ #include #include #include +#include "data_structures.h" #include "geometry.h" #include "rotation_tree.h" @@ -32,18 +33,7 @@ void init_vis( struct Point * points, int num_points, struct Line * lines, int num_lines ); -struct Point * pop(); -struct Point * top(); -void push(struct Point * p); -int empty_stack(); -void init_stack(); -static int stack_index; -static struct Point ** stack; -int cmp_points(struct Point * v1, struct Point* v2); -void quickSort( struct Point a[], int l, int r); -int partition( struct Point a[], int l, int r); - #endif From landa at grass.itc.it Wed Jul 18 13:46:05 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Jul 18 13:46:08 2007 Subject: [grass-addons] r962 - trunk/grassaddons/gui/gui_modules Message-ID: <200707181146.l6IBk5aB025523@grass.itc.it> Author: landa Date: 2007-07-18 13:46:05 +0200 (Wed, 18 Jul 2007) New Revision: 962 Modified: trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/toolbars.py Log: Each map window works with unique digit instance WARNING: Still using PyDisplayDriver, drawing of map on the canvas is extremely slow. C driver under development. Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-07-17 18:11:13 UTC (rev 961) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-07-18 11:46:05 UTC (rev 962) @@ -2,9 +2,12 @@ MODULE: digit CLASSES: + * AbstractDigit * VEdit * VDigit - * DisplayDriver + * AbstractDisplayDriver + * PyDisplayDriver + * CDisplayDriver * SettingsDialog PURPOSE: Digitization tool wxPython GUI prototype @@ -15,6 +18,9 @@ (1) v.edit called on the background (class VEdit) (2) Reimplentation of v.digit (VDigit) + Import: + from digit import Digit as Digit + AUTHORS: The GRASS Development Team Martin Landa @@ -49,11 +55,19 @@ """ Abstract digitization class """ - def __init__(self, settings=None): - self.map = None - self.driver = None - self.threshold = 0 # set by driver constructor + def __init__(self, mapwindow, settings=None): + self.map = None + + Debug.msg (3, "AbstractDigit.__init__(): map=%s" % \ + self.map) + + #self.SetCategory() + self.driver = PyDisplayDriver(self, mapwindow) + + #self.threshold = self.driver.GetThreshold() + + # is unique for map window instance if not settings: self.settings = {} # symbology @@ -77,6 +91,7 @@ # snapping self.settings["snapping"] = (10, "screen pixels") # value, unit self.settings["snapToVertex"] = False + # digitize new record self.settings["addRecord"] = True self.settings["layer"] = 1 @@ -91,7 +106,6 @@ Returns 'True' on success, 'False' on failure """ - if self.map: categoryCmd = cmd.Command(cmd=["v.category", "-g", "--q", "input=%s" % self.map, @@ -99,7 +113,7 @@ "layer=%d" % self.settings["layer"]]) if categoryCmd.returncode != 0: - return + return False for line in categoryCmd.ReadStdOutput(): if "all" in line: @@ -124,28 +138,21 @@ return self.settings["category"] - def ReInitialize(self, map=None, mapwindow=None): - """Re-initialize settings according selected map layer""" + def SetMapName(self, map): + """Set map name""" + Debug.msg (3, "AbstractDigit.SetMapName map=%s" % map) self.map = map + + self.driver.Reset(self.map) - if self.map: - Debug.msg (3, "AbstractDigit.ReInitialize(): map=%s" % \ - map) - - self.SetCategory() - self.driver = DisplayDriver(map, mapwindow) - else: - del self.driver - self.driver = None - class VEdit(AbstractDigit): """ Prototype of digitization class based on v.edit command Note: This should be replaced by VDigit class. """ - def __init__(self, settings=None): - AbstractDigit.__init__(self, settings) + def __init__(self, mapwindow, settings=None): + AbstractDigit.__init__(self, mapwindow, settings) def AddPoint (self, map, type, x, y, z=None): """ @@ -339,79 +346,43 @@ """ pass -class DisplayDriver: - """ - Experimental display driver implemented in Python using - GRASS-Python SWIG interface +class Digit(VEdit): + """Default digit class""" + def __init__(self, mapwindow): + VEdit.__init__(self, mapwindow) - Note: This will be in the future rewritten in C/C++ - """ - def __init__(self, map, mapwindow): +class AbstractDisplayDriver: + """Abstract classs for display driver""" + def __init__(self, parent, mapwindow): + self.parent = parent self.mapwindow = mapwindow - Digit.threshold = self.GetThreshold() - self.ids = {} # dict[g6id] = [pdcId] self.selected = [] # list of selected objects (grassId!) - g6lib.G_gisinit('') - - 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 __del__(self): - if self.mapInfo: - g6lib.Vect_close(self.mapInfo) - if self.points: - g6lib.Vect_destroy_line_struct(self.points) - if self.cats: - g6lib.Vect_destroy_cats_struct(self.cats) - def GetThreshold(self): """Return threshold in map units""" if Digit.settings["snapping"][1] == "screen pixels": # pixel -> cell threshold = self.mapwindow.Distance(beginpt=(0,0), - endpt=(Digit.settings["snapping"][0],0))[0] + endpt=(Digit.settings["snapping"][0],0))[0] else: threshold = Digit.settings["snapping"][0] - Debug.msg(4, "DisplayDriver.GetThreshold(): thresh=%f" % threshold) + Debug.msg(4, "AbstractDisplayDriver.GetThreshold(): thresh=%f" % threshold) + return threshold - def __SetPen(self, line, symbol): - # see include/vect/dig_defines.h - # define GV_POINT 0x01 - # define GV_LINE 0x02 - # define GV_BOUNDARY 0x04 - # define GV_CENTROID 0x08 - # define GV_FACE 0x10 - # define GV_KERNEL 0x20 - # define GV_AREA 0x40 - # define GV_VOLUME 0x80 - + def SetPen(self, line, symbol): + """Set Pen for PseudoDC according vector feature status""" + if line in self.selected: symbol = "symbolHighlight" - width = Digit.settings["lineWidth"][0] + width = self.parent.settings["lineWidth"][0] - if Digit.settings[symbol][0] in [True, None]: - self.mapwindow.pen = self.mapwindow.polypen = wx.Pen(colour=Digit.settings[symbol][1], + 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 @@ -443,6 +414,63 @@ pdcId.append(id) return pdcId + def DrawMap(self): + """Draw map content in PseudoDC""" + Debug.msg(4, "DisplayDriver.DrawMap()") + self.DisplayLines() + +class CDisplayDriver(AbstractDisplayDriver): + """ + Display driver using grass6_wxdriver module + """ + pass + +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 Reset(self, map): + g6lib.G_gisinit('') + + print map + 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 __del__(self): + if self.points: + g6lib.Vect_destroy_line_struct(self.points) + if self.cats: + g6lib.Vect_destroy_cats_struct(self.cats) + def GetSelectedVertex(self, coords): """Return PseudoDC id(s) of vertex (of selected line) on position 'coords'""" @@ -548,7 +576,7 @@ line = g6lib.Vect_find_line(self.mapInfo, point[0], point[1], 0, - type, Digit.threshold, 0, 0) + type, self.parent.threshold, 0, 0) self.selected = [] if line > 0: @@ -568,13 +596,11 @@ self.DrawMap() - def DrawMap(self): - """Draw map content in PseudoDC""" - Debug.msg(4, "DisplayDriver.DrawMap()") - self.DisplayLines() - def DisplayLines(self): """Display all lines in PseudoDC""" + if not self.mapInfo: + return + nlines = g6lib.Vect_get_num_lines(self.mapInfo) Debug.msg(4, "DisplayDriver.DisplayLines(): nlines=%d" % nlines) #symb_set_driver_color ( SYMB_HIGHLIGHT ); @@ -622,9 +648,9 @@ g6lib.doublep_value(y))) if g6lib.Vect_get_node_n_lines(self.mapInfo, node) == 1: - self.__SetPen(line, "symbolNodeOne") # one line + self.SetPen(line, "symbolNodeOne") # one line else: - self.__SetPen(line, "symbolNodeTwo") # two lines + self.SetPen(line, "symbolNodeTwo") # two lines self.ids[line].append(self.mapwindow.DrawCross(coords, size=5)) @@ -656,18 +682,18 @@ leftp, rightp) left, right = g6lib.intp_value(leftp), g6lib.intp_value(rightp) if left == 0 and right == 0: - self.__SetPen(line, "symbolBoundaryNo") + self.SetPen(line, "symbolBoundaryNo") elif left > 0 and right > 0: - self.__SetPen(line, "symbolBoundaryTwo") + self.SetPen(line, "symbolBoundaryTwo") else: - self.__SetPen(line, "symbolBoundaryOne") + self.SetPen(line, "symbolBoundaryOne") g6lib.delete_intp(leftp) g6lib.delete_intp(rightp) else: # GV_LINE - self.__SetPen(line, "symbolLine") + self.SetPen(line, "symbolLine") self.ids[line].append(self.mapwindow.DrawLines(coords)) # draw verteces - self.__SetPen(line, "symbolVertex") + self.SetPen(line, "symbolVertex") for idx in range(1, npoints-1): self.ids[line].append(self.mapwindow.DrawCross(coords[idx], size=4)) # draw nodes @@ -676,15 +702,15 @@ if type == g6lib.GV_CENTROID: cret = g6lib.Vect_get_centroid_area(self.mapInfo, line) if cret > 0: # -> area - self.__SetPen(line, "symbolCentroidIn") + self.SetPen(line, "symbolCentroidIn") elif cret == 0: - self.__SetPen(line, "symbolCentroidOut") + self.SetPen(line, "symbolCentroidOut") else: - self.__SetPen(line, "symbolCentroidDup") + self.SetPen(line, "symbolCentroidDup") else: - self.__SetPen(line, "symbolPoint") + self.SetPen(line, "symbolPoint") self.ids[line].append(self.mapwindow.DrawCross(coords[0], size=5)) - + class DigitSettingsDialog(wx.Dialog): """ Standard settings dialog for digitization purposes @@ -697,7 +723,7 @@ # notebook notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) self.__CreateSymbologyPage(notebook) - Digit.SetCategory() # update category number (next to use) + parent.digit.SetCategory() # update category number (next to use) self.__CreateSettingsPage(notebook) # buttons @@ -740,8 +766,8 @@ for label, key in self.__SymbologyData(): textLabel = wx.StaticText(panel, wx.ID_ANY, label) color = csel.ColourSelect(panel, id=wx.ID_ANY, - colour=Digit.settings[key][1], size=(25, 25)) - isEnabled = Digit.settings[key][0] + colour=self.parent.digit.settings[key][1], size=(25, 25)) + isEnabled = self.parent.digit.settings[key][0] if isEnabled is not None: enabled = wx.CheckBox(panel, id=wx.ID_ANY, label="") enabled.SetValue(isEnabled) @@ -778,11 +804,11 @@ # 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(Digit.settings["lineWidth"][0]), + value=str(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"]) - self.lineWidthUnit.SetValue(Digit.settings["lineWidth"][1]) + self.lineWidthUnit.SetValue(self.parent.digit.settings["lineWidth"][1]) flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) flexSizer.Add(self.lineWidthValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE) flexSizer.Add(self.lineWidthUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE) @@ -800,17 +826,17 @@ # 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(Digit.settings["snapping"][0]), min=1, max=1e6) + value=str(self.parent.digit.settings["snapping"][0]), min=1, max=1e6) self.snappingUnit = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(125, -1), choices=["screen pixels", "map units"]) - self.snappingUnit.SetValue(Digit.settings["snapping"][1]) + self.snappingUnit.SetValue(self.parent.digit.settings["snapping"][1]) 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) vertexSizer = wx.BoxSizer(wx.VERTICAL) self.snapVertex = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_("Snap also to vertex")) - self.snapVertex.SetValue(Digit.settings["snapToVertex"]) + self.snapVertex.SetValue(self.parent.digit.settings["snapToVertex"]) vertexSizer.Add(item=self.snapVertex, proportion=0, flag=wx.ALL | wx.EXPAND, border=1) sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1) @@ -825,7 +851,7 @@ # checkbox self.addRecord = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_("Add new record into table")) - self.addRecord.SetValue(Digit.settings["addRecord"]) + self.addRecord.SetValue(self.parent.digit.settings["addRecord"]) sizer.Add(item=self.addRecord, proportion=0, flag=wx.ALL | wx.EXPAND, border=1) # settings flexSizer = wx.FlexGridSizer(cols=2, hgap=3, vgap=3) @@ -834,15 +860,15 @@ # layer text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Layer")) self.layer = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1), - value=str(Digit.settings["layer"])) # TODO: validator + value=str(self.parent.digit.settings["layer"])) # TODO: validator flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) flexSizer.Add(item=self.layer, proportion=0, flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) # category number text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category number")) self.category = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1), - value=str(Digit.settings["category"])) # TODO: validator - if Digit.settings["categoryMode"] != "Manual entry": + value=str(self.parent.digit.settings["category"])) # TODO: validator + if self.parent.digit.settings["categoryMode"] != "Manual entry": self.category.SetEditable(False) self.category.Enable(False) flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) @@ -853,7 +879,7 @@ self.categoryMode = wx.ComboBox(parent=panel, id=wx.ID_ANY, style=wx.CB_SIMPLE | wx.CB_READONLY, size=(125, -1), choices=[_("Next to use"), _("Manual entry"), _("No category")]) - self.categoryMode.SetValue(Digit.settings["categoryMode"]) + self.categoryMode.SetValue(self.parent.digit.settings["categoryMode"]) flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) flexSizer.Add(item=self.categoryMode, proportion=0, flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) @@ -896,7 +922,7 @@ """Change category mode""" mode = event.GetString() - Digit.settings["categoryMode"] = mode + self.parent.digit.settings["categoryMode"] = mode if mode == "Manual entry": # enable self.category.Enable(True) self.category.SetEditable(True) @@ -906,12 +932,12 @@ if mode == "No category" and self.addRecord.IsChecked(): self.addRecord.SetValue(False) - Digit.SetCategory() - self.category.SetValue(str(Digit.settings['category'])) + self.parent.digit.SetCategory() + self.category.SetValue(str(self.parent.digit.settings['category'])) def OnChangeAddRecord(self, event): """Checkbox 'Add new record' status changed""" - self.category.SetValue(str(Digit.SetCategory())) + self.category.SetValue(str(self.parent.digit.SetCategory())) def OnOK(self, event): """Button 'OK' clicked""" @@ -923,39 +949,33 @@ self.UpdateSettings() def UpdateSettings(self): - """Update Digit.settings""" + """Update self.parent.digit.settings""" # symbology for key, (enabled, color) in self.symbology.iteritems(): if enabled: - Digit.settings[key] = (enabled.IsChecked(), color.GetColour()) + self.parent.digit.settings[key] = (enabled.IsChecked(), color.GetColour()) else: - Digit.settings[key] = (None, color.GetColour()) + self.parent.digit.settings[key] = (None, color.GetColour()) # display - Digit.settings["lineWidth"] = (int(self.lineWidthValue.GetValue()), + self.parent.digit.settings["lineWidth"] = (int(self.lineWidthValue.GetValue()), self.lineWidthUnit.GetValue()) # snapping - Digit.settings["snapping"] = (int(self.snappingValue.GetValue()), # value + self.parent.digit.settings["snapping"] = (int(self.snappingValue.GetValue()), # value self.snappingUnit.GetValue()) # unit - Digit.settings["snapToVertex"] = self.snapVertex.IsChecked() + self.parent.digit.settings["snapToVertex"] = self.snapVertex.IsChecked() # digitize new feature - Digit.settings["addRecord"] = self.addRecord.IsChecked() - Digit.settings["layer"] = int(self.layer.GetValue()) - if Digit.settings["categoryMode"] == "No category": - Digit.settings["category"] = None + self.parent.digit.settings["addRecord"] = self.addRecord.IsChecked() + self.parent.digit.settings["layer"] = int(self.layer.GetValue()) + if self.parent.digit.settings["categoryMode"] == "No category": + self.parent.digit.settings["category"] = None else: - Digit.settings["category"] = int(self.category.GetValue()) - Digit.settings["categoryMode"] = self.categoryMode.GetValue() + self.parent.digit.settings["category"] = int(self.category.GetValue()) + self.parent.digit.settings["categoryMode"] = self.categoryMode.GetValue() # threshold try: - Digit.threshold = Digit.driver.GetThreshold() + self.parent.digit.threshold = self.parent.digit.driver.GetThreshold() except: pass - -############################## -# digitization class instance -############################## - -Digit = VEdit() Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-17 18:11:13 UTC (rev 961) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-18 11:46:05 UTC (rev 962) @@ -512,10 +512,10 @@ (self.Map.region["w"], self.Map.region["e"], self.Map.region["n"], self.Map.region["s"]), 0) - digit = self.parent.digittoolbar - if digit and Digit.driver: + digitActive = self.parent.digittoolbar + if digitActive and self.parent.digit.driver: self.pen = wx.Pen(colour='red', width=2, style=wx.SOLID) - Digit.driver.DrawMap() + self.parent.digit.driver.DrawMap() def EraseMap(self): """ @@ -1532,6 +1532,11 @@ # self.projinfo = self.Map.ProjInfo() + # + # Initialization of digitization tool + # + self.digit = Digit(mapwindow=self.MapWindow) + def AddToolbar(self, name): """ Add defined toolbar to the window Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-17 18:11:13 UTC (rev 961) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-07-18 11:46:05 UTC (rev 962) @@ -380,9 +380,9 @@ Debug.msg (4, "DigitToolbar.StartEditing(): layerSelectedID=%d layer=%s" % \ (self.layerSelectedID, mapLayer.name)) - - Digit.ReInitialize(mapLayer.name, self.parent.MapWindow) + self.parent.digit.SetMapName(mapLayer.name) + # deactive layer self.mapcontent.ChangeLayerActive(mapLayer, False) @@ -404,7 +404,7 @@ # re-active layer self.mapcontent.ChangeLayerActive(layerSelected, True) - Digit.ReInitialize() + self.parent.digit.SetMapName(None) return True From landa at grass.itc.it Wed Jul 18 16:58:31 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Jul 18 16:58:33 2007 Subject: [grass-addons] r963 - trunk/grassaddons/gui/gui_modules Message-ID: <200707181458.l6IEwVLm030794@grass.itc.it> Author: landa Date: 2007-07-18 16:58:31 +0200 (Wed, 18 Jul 2007) New Revision: 963 Modified: trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Additional fixes for Each map window works with unique digit instance WARNING: Still using PyDisplayDriver, drawing of map on the canvas is extremely slow. C driver under development. Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-07-18 11:46:05 UTC (rev 962) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-07-18 14:58:31 UTC (rev 963) @@ -30,6 +30,7 @@ for details. """ +import os import sys import string @@ -40,17 +41,24 @@ import dbm from debug import Debug as Debug -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." +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: + driverPath = os.path.join( os.getenv("GISBASE"), "etc","wx", "display_driver") + sys.path.append(driverPath) + from grass6_wxdriver import DisplayDriver + class AbstractDigit: """ Abstract digitization class @@ -62,11 +70,12 @@ self.map) #self.SetCategory() - - self.driver = PyDisplayDriver(self, mapwindow) - #self.threshold = self.driver.GetThreshold() - + if usePyDisplayDriver: + self.driver = PyDisplayDriver(self, mapwindow) + else: + self.driver = CDisplayDriver(self, mapwindow) + # is unique for map window instance if not settings: self.settings = {} @@ -100,6 +109,8 @@ else: self.settings = settings + self.threshold = self.driver.GetThreshold() + def SetCategoryNextToUse(self): """Find maximum category number in the map layer and update Digit.settings['category'] @@ -215,8 +226,6 @@ "tool=add", "thresh=%f" % self.threshold] - print "#", self.threshold - # additional flags for flag in flags: command.append(flag) @@ -273,7 +282,7 @@ "tool=%s" % tool, "ids=%s" % ids, "move=%f,%f" % (float(move[0]),float(move[1])), - "thresh=%f" % Digit.threshold] + "thresh=%f" % self.threshold] if tool == "vertexmove": command.append("coords=%f,%f" % (float(coords[0]), float(coords[1]))) @@ -356,16 +365,16 @@ def __init__(self, parent, mapwindow): self.parent = parent self.mapwindow = mapwindow - + self.ids = {} # dict[g6id] = [pdcId] self.selected = [] # list of selected objects (grassId!) def GetThreshold(self): """Return threshold in map units""" - if Digit.settings["snapping"][1] == "screen pixels": + if self.parent.settings["snapping"][1] == "screen pixels": # pixel -> cell threshold = self.mapwindow.Distance(beginpt=(0,0), - endpt=(Digit.settings["snapping"][0],0))[0] + endpt=(self.parent.settings["snapping"][0],0))[0] else: threshold = Digit.settings["snapping"][0] @@ -414,17 +423,26 @@ pdcId.append(id) return pdcId - def DrawMap(self): - """Draw map content in PseudoDC""" - Debug.msg(4, "DisplayDriver.DrawMap()") - self.DisplayLines() - class CDisplayDriver(AbstractDisplayDriver): """ Display driver using grass6_wxdriver module """ - pass - + def __init__(self, parent, mapwindow): + AbstractDisplayDriver.__init__(self, parent, mapwindow) + self.display = DisplayDriver(None) + + def Reset(self, map): + if map: + name, mapset = map.split('@') + self.display.Reset(name, mapset) + else: + self.display.Reset1() + + def DrawMap(self): + """Display content of the map in PseudoDC""" + nlines = self.display.DrawMap() + Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d" % nlines) + class PyDisplayDriver(AbstractDisplayDriver): """ Experimental display driver implemented in Python using @@ -434,12 +452,17 @@ """ def __init__(self, parent, mapwindow): AbstractDisplayDriver.__init__(self, parent, mapwindow) - self.mapInfo = None - + 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('') - print map if map == None: if self.mapInfo: g6lib.Vect_close(self.mapInfo) @@ -465,12 +488,6 @@ self.points = g6lib.Vect_new_line_struct(); self.cats = g6lib.Vect_new_cats_struct(); - def __del__(self): - if self.points: - g6lib.Vect_destroy_line_struct(self.points) - if self.cats: - g6lib.Vect_destroy_cats_struct(self.cats) - def GetSelectedVertex(self, coords): """Return PseudoDC id(s) of vertex (of selected line) on position 'coords'""" @@ -596,17 +613,14 @@ self.DrawMap() - def DisplayLines(self): - """Display all lines in PseudoDC""" + 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, "DisplayDriver.DisplayLines(): nlines=%d" % nlines) - #symb_set_driver_color ( SYMB_HIGHLIGHT ); + Debug.msg(4, "PyDisplayDriver.DrawMap(): nlines=%d" % nlines) + for line in range(1, nlines + 1): - #symb = LineSymb[i]; - #if ( !Symb[symb].on ) continue; self.DisplayLine(line) return nlines Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-18 11:46:05 UTC (rev 962) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-18 14:58:31 UTC (rev 963) @@ -512,8 +512,8 @@ (self.Map.region["w"], self.Map.region["e"], self.Map.region["n"], self.Map.region["s"]), 0) - digitActive = self.parent.digittoolbar - if digitActive and self.parent.digit.driver: + digitToolbar = self.parent.digittoolbar + if digitToolbar and self.parent.digit.driver: self.pen = wx.Pen(colour='red', width=2, style=wx.SOLID) self.parent.digit.driver.DrawMap() @@ -726,12 +726,12 @@ elif self.mouse["use"] == "pointer" and self.parent.digittoolbar: # digitization - digit = self.parent.digittoolbar + digitToolbar = self.parent.digittoolbar east, north = self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]) try: - map = digit.layers[digit.layerSelectedID].name + map = digitToolbar.layers[digitToolbar.layerSelectedID].name except: map = None dlg = wx.MessageDialog(self, _("No vector map layer selected for editing"), @@ -750,20 +750,20 @@ 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 digit.action == "addLine": - if digit.type in ["point", "centroid"]: + if digitToolbar.action == "addLine": + if digitToolbar.type in ["point", "centroid"]: # add new point #self.DrawCross(self.mouse['begin'], 5) - Digit.AddPoint(map=map, - type=digit.type, - x=east, y=north) + self.parent.digit.AddPoint(map=map, + type=digitToolbar.type, + x=east, y=north) # add new record into atribute table - if Digit.settings["addRecord"]: + if self.parent.digit.settings["addRecord"]: # select attributes based on layer and category addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, - layer=Digit.settings["layer"], - cat=Digit.settings["category"], + layer=self.parent.digit.settings["layer"], + cat=self.parent.digit.settings["category"], pos=posWindow, action="add") if addRecordDlg.mapInfo and \ @@ -776,20 +776,20 @@ "input=%s" % sqlfile.name]) self.UpdateMap() # redraw map - elif digit.type in ["line", "boundary"]: + elif digitToolbar.type in ["line", "boundary"]: # add new point to the line self.polycoords.append(event.GetPositionTuple()[:]) self.mouse['begin'] = self.polycoords[-1] self.DrawLines() - elif digit.action == "deleteLine": + elif digitToolbar.action == "deleteLine": pass - elif digit.action in ["moveLine", "moveVertex"]: + elif digitToolbar.action in ["moveLine", "moveVertex"]: self.moveBegin = [0, 0] self.moveCoords = self.mouse['begin'] self.moveIds = [] - elif digit.action == "splitLine": + elif digitToolbar.action == "splitLine": pass - elif digit.action == "displayAttributes": + elif digitToolbar.action == "displayAttributes": 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, @@ -798,7 +798,7 @@ pos=posWindow, action="update") if not updateRecordDlg.mapInfo and \ - Digit.settings["addRecord"]: + self.parent.digit.settings["addRecord"]: updateRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, layer=-1, queryCoords=(east, north), @@ -807,7 +807,7 @@ action="add") if updateRecordDlg.mapInfo: # highlight feature & re-draw map - Digit.driver.SetSelected(updateRecordDlg.selectedLines) + self.parent.digit.driver.SetSelected(updateRecordDlg.selectedLines) self.UpdateMap() if updateRecordDlg.ShowModal() == wx.ID_OK: @@ -865,31 +865,31 @@ elif self.mouse["use"] == "pointer" and self.parent.digittoolbar: # digitization - digit = self.parent.digittoolbar + digitToolbar = self.parent.digittoolbar self.mouse['end'] = event.GetPositionTuple()[:] - if digit.action in ["deleteLine", "moveLine", "moveVertex"]: - if digit.action == "moveVertex": - self.moveIds = Digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], + if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex"]: + if digitToolbar.action == "moveVertex": + self.moveIds = self.parent.digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]), onlyType="line") else: # moveLine | deleteLine - self.moveIds = Digit.driver.SelectLinesByBox((self.Pixel2Cell(self.mouse['begin'][0], + self.moveIds = self.parent.digit.driver.SelectLinesByBox((self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]), self.Pixel2Cell(self.mouse['end'][0], self.mouse['end'][1]))) if len(self.moveIds) > 0: self.UpdateMap(render=False) - if digit.action in ["moveLine", "moveVertex"]: + if digitToolbar.action in ["moveLine", "moveVertex"]: self.UpdateMap(render=False, redrawAll=False, removeId=self.moveIds) # get pseudoDC id of objects which should be redrawn - if digit.action == "moveLine": - self.moveIds = Digit.driver.GetSelected(grassId=False) + if digitToolbar.action == "moveLine": + self.moveIds = self.parent.digit.driver.GetSelected(grassId=False) else: - self.moveIds = Digit.driver.GetSelectedVertex(self.Pixel2Cell(self.mouse['begin'][0], + self.moveIds = self.parent.digit.driver.GetSelectedVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) - elif digit.action in ["splitLine", "addVertex", "removeVertex"]: - Digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]), onlyType="line") + elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]: + self.parent.digit.driver.SelectLinesByPoint(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]), onlyType="line") self.UpdateMap(render=False) elif self.dragid != None: # end drag of overlay decoration @@ -1001,20 +1001,20 @@ for coord in self.polycoords: mapcoords.append(self.Pixel2Cell (coord[0], coord[1])) - Digit.AddLine(map=map, + self.parent.digit.AddLine(map=map, type=self.parent.digittoolbar.type, coords=mapcoords) # add new record into atribute table - if Digit.settings["addRecord"]: + if self.parent.digit.settings["addRecord"]: offset = 5 posWindow = self.ClientToScreen((self.polycoords[-1][0] + offset, self.polycoords[-1][1] + offset)) # select attributes based on layer and category addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, - layer=Digit.settings["layer"], - cat=Digit.settings["category"], + layer=self.parent.digit.settings["layer"], + cat=self.parent.digit.settings["category"], pos=posWindow, action="addLine") if addRecordDlg.mapInfo and \ @@ -1029,7 +1029,7 @@ # clean up saved positions self.polycoords = [] elif digit.action == "deleteLine": - Digit.DeleteSelectedLines() + self.parent.digit.DeleteSelectedLines() elif digit.action in ["moveLine", "moveVertex"] and hasattr(self, "moveBegin"): # pixel -> cell move = [self.Distance((0,0), (self.moveBegin[0], 0))[0], @@ -1041,21 +1041,21 @@ move[1] *= -1.0 if digit.action == "moveLine": - Digit.MoveSelectedLines(move) + self.parent.digit.MoveSelectedLines(move) else: # moveVertex - Digit.MoveSelectedVertex(self.Pixel2Cell (self.moveCoords[0], self.moveCoords[1]),move) + self.parent.digit.MoveSelectedVertex(self.Pixel2Cell (self.moveCoords[0], self.moveCoords[1]),move) del self.moveBegin del self.moveCoords del self.moveIds elif digit.action == "splitLine": - Digit.SplitLine(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) + self.parent.digit.SplitLine(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) elif digit.action == "addVertex": - Digit.AddVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) + self.parent.digit.AddVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) elif digit.action == "removeVertex": - Digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) + self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) - Digit.driver.SetSelected([]) + self.parent.digit.driver.SetSelected([]) self.UpdateMap(render=False) event.Skip() @@ -1073,7 +1073,7 @@ self.DrawLines() elif digit.action in ["deleteLine", "moveLine", "splitLine", "addVertex", "removeVertex", "moveVertex"]: # unselected selected features - Digit.driver.SetSelected([]) + self.parent.digit.driver.SetSelected([]) if digit.action in ["moveLine", "moveVertex"] and hasattr(self, "moveBegin"): del self.moveBegin del self.moveCoords From maldacker at grass.itc.it Wed Jul 18 18:38:50 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Wed Jul 18 18:38:51 2007 Subject: [grass-addons] r964 - trunk/grassaddons/v.path.obstacles Message-ID: <200707181638.l6IGcoPt032238@grass.itc.it> Author: maldacker Date: 2007-07-18 18:38:43 +0200 (Wed, 18 Jul 2007) New Revision: 964 Modified: trunk/grassaddons/v.path.obstacles/visibility.c Log: modification in the point inside function Modified: trunk/grassaddons/v.path.obstacles/visibility.c =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-18 14:58:31 UTC (rev 963) +++ trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-18 16:38:43 UTC (rev 964) @@ -60,6 +60,7 @@ */ void handle( struct Point* p, struct Point* q, struct Map_info * out ) { + if ( segment1(q) == NULL && segment2(q) == NULL && before(p,q, p->vis )) { report(p,q,out); @@ -77,7 +78,7 @@ } else p->vis = q->vis; - + report( p, q, out ); } else if ( segment2(p) != NULL && q == other2(p)) @@ -93,7 +94,7 @@ } else p->vis = q->vis; - + report(p, q, out ); } else if ( segment1(q) == p->vis && segment1(q) != NULL) @@ -103,7 +104,7 @@ p->vis = segment2(q); else p->vis = q->vis ; - + /* check that p and q are not on the same boundary and that the edge pq is inside the boundary*/ if ( p->cat == -1 || p->cat != q->cat || !point_inside( p, (p->x+q->x)*0.5, (p->y+q->y)*0.5 ) ) report( p,q, out ); From maldacker at grass.itc.it Wed Jul 18 18:39:08 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Wed Jul 18 18:39:09 2007 Subject: [grass-addons] r965 - trunk/grassaddons/v.path.obstacles Message-ID: <200707181639.l6IGd8sv032668@grass.itc.it> Author: maldacker Date: 2007-07-18 18:39:05 +0200 (Wed, 18 Jul 2007) New Revision: 965 Modified: trunk/grassaddons/v.path.obstacles/geometry.c Log: Modified: trunk/grassaddons/v.path.obstacles/geometry.c =================================================================== --- trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-18 16:38:43 UTC (rev 964) +++ trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-18 16:39:05 UTC (rev 965) @@ -69,19 +69,19 @@ { int c = 0; struct Point * n1 = p; - struct Point * n2 = other1(p); - + struct Point * n2 = other2(p); + do { - if ( ( ( n2->y <=y && y < n1->y ) || - ( n1->y <= y && y< n2->y ) ) && - (x < (n1->x - n2->x) * (y - n2->y) / (n1->y - n2->y) + n2->x)) - c = !c; - - n1 = other1(n1); - n2 = other1(n2); - - }while ( n1 != p ); + if ( ( ( (n1->y <= y) && (y < n2->y) ) || + ( (n2->y <= y) && (y < n1->y) ) ) && + (x < (n2->x - n1->x) * (y - n1->y) / (n2->y - n1->y) + n1->x) ) + c = !c; + + n1 = other2(n1); + n2 = other2(n2); + + }while( n2 != p ); return c; } From ullah at grass.itc.it Thu Jul 19 19:54:54 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 19 19:54:57 2007 Subject: [grass-addons] r966 - in trunk/grassaddons/LandDyn: . r.intensive.cult Message-ID: <200707191754.l6JHssrs032698@grass.itc.it> Author: ullah Date: 2007-07-19 19:54:48 +0200 (Thu, 19 Jul 2007) New Revision: 966 Added: trunk/grassaddons/LandDyn/r.intensive.cult/ trunk/grassaddons/LandDyn/r.intensive.cult/r.intensive.cult Log: Added this model which simulates intensive agriculture over a given number of years and returns landuse maps and c-factor maps Added: trunk/grassaddons/LandDyn/r.intensive.cult/r.intensive.cult =================================================================== --- trunk/grassaddons/LandDyn/r.intensive.cult/r.intensive.cult (rev 0) +++ trunk/grassaddons/LandDyn/r.intensive.cult/r.intensive.cult 2007-07-19 17:54:48 UTC (rev 966) @@ -0,0 +1,162 @@ +#!/bin/sh +# +############################################################################ +# +# MODULE: r.intensive.cult +# AUTHOR(S): Isaac Ullah, Arizona State University +# PURPOSE: Creates a series of iterative agricultural landuse maps from a catchment +# created by r.catchment. This model takes natural vegetational succession into account. +# Optionally outputs c factor as well +# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269 +# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +# +############################################################################# + + +#%Module +#% description: Creates a series of iterative agricultural landuse maps from a catchment created by r.catchment. This model takes natural vegetational succession into account. Optionally outputs c factor as well +#%END + +#%option +#% key: inmap +#% type: string +#% gisprompt: old,cell,raster +#% description: Input catchment map (from r.catchment) +#% required : yes +#%END + +#%option +#% key: lc_rules +#% type: string +#% gisprompt: string +#% description: path to reclass rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_reclass_rules.txt +#% required : yes +#%END +#%option +#% key: lc_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_colors.txt +#% required : yes +#%END +#%option +#% key: cfact_rules +#% type: string +#% gisprompt: string +#% description: path to recode rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_recode_rules.txt +#% required : yes +#%END +#%option +#% key: cfact_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_colors.txt +#% required : yes +#%END + +#%option +#% key: loop +#% type: integer +#% description: number of iterations to run +#% answer: 50 +#% required : yes +#%END +#%option +#% key: prfx +#% type: string +#% gisprompt: string +#% description: prefix for all output maps +#% required : yes +#%END +#%flag +#% key: m +#% description: -m output some stats to a text file in your home directory +#% answer: 1 +#%END +#%flag +#% key: s +#% description: -s Suppress output of landuse map (output C factor map only) +#%END +#%flag +#% key: f +#% description: -f Output maps of random fields at each iteration as well +#%END + + + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." >&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + + +lc_rules=$GIS_OPT_lc_rules + +lc_color=$GIS_OPT_lc_color + +cfact_rules=$GIS_OPT_cfact_rules + +cfact_color=$GIS_OPT_cfact_color + +prfx=$GIS_OPT_prfx + +inmap=$GIS_OPT_inmap +temp1=$prfx"_temp1" +temp2=$prfx"_temp2" + +loop=$GIS_OPT_loop + + + +step=1 + +newmap=$prfx"_landcover"$step +cfact=$prfx"_cfactor_"$step + + r.mapcalc "$temp1=if(isnull($inmap), 50, 5)" + + r.reclass input=$temp1 output=$temp2 rules=$lc_rules + + r.mapcalc "$newmap=$temp2" + +g.remove --quiet rast=$temp2,$temp1 + + r.colors --quiet map=$newmap rules=$lc_color + + r.recode --quiet input=$newmap output=$cfact rules=$cfact_rules + + r.colors --quiet map=$cfact rules=$cfact_color + + echo "Making map: $newmap" + echo "" + +while [ "$step" -lt "$loop" ] +do + step=$(($step+1)) + +newlcmap=$prfx"_landcover"$step +newcfact=$prfx"_cfactor_"$step + +g.copy rast=$newmap,$newlcmap +g.copy rast=$cfact,$newcfact + + echo "Making map: $newmap" + echo "" +done + +echo "" +echo "DONE!" +echo "" +echo "" + Property changes on: trunk/grassaddons/LandDyn/r.intensive.cult/r.intensive.cult ___________________________________________________________________ Name: svn:executable + * From ullah at grass.itc.it Thu Jul 19 19:55:35 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 19 19:55:36 2007 Subject: [grass-addons] r967 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200707191755.l6JHtZbu032726@grass.itc.it> Author: ullah Date: 2007-07-19 19:55:29 +0200 (Thu, 19 Jul 2007) New Revision: 967 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: minor internal changes to improve run-time speed Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-19 17:54:48 UTC (rev 966) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-19 17:55:29 UTC (rev 967) @@ -112,8 +112,7 @@ #%option #% key: R #% type: string -#% description: Rainfall (R factor) constant or map -#% gisprompt: old,cell,raster +#% description: Rainfall (R factor) constant (AVERAGE FOR WHOLE MAP AREA) #% answer: 5 #% required : yes #% guisection: Variables @@ -742,7 +741,8 @@ g.remove --quiet rast=$tmperosion,$tmpdep -txtout=$prefx"erdep_stats.txt" +mapset=`eval g.gisenv get=MAPSET` +txtout=$mapset$prefx"erdep_stats.txt" echo "outputing stats to textfile: $txtout" @@ -1208,6 +1208,8 @@ # now we have met the loop critereon set by us above, so we have broken out. We must now reset the region settings +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 + # create temporary file to list all the smoothdz files for statistics TMP2=`g.tempfile pid=$$` if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then @@ -1246,8 +1248,12 @@ 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 + # create temporary file to list all the soil depth files for statistics TMP3=`g.tempfile pid=$$` if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then @@ -1281,10 +1287,12 @@ r.series --q input=$liststring2 output=$prefx"min_"$outsoil method=minimum fi -\rm -f $TMP2 $TMP2.sort + \rm -f $TMP3 $TMP3.sort +fi + echo "************************" if [ "$GIS_FLAG_k" -eq 1 ]; then From ullah at grass.itc.it Thu Jul 19 19:56:37 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 19 19:56:38 2007 Subject: [grass-addons] r968 - trunk/grassaddons/LandDyn/r.landscape.evol.itr Message-ID: <200707191756.l6JHubNM032763@grass.itc.it> Author: ullah Date: 2007-07-19 19:56:31 +0200 (Thu, 19 Jul 2007) New Revision: 968 Modified: trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr Log: brought this version up to date with latest r.landscape.evol and added feature to write stats file to curretn mapset directory instead of user's home directory Modified: trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr 2007-07-19 17:55:29 UTC (rev 967) +++ trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr 2007-07-19 17:56:31 UTC (rev 968) @@ -65,17 +65,29 @@ #% guisection: Input #%end #%flag +#% key: e +#% description: -e Keep initial soil depths map +#% guisection: Input +#%end +#%flag #% key: z #% description: -z Keep region zoomed to output maps +#% answer: 1 #% guisection: Input #%end +#%flag +#% key: b +#% description: -b Use static bedrock elavations (do not create new soil) +#% answer: 1 +#% guisection: Input +#%end + #%option #% key: R #% type: string -#% description: Rainfall (R factor) map prefixes (leave off years) -#% gisprompt: old,cell,raster -#% answer: rfactor +#% description: Rainfall (R factor) constant (AVERAGE FOR WHOLE MAP AREA) +#% answer: 5 #% required : yes #% guisection: Variables #%end @@ -93,7 +105,7 @@ #% type: string #% gisprompt: old,cell,raster #% description: Landcover index (C factor) map prefixes (leave off years) -#% answer: landcover_cfactor +#% answer: cfactor #% required : yes #% guisection: Variables #%end @@ -166,7 +178,7 @@ #% key: nbhood #% type: string #% description: Band-pass filter neighborhood size -#% answer: 3 +#% answer: 7 #% options: 1,3,5,7,9,11,13,15,17,19,21,23,25 #% required : yes #% guisection: Smoothing_Filter @@ -270,7 +282,7 @@ prefx=$GIS_OPT_prefx elev=$GIS_OPT_elev initbdrk=$GIS_OPT_initbdrk -Rprfx=$GIS_OPT_R +R=$GIS_OPT_R echo "R prefix = $Rprfx" K=$GIS_OPT_K Cprfx=$GIS_OPT_C @@ -322,18 +334,29 @@ echo "n=$n" erdep=$prefx".erosdep1" echo "erdep=$erdep" -initsoil=$prefx".initsoil" + echo "" new_bdrk=$prefx"_new_bdrk1" new_soil=$prefx"_new_soil1" new_dem=$prefx"_new_dem1" initsoil=$prefx"_initsoil" -echo "Initial soil depths calculated will be in $initsoil" + echo "The new dem for this iteration will be called $new_dem" echo "The new bedrock elevation map for this iteration will be called $new_bdrk" 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"_new_bdrk1" + +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` @@ -359,7 +382,6 @@ echo "Start year = $step BP" echo "End year = $maxyrs BP" -R=$Rprfx"_$step" Cinit=$Cprfx"_$step" echo "" @@ -469,7 +491,7 @@ 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 in0 ] +elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 0 ] then echo "" @@ -518,8 +540,8 @@ 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=1+($flowacc * (0.3/($maxflow - $minflow)))" +r.mapcalc "$n=1+($flowacc * (0.15/($maxflow - $minflow)))" report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` @@ -631,7 +653,17 @@ 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)" @@ -652,8 +684,8 @@ r.mapcalc "$new_bdrk=$initbdrk - $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=$initbdrk - ($Ba * ($Bb*($smoothdz - $initbdrk)))" #r.mapcalc "$new_soil=if (($smoothdz - $initbdrk) < 0, 0, ($smoothdz - $initbdrk))" @@ -672,7 +704,10 @@ g.remove --quiet rast=$tmperosion,$tmpdep -txtout=$prefx"_erdep_stats.txt" +mapset=`eval g.gisenv get=MAPSET` +location=`eval g.gisenv get=LOCATION_NAME` +gisdbase=`eval g.gisenv get=GISDBASE` +txtout=$gisdbase"/"$location"/"$mapset"/"$prefx"_erdep_stats.txt" echo "outputing stats to textfile: $txtout" @@ -688,8 +723,17 @@ 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 "Raster map $smoothdz shows filtered net erosion/deposition" echo "" @@ -774,14 +818,27 @@ echo "" R=$Rprfx"_$step" C=$Cprfx"_$step" -new_bdrk=$prefx"_new_bdrk"$step + + new_soil=$prefx"_new_soil"$step new_dem=$prefx"_new_dem"$step + +echo "The new net ersoion/deposition map for this iteration will be called $smoothdz" echo "The new dem for this iteration will be called $new_dem" -echo "The new bedrock elevation map for this iteration will be called $new_bdrk" 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"_new_bdrk"$step +echo "The new bedrock elevation map for this iteration will be called $new_bdrk" + +fi + +echo "" echo "##################################################" echo "##################################################" echo "" @@ -1037,7 +1094,18 @@ r.mapcalc "$new_dem=$smoothdz + $old_dem" 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" + + +new_bdrk=$initbdrk +r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" + +else + +echo "" echo "step 8.5: Calculating new soil depths from landscape curvature" r.mapcalc "$meancurv=($pc+$tc/2)" @@ -1060,8 +1128,8 @@ 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))" @@ -1110,6 +1178,7 @@ # now we have met the loop critereon set by us above, so we have broken out. We must now reset the region settings +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 # create temporary file to list all the smoothdz files for statistics TMP2=`g.tempfile pid=$$` @@ -1149,8 +1218,13 @@ 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 + # create temporary file to list all the soil depth files for statistics TMP3=`g.tempfile pid=$$` if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then @@ -1184,10 +1258,15 @@ r.series --q input=$liststring2 output=$prefx"_min_soil" method=minimum fi -\rm -f $TMP2 $TMP2.sort + \rm -f $TMP3 $TMP3.sort +fi + + + + echo "************************" if [ "$GIS_FLAG_k" -eq 1 ]; then From ullah at grass.itc.it Thu Jul 19 19:58:49 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 19 19:58:50 2007 Subject: [grass-addons] r969 - trunk/grassaddons/LandDyn/r.shift.cult Message-ID: <200707191758.l6JHwnZ6000319@grass.itc.it> Author: ullah Date: 2007-07-19 19:58:43 +0200 (Thu, 19 Jul 2007) New Revision: 969 Modified: trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult Log: Modified script to utilize new "rules file" features of r.reclass, r.colors, and r.recode so that now a rules file has to be specified for landscape and cfactor recoding and recoloring. Also made succsession run to fifty years instaed of 21. added feature to write stats file to curretn mapset directory instead of user's home directory Modified: trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult =================================================================== --- trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult 2007-07-19 17:56:31 UTC (rev 968) +++ trunk/grassaddons/LandDyn/r.shift.cult/r.shift.cult 2007-07-19 17:58:43 UTC (rev 969) @@ -2,7 +2,7 @@ # ############################################################################ # -# MODULE: r.landuse.agr +# MODULE: r.shift.cult # AUTHOR(S): Isaac Ullah, Arizona State University # PURPOSE: Creates a series of iterative agricultural landuse maps from a catchment # created by r.catchment. This model takes natural vegetational succession into account. @@ -55,6 +55,40 @@ #% description: prefix for all output maps #% required : yes #%END + +#%option +#% key: lc_rules +#% type: string +#% gisprompt: string +#% description: path to reclass rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_reclass_rules.txt +#% required : yes +#%END +#%option +#% key: lc_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_colors.txt +#% required : yes +#%END +#%option +#% key: cfact_rules +#% type: string +#% gisprompt: string +#% description: path to recode rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_recode_rules.txt +#% required : yes +#%END +#%option +#% key: cfact_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_colors.txt +#% required : yes +#%END + #%flag #% key: m #% description: -m output some stats to a text file in your home directory @@ -85,105 +119,34 @@ size=$GIS_OPT_size loop=$GIS_OPT_loop prfx=$GIS_OPT_prfx -txtout=$prfx"_stats.txt" -TMP1=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then - echo "ERROR: unable to create temporary file" 1>&2 - exit 1 -fi +lc_rules=$GIS_OPT_lc_rules -TMP2=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi +lc_color=$GIS_OPT_lc_color -echo "0 brown" > $TMP2 -echo "7 orange" >> $TMP2 -echo "14 yellow" >> $TMP2 -echo "21 green" >> $TMP2 -echo "end" >> $TMP2 +cfact_rules=$GIS_OPT_cfact_rules -TMP3=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi +cfact_color=$GIS_OPT_cfact_color -echo "0 = 0 actively cultivated field" > $TMP3 -echo "1 = 1 field with weeds" >> $TMP3 -echo "2 = 2 returning grassland" >> $TMP3 -echo "3 = 3 moderate grassland" >> $TMP3 -echo "4 = 4 grassland" >> $TMP3 -echo "5 = 5 grass and sparse shrubs" >> $TMP3 -echo "6 = 6 grass and shrubs" >> $TMP3 -echo "7 = 7 mainly shrubs" >> $TMP3 -echo "8 = 8 developing maquis" >> $TMP3 -echo "9 = 9 moderate maquis" >> $TMP3 -echo "10 = 10 maquis" >> $TMP3 -echo "11 = 11 moderately dense maquis" >> $TMP3 -echo "12 = 12 dense maquis" >> $TMP3 -echo "13 = 13 maquis and small trees" >> $TMP3 -echo "14 = 14 young woodland and maquis" >> $TMP3 -echo "15 = 15 mostly young open woodland" >> $TMP3 -echo "16 = 16 young open woodland" >> $TMP3 -echo "17 = 17 moderate open woodland" >> $TMP3 -echo "18 = 18 maturing and moderate open woodland" >> $TMP3 -echo "19 = 19 maturing open woodland" >> $TMP3 -echo "20 = 20 mostly matured open woodland" >> $TMP3 -echo "21 = 21 fully matured woodland" >> $TMP3 -echo "end" >> $TMP3 +mapset=`eval g.gisenv get=MAPSET` +location=`eval g.gisenv get=LOCATION_NAME` +gisdbase=`eval g.gisenv get=GISDBASE` +txtout=$gisdbase"/"$location"/"$mapset"/"$prfx"_stats.txt" -TMP4=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi -echo "0:1:0.1:0.1" > $TMP4 -echo "2:3:0.15:0.15" >> $TMP4 -echo "4:6:0.1:0.1" >> $TMP4 -echo "7:9:0.09:0.09" >> $TMP4 -echo "10:13:0.08:0.08" >> $TMP4 -echo "13:16:0.07:0.07" >> $TMP4 -echo "17:20:0.06:0.06" >> $TMP4 -echo "21:21:0.05:0.05" >> $TMP4 -echo "end" >> $TMP4 - -TMP5=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi - -echo "0.15 grey" > $TMP5 -echo "0.1 magenta" >> $TMP5 -echo "0.09 red" >> $TMP5 -echo "0.08 orange" >> $TMP5 -echo "0.08 brown" >> $TMP5 -echo "0.06 yellow" >> $TMP5 -echo "0.05 green" >> $TMP5 -echo "end" >> $TMP5 - - - echo "" echo "*************************" echo "step 1 of 4: Calculating MASK" echo "*************************" echo "" -r.mapcalc "temp_background_1=if(isnull($inmap), 21)" -cat $TMP3 | r.reclass --quiet input=temp_background_1 output=temp_background_2 +r.mapcalc "temp_background_1=if(isnull($inmap), 50)" +r.reclass --quiet input=temp_background_1 output=temp_background_2 rules=$lc_rules r.mapcalc "temp_background=if(isnull(temp_background_2), null(), temp_background_2)" g.remove --quiet rast=temp_background_2,temp_background_1 +r.mask --quiet input=$inmap maskcats=* -r.mask input=$inmap maskcats=* - - - echo "" echo "*************************" echo "step 2 of 4: Changing resolution to field size (will be reset)" @@ -204,8 +167,8 @@ echo "Year 1" -r.mapcalc "tmpinreclass = if ($inmap, 0, null())" -r.mapcalc "temp_class0 = if ($inmap, 21, null())" +r.mapcalc "tmpinreclass = if ($inmap, 5, null())" +r.mapcalc "temp_class0 = if ($inmap, 50, null())" r.random input=tmpinreclass n=$rand"%" raster_output=$prfx"_fields1" @@ -219,17 +182,17 @@ r.patch --quiet input=$prfx"_fields1",temp_class0 output=temp_landuse1_1 - cat $TMP3 | r.reclass --quiet input=temp_landuse1_1 output=temp_landuse1 + r.reclass --quiet input=temp_landuse1_1 output=temp_landuse1 rules=$lc_rules g.rename --quiet rast=MASK,$prfx"mask" r.mapcalc "$prfx"_landuse1" = if (isnull($inmap), temp_background, temp_landuse1)" - cat $TMP2 | r.colors --quiet map=$prfx"_landuse1" color=rules + r.colors --quiet map=$prfx"_landuse1" rules=$lc_color - cat $TMP4 | r.recode --quiet input=$prfx"_landuse1" output=$prfx"_cfactor_1" + r.recode --quiet input=$prfx"_landuse1" output=$prfx"_cfactor_1" rules=$cfact_rules - cat $TMP5 | r.colors --quiet map=$prfx"_cfactor_1" color=rules + r.colors --quiet map=$prfx"_cfactor_1" rules=$cfact_color temparea=`eval r.stats -n --quiet -a fs=- input=$prfx"_fields1" | cut -d'-' -f2` @@ -240,11 +203,11 @@ if [ "$GIS_FLAG_m" -eq 1 ]; then - r.mapcalc "tempmap_arable=if($prfx"_landuse1" >= 10, 1, null())" + r.mapcalc "tempmap_arable=if($prfx"_landuse1" >= 17, 1, null())" arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` - r.mapcalc "tempmap_fallow=if($prfx"_landuse1" > 1 && $prfx"_landuse1" < 10, 1, null())" + r.mapcalc "tempmap_fallow=if($prfx"_landuse1" > 1 && $prfx"_landuse1" < 17, 1, null())" fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` @@ -287,21 +250,21 @@ fi - r.mapcalc "$tcs = if ($tcls < 21, ($tcls + 1), $tcls)" + r.mapcalc "$tcs = if ($tcls < 50, ($tcls + 1), $tcls)" r.patch --quiet input=$outfields,$tcs output=$tmp2landuse - cat $TMP3 | r.reclass --quiet input=$tmp2landuse output=$tmplanduse + r.reclass --quiet input=$tmp2landuse output=$tmplanduse rules=$lc_rules g.rename --quiet rast=MASK,$prfx"mask" r.mapcalc "$outlanduse =if (isnull($inmap), temp_background, $tmplanduse)" - cat $TMP2 | r.colors --quiet map=$outlanduse color=rules + r.colors --quiet map=$outlanduse rules=$lc_color - cat $TMP4 | r.recode --quiet input=$outlanduse output=$outcfactor + r.recode --quiet input=$outlanduse output=$outcfactor rules=$cfact_rules - cat $TMP5 | r.colors --quiet map=$outcfactor color=rules + r.colors --quiet map=$outcfactor rules=$cfact_color temparea=`eval r.stats -n --quiet -a fs=- input=$outfields | cut -d'-' -f2` @@ -311,11 +274,11 @@ if [ "$GIS_FLAG_m" -eq 1 ]; then - r.mapcalc "tempmap_arable=if($outlanduse >= 10, 1, null())" + r.mapcalc "tempmap_arable=if($outlanduse >= 17, 1, null())" arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` - r.mapcalc "tempmap_fallow=if($outlanduse > 1 && $outlanduse < 10, 1, null())" + r.mapcalc "tempmap_fallow=if($outlanduse > 1 && $outlanduse < 17, 1, null())" fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` @@ -391,3 +354,5 @@ echo "" echo "" + + From ullah at grass.itc.it Thu Jul 19 19:59:03 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 19 19:59:04 2007 Subject: [grass-addons] r970 - trunk/grassaddons/LandDyn/r.agropast.intensive Message-ID: <200707191759.l6JHx3Kj000339@grass.itc.it> Author: ullah Date: 2007-07-19 19:58:58 +0200 (Thu, 19 Jul 2007) New Revision: 970 Modified: trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive Log: Modified script to utilize new "rules file" features of r.reclass, r.colors, and r.recode so that now a rules file has to be specified for landscape and cfactor recoding and recoloring. Also made succsession run to fifty years instaed of 21. added feature to write stats file to curretn mapset directory instead of user's home directory Modified: trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive =================================================================== --- trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive 2007-07-19 17:58:43 UTC (rev 969) +++ trunk/grassaddons/LandDyn/r.agropast.intensive/r.agropast.intensive 2007-07-19 17:58:58 UTC (rev 970) @@ -69,6 +69,38 @@ #% description: prefix for all output maps #% required : yes #%END +#%option +#% key: lc_rules +#% type: string +#% gisprompt: string +#% description: path to reclass rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_reclass_rules.txt +#% required : yes +#%END +#%option +#% key: lc_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_colors.txt +#% required : yes +#%END +#%option +#% key: cfact_rules +#% type: string +#% gisprompt: string +#% description: path to recode rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_recode_rules.txt +#% required : yes +#%END +#%option +#% key: cfact_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_colors.txt +#% required : yes +#%END #%flag #% key: l #% description: -l Suppress output of C factor map (output landuse map only) @@ -79,7 +111,7 @@ #%END #%flag #% key: s -#% description: -s Output text file of land-use stats from the simulation (will be named "prefix"_luse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) +#% description: -s Output text file of land-use stats from the simulation (will be written to current Mapset and named "prefix"_luse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) #% answer: 1 #%END @@ -101,104 +133,36 @@ effect=$GIS_OPT_effect prfx=$GIS_OPT_prfx timer=$prfx".timer1" -txtout=$prfx"_luse_stats.txt" -TMP1=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then - echo "ERROR: unable to create temporary file" 1>&2 - exit 1 -fi +mapset=`eval g.gisenv get=MAPSET` +location=`eval g.gisenv get=LOCATION_NAME` +gisdbase=`eval g.gisenv get=GISDBASE` +txtout=$gisdbase"/"$location"/"$mapset"/"$prfx"_luse_stats.txt" -echo "2 = 2 actively cultivated field" > $TMP1 +lc_rules=$GIS_OPT_lc_rules -TMP2=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi +lc_color=$GIS_OPT_lc_color -echo "0 grey" > $TMP2 -echo "5 brown" >> $TMP2 -echo "10 orange" >> $TMP2 -echo "15 yellow" >> $TMP2 -echo "21 green" >> $TMP2 -echo "end" >> $TMP2 +cfact_rules=$GIS_OPT_cfact_rules -TMP3=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then - echo "ERROR: unable to create temporary file for categories" 1>&2 - exit 1 -fi +cfact_color=$GIS_OPT_cfact_color -echo "0 = 0 badly overgrazed" > $TMP3 -echo "1 = 1 overgrazed" >> $TMP3 -echo "2 = 2 sparse grassland" >> $TMP3 -echo "3 = 3 moderate grassland" >> $TMP3 -echo "4 = 4 grassland" >> $TMP3 -echo "5 = 5 grass and sparse shrubs" >> $TMP3 -echo "6 = 6 grass and shrubs" >> $TMP3 -echo "7 = 7 mainly shrubs" >> $TMP3 -echo "8 = 8 developing maquis" >> $TMP3 -echo "9 = 9 moderate maquis" >> $TMP3 -echo "10 = 10 maquis" >> $TMP3 -echo "11 = 11 moderately dense maquis" >> $TMP3 -echo "12 = 12 dense maquis" >> $TMP3 -echo "13 = 13 maquis and small trees" >> $TMP3 -echo "14 = 14 young woodland and maquis" >> $TMP3 -echo "15 = 15 mostly young open woodland" >> $TMP3 -echo "16 = 16 young open woodland" >> $TMP3 -echo "17 = 17 moderate open woodland" >> $TMP3 -echo "18 = 18 maturing and moderate open woodland" >> $TMP3 -echo "19 = 19 maturing open woodland" >> $TMP3 -echo "20 = 20 mostly matured open woodland" >> $TMP3 -echo "21 = 21 fully matured woodland" >> $TMP3 -echo "end" >> $TMP3 -TMP4=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then - echo "ERROR: unable to create temporary file for categories" 1>&2 - exit 1 -fi - -echo "0:1:0.5:0.5" > $TMP4 -echo "2:5:0.10:0.10" >> $TMP4 -echo "6:9:0.15:0.15" >> $TMP4 -echo "10:13:0.18:0.18" >> $TMP4 -echo "13:16:0.08:0.08" >> $TMP4 -echo "17:20:0.06:0.06" >> $TMP4 -echo "21:21:0.05:0.05" >> $TMP4 -echo "end" >> $TMP4 - -TMP5=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi - -echo "0.5 grey" > $TMP5 -echo "0.6 grey" >> $TMP5 -echo "0.19 brown" >> $TMP5 -echo "0.17 brown" >> $TMP5 -echo "0.10 yellow" >> $TMP5 -echo "0.05 green" >> $TMP5 -echo "end" >> $TMP5 - - - echo "" echo "*************************" echo "step 1 of 4: Calculating MASK and background files" echo "*************************" echo "" -r.mapcalc "temp_cat_1=if(isnull($inmapa), null(), 2)" -cat $TMP1 | r.reclass --quiet input=temp_cat_1 output=temp_cat_2 -r.mapcalc "temp_agricultral_luse=if(isnull(temp_cat_2), null(), temp_cat_2)" +r.mapcalc "temp_cat_1=if(isnull($inmapa), null(), 5)" +r.reclass --quiet input=temp_cat_1 output=temp_cat_2 rules=$lc_rules + +r.mapcalc "temp_agricultral_luse=temp_cat_2" g.remove --quiet rast=temp_cat_2,temp_cat_1 -r.mapcalc "temp_background_1=if(isnull($inmap), 21)" -cat $TMP3 | r.reclass --quiet input=temp_background_1 output=temp_background_2 -r.mapcalc "temp_background=if(isnull(temp_background_2), null(), temp_background_2)" +r.mapcalc "temp_background_1=if(isnull($inmap), 50)" +r.reclass --quiet input=temp_background_1 output=temp_background_2 rules=$lc_rules +r.mapcalc "temp_background=temp_background_2" g.remove --quiet rast=temp_background_2,temp_background_1 g.remove --quiet rast=MASK @@ -240,20 +204,20 @@ fi -r.mapcalc "$timer = if (isnull($patches), 21, 21-$effect)" +r.mapcalc "$timer = if (isnull($patches), 50, 50-$effect)" - cat $TMP3 | r.reclass --q input=$timer output=temp_landuse1 + r.reclass --q input=$timer output=temp_landuse1 rules=$lc_rules g.rename --quiet rast=MASK,$prfx"mask" r.mapcalc "$prfx"_landuse1" = if(isnull($inmapa) && isnull($inmap), temp_background, if(isnull($inmapa) && ($inmap >= 0), temp_landuse1, temp_agricultral_luse))" - cat $TMP2 | r.colors --q map=$prfx"_landuse1" color=rules + r.colors --q map=$prfx"_landuse1" rules=$lc_color - cat $TMP4 | r.recode --q input=$prfx"_landuse1" output=$prfx"_cfactor_1" + r.recode --q input=$prfx"_landuse1" output=$prfx"_cfactor_1" rules=$cfact_rules - cat $TMP5 | r.colors --q map=$prfx"_cfactor_1" color=rules + r.colors --q map=$prfx"_cfactor_1" rules=$cfact_color temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2` @@ -306,21 +270,21 @@ fi -r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 20, $oldtimer + 1, (if(isnull($outpatches), 21, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" +r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 49, $oldtimer + 1, (if(isnull($outpatches), 50, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" - cat $TMP3 | r.reclass --q input=$newtimer output=$tmplanduse + r.reclass --q input=$newtimer output=$tmplanduse rules=$lc_rules g.rename --quiet rast=MASK,$prfx"mask" - r.mapcalc "$outlanduse =if(isnull($inmapa) && isnull($inmap), temp_background, if(isnull($inmapa) && ($inmap >= 0), $tmplanduse, temp_agricultral_luse))" + r.mapcalc "$outlanduse =if(isnull($inmapa) && isnull($inmap), temp_background, if(isnull($inmapa) &! isnull($inmap), $tmplanduse, temp_agricultral_luse))" - cat $TMP2 | r.colors --q map=$outlanduse color=rules + r.colors --q map=$outlanduse rules=$lc_color - cat $TMP4 | r.recode --q input=$outlanduse output=$outcfactor + r.recode --q input=$outlanduse output=$outcfactor rules=$cfact_rules - cat $TMP5 | r.colors --q map=$outcfactor color=rules + r.colors --q map=$outcfactor rules=$cfact_color temparea=`eval r.stats -n -a fs=- input=$outpatches | cut -d'-' -f2` echo "" From ullah at grass.itc.it Thu Jul 19 19:59:17 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 19 19:59:20 2007 Subject: [grass-addons] r971 - trunk/grassaddons/LandDyn/r.agropast.extensive Message-ID: <200707191759.l6JHxHJe000368@grass.itc.it> Author: ullah Date: 2007-07-19 19:59:12 +0200 (Thu, 19 Jul 2007) New Revision: 971 Modified: trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive Log: Modified script to utilize new "rules file" features of r.reclass, r.colors, and r.recode so that now a rules file has to be specified for landscape and cfactor recoding and recoloring. Also made succsession run to fifty years instaed of 21. added feature to write stats file to curretn mapset directory instead of user's home directory Modified: trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive =================================================================== --- trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive 2007-07-19 17:58:58 UTC (rev 970) +++ trunk/grassaddons/LandDyn/r.agropast.extensive/r.agropast.extensive 2007-07-19 17:59:12 UTC (rev 971) @@ -94,7 +94,7 @@ #%END #%flag #% key: s -#% description: -s Output text file of pastoral land-use stats from the simulation (will be named "prefix"_pastoraluse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) +#% description: -s Output text file of pastoral land-use stats from the simulation (will be written to current mapset named "prefix"_pastoraluse_stats.txt, and will be overwritten if you run the simulation again with the same prefix) #% answer: 1 #%END #%flag @@ -108,7 +108,40 @@ #% answer: 1 #%END +#%option +#% key: lc_rules +#% type: string +#% gisprompt: string +#% description: path to reclass rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_reclass_rules.txt +#% required : yes +#%END +#%option +#% key: lc_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for landcover map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/luse_colors.txt +#% required : yes +#%END +#%option +#% key: cfact_rules +#% type: string +#% gisprompt: string +#% description: path to recode rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_recode_rules.txt +#% required : yes +#%END +#%option +#% key: cfact_color +#% type: string +#% gisprompt: string +#% description: path to color rules file for c-factor map +#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_colors.txt +#% required : yes +#%END + if [ -z "$GISBASE" ] ; then echo "You must be in GRASS GIS to run this program." >&2 exit 1 @@ -125,137 +158,27 @@ randg=$GIS_OPT_randg sizeg=$GIS_OPT_sizeg - loop=$GIS_OPT_loop effect=$GIS_OPT_effect prfx=$GIS_OPT_prfx timer=$prfx".timer1" -txtout=$prfx"_ag_use_stats.txt" -txtout2=$prfx"_pastoral_use_stats.txt" -txtout3=$prfx"_ag_plus_past_use_stats.txt" +mapset=`eval g.gisenv get=MAPSET` +location=`eval g.gisenv get=LOCATION_NAME` +gisdbase=`eval g.gisenv get=GISDBASE` +txtout=$gisdbase"/"$location"/"$mapset"/"$prfx"_ag_use_stats.txt" +txtout2=$gisdbase"/"$location"/"$mapset"/"$prfx"_pastoral_use_stats.txt" +txtout3=$gisdbase"/"$location"/"$mapset"/"$prfx"_ag_plus_past_use_stats.txt" +lc_rules=$GIS_OPT_lc_rules -#first make some tempfiles to hold various reclass and color rules -TMP1=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then - echo "ERROR: unable to create temporary file" 1>&2 - exit 1 -fi +lc_color=$GIS_OPT_lc_color +cfact_rules=$GIS_OPT_cfact_rules -echo "0 = 0 bare land" > $TMP1 -echo "1 = 1 sparsely covered land" >> $TMP1 -echo "2 = 2 actively cultivated field" >> $TMP1 -echo "3 = 3 moderate grassland" >> $TMP1 -echo "4 = 4 grassland" >> $TMP1 -echo "5 = 5 grass and sparse shrubs" >> $TMP1 -echo "6 = 6 grass and shrubs" >> $TMP1 -echo "7 = 7 mainly shrubs" >> $TMP1 -echo "8 = 8 developing maquis" >> $TMP1 -echo "9 = 9 moderate maquis" >> $TMP1 -echo "10 = 10 maquis" >> $TMP1 -echo "11 = 11 moderately dense maquis" >> $TMP1 -echo "12 = 12 dense maquis" >> $TMP1 -echo "13 = 13 maquis and small trees" >> $TMP1 -echo "14 = 14 young woodland and maquis" >> $TMP1 -echo "15 = 15 mostly young open woodland" >> $TMP1 -echo "16 = 16 young open woodland" >> $TMP1 -echo "17 = 17 moderate open woodland" >> $TMP1 -echo "18 = 18 maturing and moderate open woodland" >> $TMP1 -echo "19 = 19 maturing open woodland" >> $TMP1 -echo "20 = 20 mostly matured open woodland" >> $TMP1 -echo "21 = 21 fully matured woodland" >> $TMP1 -echo "end" >> $TMP1 +cfact_color=$GIS_OPT_cfact_color -TMP6=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP6" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi - -echo "0 brown" > $TMP6 -echo "1 brown" >> $TMP6 -echo "2 red" >> $TMP6 -echo "3 orange" >> $TMP6 -echo "7 orange" >> $TMP6 -echo "14 yellow" >> $TMP6 -echo "21 green" >> $TMP6 -echo "end" >> $TMP6 - -TMP2=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi - -echo "0 brown" > $TMP2 -echo "7 orange" >> $TMP2 -echo "14 yellow" >> $TMP2 -echo "21 green" >> $TMP2 -echo "end" >> $TMP2 - -TMP3=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then - echo "ERROR: unable to create temporary file for categories" 1>&2 - exit 1 -fi - -echo "0 = 0 badly overgrazed" > $TMP3 -echo "1 = 1 overgrazed" >> $TMP3 -echo "2 = 2 sparse grassland" >> $TMP3 -echo "3 = 3 moderate grassland" >> $TMP3 -echo "4 = 4 grassland" >> $TMP3 -echo "5 = 5 grass and sparse shrubs" >> $TMP3 -echo "6 = 6 grass and shrubs" >> $TMP3 -echo "7 = 7 mainly shrubs" >> $TMP3 -echo "8 = 8 developing maquis" >> $TMP3 -echo "9 = 9 moderate maquis" >> $TMP3 -echo "10 = 10 maquis" >> $TMP3 -echo "11 = 11 moderately dense maquis" >> $TMP3 -echo "12 = 12 dense maquis" >> $TMP3 -echo "13 = 13 maquis and small trees" >> $TMP3 -echo "14 = 14 young woodland and maquis" >> $TMP3 -echo "15 = 15 mostly young open woodland" >> $TMP3 -echo "16 = 16 young open woodland" >> $TMP3 -echo "17 = 17 moderate open woodland" >> $TMP3 -echo "18 = 18 maturing and moderate open woodland" >> $TMP3 -echo "19 = 19 maturing open woodland" >> $TMP3 -echo "20 = 20 mostly matured open woodland" >> $TMP3 -echo "21 = 21 fully matured woodland" >> $TMP3 -echo "50 = 3 actively cultivated wheat field" >> $TMP3 -echo "end" >> $TMP3 - -TMP4=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then - echo "ERROR: unable to create temporary file for categories" 1>&2 - exit 1 -fi - -echo "0:1:0.5:0.5" > $TMP4 -echo "2:21:0.10:0.05" >> $TMP4 -echo "end" >> $TMP4 - -TMP5=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP5" ] ; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 -fi - -echo "0.4 red" > $TMP5 -echo "0.6 black" >> $TMP5 -echo "0.19 grey" >> $TMP5 -echo "0.17 brown" >> $TMP5 -echo "0.1 orange" >> $TMP5 -echo "0.07 yellow" >> $TMP5 -echo "0.05 green" >> $TMP5 -echo "end" >> $TMP5 - - - - - g.region --quiet save=temp_region @@ -275,22 +198,30 @@ echo "Part 1: agricultural simulation" echo "" -r.mapcalc "temp_background_1=if(isnull($inmapg), 21)" - cat $TMP3 | r.reclass --quiet input=temp_background_1 output=temp_background_2 -r.mapcalc "temp_background=if(isnull(temp_background_2), null(), temp_background_2)" -g.remove --quiet rast=temp_background_2,temp_background_1 +#setting initial conditions of map area + r.mapcalc "temp_background_1=if(isnull($inmapg), 50, null())" - cat $TMP2 | r.colors --quiet map=temp_background color=rules +#adding text descriptions to raw landscape categories and setting colors + r.reclass --quiet rules=$lc_rules input=temp_background_1 output=temp_background_2 - cat $TMP4 | r.recode --quiet input=temp_background output=temp_background_cfactor - cat $TMP5 | r.colors --quiet map=temp_background_cfactor color=rules + r.mapcalc "temp_background=if(isnull(temp_background_2), null(), temp_background_2)" + g.remove --quiet rast=temp_background_2,temp_background_1 + r.colors --quiet map=temp_background rules=$lc_color + +#creating c-factor map and setting colors + r.recode input=temp_background output=temp_background_cfactor rules=$cfact_rules --quiet + + r.colors map=temp_background_cfactor rules=$cfact_color + + +#updating raw landscape category numbers r.mask --quiet input=$inmapa maskcats=* g.region --quiet res=$sizea -r.mapcalc "tmpinreclassa = if ($inmapa, 2, null())" +r.mapcalc "tmpinreclassa = if ($inmapa, 5, null())" fields1=$prfx"_fields1" @@ -300,7 +231,7 @@ echo "fields map = $fields1" - fi +fi temparea=`eval r.stats -n --quiet -a fs=- input=$fields1 | cut -d'-' -f2` @@ -317,7 +248,7 @@ -r.mapcalc "MASK=if( if(isnull($prfx"_fields1") && ($inmapg <= 0 || $inmapg >= 0), 1, null()))" +r.mapcalc "MASK=if( if(isnull($prfx"_fields1") &! isnull($inmapg), 1, null()))" timer=$prfx".timer1" @@ -336,18 +267,19 @@ fi -r.mapcalc "$timer = if (isnull($patches), 21, 21-$effect)" +r.mapcalc "$timer = if (isnull($patches), 50, 50-$effect)" +#adding text descriptions to raw landscape categories and setting colors + r.reclass --quiet rules=$lc_rules input=$timer output=temp_pastuse1 - cat $TMP3 | r.reclass --quiet input=$timer output=temp_pastuse1 - r.mapcalc "$prfx"_past_luse1" = temp_pastuse1" - cat $TMP2 | r.colors --quiet map=$prfx"_past_luse1" color=rules + r.colors --quiet map=$prfx"_past_luse1" rules=$lc_color - cat $TMP4 | r.recode --quiet input=$prfx"_past_luse1" output=$prfx"_past_cfactor_1" +#creating c-factor map and setting colors + r.recode --quiet input=$prfx"_past_luse1" output=$prfx"_past_cfactor_1" rules=$cfact_rules - cat $TMP5 | r.colors --quiet map=$prfx"_past_cfactor_1" color=rules + r.colors --quiet map=$prfx"_past_cfactor_1" rules=$cfact_color temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2` @@ -382,15 +314,15 @@ - cat $TMP1 | r.reclass --quiet input=temp_landuse1_1 output=temp_landuse1 + r.reclass --quiet input=temp_landuse1_1 output=temp_landuse1 rules=$lc_rules r.mapcalc "$prfx"_ag_luse1" = temp_landuse1" - cat $TMP6 | r.colors --quiet map=$prfx"_ag_luse1" color=rules + r.colors --quiet map=$prfx"_ag_luse1" rules=$lc_color - cat $TMP4 | r.recode --quiet input=$prfx"_ag_luse1" output=$prfx"_ag_cfactor_1" + r.recode --quiet input=$prfx"_ag_luse1" output=$prfx"_ag_cfactor_1" rules=$cfact_rules - cat $TMP5 | r.colors --quiet map=$prfx"_ag_cfactor_1" color=rules + r.colors --quiet map=$prfx"_ag_cfactor_1" rules=$cfact_color @@ -398,11 +330,11 @@ if [ "$GIS_FLAG_m" -eq 1 ]; then - r.mapcalc "tempmap_arable=if($prfx"_ag_luse1" >= 12, 1, null())" + r.mapcalc "tempmap_arable=if($prfx"_ag_luse1" >= 17, 1, null())" arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` - r.mapcalc "tempmap_fallow=if($prfx"_ag_luse1" > 0 && $prfx"_ag_luse1" < 12, 1, null())" + r.mapcalc "tempmap_fallow=if($prfx"_ag_luse1" > 0 && $prfx"_ag_luse1" < 17, 1, null())" fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` @@ -490,7 +422,7 @@ echo "Part 2: grazing simulation" echo "" -r.mapcalc "MASK=if( if(isnull($outfields) && ($inmapg <= 0 || $inmapg >= 0), 1, null()))" +r.mapcalc "MASK=if( if(isnull($outfields) &! isnull($inmapg), 1, null()))" g.region --quiet res=$sizeg @@ -510,18 +442,18 @@ fi -r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 20, $oldtimer + 1, (if(isnull($outpatches), 21, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" +r.mapcalc "$newtimer= if (isnull($outpatches) && $oldtimer <= 49, $oldtimer + 1, (if(isnull($outpatches), 50, (if ($oldtimer < $effect, 0, $oldtimer - $effect)))))" - cat $TMP3 | r.reclass --quiet input=$newtimer output=$tmplanduse + r.reclass --quiet input=$newtimer output=$tmplanduse rules=$lc_rules r.mapcalc "$outlanduse = $tmplanduse" - cat $TMP2 | r.colors --quiet map=$outlanduse color=rules + r.colors --quiet map=$outlanduse rules=$lc_color - cat $TMP4 | r.recode --quiet input=$outlanduse output=$outcfactor + r.recode --quiet input=$outlanduse output=$outcfactor rules=$cfact_rules - cat $TMP5 | r.colors --quiet map=$outcfactor color=rules + r.colors --quiet map=$outcfactor rules=$cfact_color temparea=`eval r.stats -n -a fs=- input=$patches | cut -d'-' -f2` @@ -565,15 +497,15 @@ - cat $TMP1 | r.reclass --quiet input=$tmp2landuse output=$tmplanduse + r.reclass --quiet input=$tmp2landuse output=$tmplanduse rules=$lc_rules r.mapcalc "$outaglanduse = $tmplanduse" - cat $TMP6 | r.colors --quiet map=$outaglanduse color=rules + r.colors --quiet map=$outaglanduse rules=$lc_color - cat $TMP4 | r.recode --quiet input=$outaglanduse output=$outagcfactor + r.recode --quiet input=$outaglanduse output=$outagcfactor rules=$cfact_rules - cat $TMP5 | r.colors --quiet map=$outagcfactor color=rules + r.colors --quiet map=$outagcfactor rules=$cfact_color temparea=`eval r.stats -n --quiet -a fs=- input=$outfields | cut -d'-' -f2` @@ -584,11 +516,11 @@ if [ "$GIS_FLAG_m" -eq 1 ]; then - r.mapcalc "tempmap_arable=if($outaglanduse >= 12, 1, null())" + r.mapcalc "tempmap_arable=if($outaglanduse >= 17, 1, null())" arablearea=`eval r.stats -n --quiet -a fs=- input=tempmap_arable | cut -d'-' -f2` - r.mapcalc "tempmap_fallow=if($outaglanduse > 0 && $outaglanduse < 12, 1, null())" + r.mapcalc "tempmap_fallow=if($outaglanduse > 0 && $outaglanduse < 17, 1, null())" fallowarea=`eval r.stats -n --quiet -a fs=- input=tempmap_fallow | cut -d'-' -f2` From chemin at grass.itc.it Thu Jul 19 20:04:23 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Thu Jul 19 20:04:24 2007 Subject: [grass-addons] r972 - trunk/grassaddons/gipe/i.sunhours Message-ID: <200707191804.l6JI4NJI000403@grass.itc.it> Author: chemin Date: 2007-07-19 20:04:20 +0200 (Thu, 19 Jul 2007) New Revision: 972 Modified: trunk/grassaddons/gipe/i.sunhours/main.c Log: Bugfix Modified: trunk/grassaddons/gipe/i.sunhours/main.c =================================================================== --- trunk/grassaddons/gipe/i.sunhours/main.c 2007-07-19 17:59:12 UTC (rev 971) +++ trunk/grassaddons/gipe/i.sunhours/main.c 2007-07-19 18:04:20 UTC (rev 972) @@ -175,7 +175,7 @@ } d_da = 2 * PI * ( d_doy - 1 ) / 365.0; d_delta = 0.006918-0.399912*cos(d_da)+0.070257*sin(d_da)-0.006758*cos(2*d_da)+0.000907*sin(2*d_da)-0.002697*cos(3*d_da)+0.00148*sin(3*d_da); - d_Ws = acos(-tan(d_lat)*tan(d_delta)); + d_Ws = acos(-tan(d_lat*PI/180)*tan(d_delta)); d_N = ( 360.0 / ( 15.0 * PI ) ) * d_Ws; ((DCELL *) outrast1)[col] = d_N; } From ullah at grass.itc.it Thu Jul 19 20:38:04 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Jul 19 20:38:05 2007 Subject: [grass-addons] r973 - trunk/grassaddons/LandDyn/r.landscape.evol.itr Message-ID: <200707191838.l6JIc49Y000497@grass.itc.it> Author: ullah Date: 2007-07-19 20:37:59 +0200 (Thu, 19 Jul 2007) New Revision: 973 Modified: trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr Log: minor bug fix Modified: trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr 2007-07-19 18:04:20 UTC (rev 972) +++ trunk/grassaddons/LandDyn/r.landscape.evol.itr/r.landscape.evol.itr 2007-07-19 18:37:59 UTC (rev 973) @@ -816,7 +816,6 @@ old_soil=$prefx"_new_soil"$laststep echo "old_soil=$old_soil" echo "" -R=$Rprfx"_$step" C=$Cprfx"_$step" From ullah at grass.itc.it Fri Jul 20 21:41:42 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Fri Jul 20 21:41:44 2007 Subject: [grass-addons] r974 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200707201941.l6KJfgW5016294@grass.itc.it> Author: ullah Date: 2007-07-20 21:41:37 +0200 (Fri, 20 Jul 2007) New Revision: 974 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: Modified script with a fix so that the edges are not affected by the attrition caused by r.slope.aspect when called multiple times by another program to run single iterations (ie. when iterated by an outside process). This fix was already present in the iterative loop of the script itself, but until now was not incorporated in year 1 which is run before the loop... Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-19 18:37:59 UTC (rev 973) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-07-20 19:41:37 UTC (rev 974) @@ -686,10 +686,25 @@ 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" -r.colors --q map=$new_dem rast=$elev +fi + +r.colors --quiet map=$new_dem rast=$elev + if [ $GIS_FLAG_b -eq 1 ]; then echo "" From bundala at grass.itc.it Mon Jul 23 00:39:28 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Mon Jul 23 00:39:31 2007 Subject: [grass-addons] r975 - trunk/grassaddons/v.generalize Message-ID: <200707222239.l6MMdSpM028749@grass.itc.it> Author: bundala Date: 2007-07-23 00:39:21 +0200 (Mon, 23 Jul 2007) New Revision: 975 Added: trunk/grassaddons/v.generalize/displacement.c trunk/grassaddons/v.generalize/network.c Modified: trunk/grassaddons/v.generalize/description.html trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/matrix.c trunk/grassaddons/v.generalize/matrix.h trunk/grassaddons/v.generalize/smoothing.c Log: added: network generalization (based on graph approach), snakes smoothing is more efficient, some issues in description.html and first version of displacement algorithm Modified: trunk/grassaddons/v.generalize/description.html =================================================================== --- trunk/grassaddons/v.generalize/description.html 2007-07-20 19:41:37 UTC (rev 974) +++ trunk/grassaddons/v.generalize/description.html 2007-07-22 22:39:21 UTC (rev 975) @@ -79,7 +79,7 @@ is equivalent to

    -v.generalize input=in output=out method=douglas_reduction threshold=eps reduction=0
    +v.generalize input=in output=out method=douglas_reduction threshold=eps reduction=100
     
    However, in this case, the first method is faster. Also observe that douglas_reduction never outputs more vertices than douglas. And that, @@ -95,8 +95,9 @@

    The following smoothing algorithms are implemented in v.generalize

      -
    • Boyle's Forward-Looking Algorithm - Works by taking the average of - look_ahead consecutive points
    • . Input parameters: input, look_ahead. +
    • Boyle's Forward-Looking Algorithm - The position of each point depends on the + position of the previous points and the point look_ahead ahead. + look_ahead consecutive points. Input parameters: input, look_ahead.
    • McMaster's Sliding Averaging Algorithm - Input Parameters: input, slide, look_ahead. The new position of each point is the average of the look_ahead points around. Paremeter slide is used for linear interpolation between old and new position (see below).
    • @@ -148,8 +149,8 @@

      SEE ALSO

      - -v.clean
      +v.clean
      +v.dissolve


      Added: trunk/grassaddons/v.generalize/displacement.c =================================================================== --- trunk/grassaddons/v.generalize/displacement.c (rev 0) +++ trunk/grassaddons/v.generalize/displacement.c 2007-07-22 22:39:21 UTC (rev 975) @@ -0,0 +1,239 @@ + +/**************************************************************** + * + * MODULE: v.generalize + * + * AUTHOR(S): Daniel Bundala + * + * PURPOSE: Methods for displacement + * + * COPYRIGHT: (C) 2002-2005 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 +#include +#include +#include +#include +#include "point.h" +#include "matrix.h" + +/* snakes method modified for displacement. + * Function returns somthing */ +int snakes_displacement(struct Map_info *In, struct Map_info *Out, + double threshold, double alfa, double beta, double gama, + double delta, int iterations) +{ + + int n_points; + int n_lines; + + /*this is not THE final version, we need to threat the same + * points on the different lines (e.g croassroads) + * + * Also, we must be able to specify the lines we want to + * displace. + * + * Moreover, there is no reason to cnsider the lines/points + * which are OK + * + * I just want to see the results, before i spend + * two afternoons working...:) + */ + + int i, j, index, pindex, iter; + int with_z = 0; + struct line_pnts *Points, *Write; + struct line_cats *Cats; + MATRIX k, dx, dy, fx, fy, kinv, dx_old, dy_old; + POINT *parray; + int *point_index; + int *first, *line_index; + double threshold2; + int from, to; + + Points = Vect_new_line_struct(); + Write = Vect_new_line_struct(); + Cats = Vect_new_cats_struct(); + n_lines = Vect_get_num_lines(In); + n_points = 0; + + for (i = 1; i <= n_lines; i++) { + Vect_read_line(In, Points, NULL, i); + n_points += Points->n_points; + }; + + matrix_init(n_points, n_points, &k); + matrix_init(n_points, 1, &dx); + matrix_init(n_points, 1, &dy); + matrix_init(n_points, 1, &fx); + matrix_init(n_points, 1, &fy); + matrix_init(n_points, 1, &dx_old); + matrix_init(n_points, 1, &dy_old); + parray = (POINT *) G_calloc(n_points, sizeof(POINT)); + point_index = (int *)G_calloc(n_points, sizeof(int)); + first = (int *)G_calloc(n_points, sizeof(int)); + line_index = (int *)G_calloc(n_points, sizeof(int)); + + index = 0; + pindex = 0; + from = to = 0; + for (i = 1; i <= n_lines; i++) { + Vect_read_line(In, Points, NULL, i); + from = to; + to = from + Points->n_points; + for (j = 0; j < Points->n_points; j++) { + int q, w; + double a, b, c, h; + point_assign(Points, j, with_z, &parray[pindex++]); + point_index[pindex - 1] = index; + first[pindex - 1] = (j == 0); + line_index[pindex - 1] = i; + + a = 2.0 * alfa + 6.0 * beta; + b = -alfa - 4.0 * beta; + c = beta; + + if (!first[pindex - 1]) { + h = point_dist(parray[pindex - 1], parray[pindex - 2]); + if (h == 0) + h = 1.0; + } + else + h = 1.0; + a /= h; + b /= h; + c /= h; + double ar[5] = { c, b, a, b, c }; + for (q = 0; q < 5; q++) + if (index + q - 2 >= from && index + q - 2 < to) + k.a[index][index + q - 2] = ar[q]; + + + index++; + }; + }; + + threshold2 = threshold * threshold; + + matrix_add_identity(gama, &k); + + matrix_mult_scalar(0.0, &dx); + matrix_mult_scalar(0.0, &dy); + + /*calculate the inverse */ + if (!matrix_inverse(k, &kinv, 4)) + G_fatal_error(_("Could not calculate the inverse matrix")); + + for (iter = 0; iter < iterations; iter++) { + + int conflicts = 0; + + matrix_mult_scalar(0.0, &fx); + matrix_mult_scalar(0.0, &fy); + + matrix_mult_scalar(0.0, &dx_old); + matrix_mult_scalar(0.0, &dy_old); + + matrix_add(dx_old, dx, &dx_old); + matrix_add(dy_old, dy, &dy_old); + + /* calculate force vectors */ + for (i = 0; i < pindex; i++) { + + double cx, cy; + cx = dx.a[point_index[i]][0]; + cy = dy.a[point_index[i]][0]; + double f = sqrt(cx * cx + cy * cy); + f /= threshold2; + fx.a[point_index[i]][0] -= cx * f; + fy.a[point_index[i]][0] -= cy * f; + + for (j = 1; j < pindex; j++) { + if (line_index[i] == line_index[j] || first[j]) + continue; + /* if ith point is close to some segment then + * apply force to ith point. If the distance + * is zero, do not move the points */ + double d, pdist; + POINT in; + int status; + d = dig_distance2_point_to_line(parray[i].x, parray[i].y, + parray[i].z, parray[j].x, + parray[j].y, parray[j].z, + parray[j - 1].x, + parray[j - 1].y, + parray[j - 1].z, with_z, &in.x, + &in.y, &in.z, &pdist, &status); + + POINT dir; + if (d == 0.0 || d > threshold2) + continue; + d = sqrt(d); + point_subtract(parray[i], in, &dir); + point_scalar(dir, 1.0 / d, &dir); + point_scalar(dir, 1.0 - d / threshold, &dir); + fx.a[point_index[i]][0] += dir.x; + fy.a[point_index[i]][0] += dir.y; + conflicts++; + }; + }; + + matrix_mult_scalar(delta, &fx); + matrix_mult_scalar(delta, &fy); + matrix_mult_scalar(gama, &dx); + matrix_mult_scalar(gama, &dy); + + matrix_add(dx, fx, &fx); + matrix_add(dy, fy, &fy); + + matrix_mult(kinv, fx, &dx); + matrix_mult(kinv, fy, &dy); + + for (i = 0; i < pindex; i++) { + parray[i].x += + dx.a[point_index[i]][0] - dx_old.a[point_index[i]][0]; + parray[i].y += + dy.a[point_index[i]][0] - dy_old.a[point_index[i]][0]; + }; + + + }; + index = 0; + for (i = 1; i <= n_lines; i++) { + int type = Vect_read_line(In, Points, Cats, i); + /*Vect_read_line(In, Write, NULL, i); + * Write->n_points = 2; */ + for (j = 0; j < Points->n_points; j++) { + /* Write->x[0] = Points->x[j]; + * Write->y[0] = Points->y[j]; */ + Points->x[j] = parray[index].x; + Points->y[j] = parray[index].y; + /* Write->x[1] = Points->x[j]; + * Write->y[1] = Points->y[j]; + * Vect_write_line(Out, GV_LINE, Write, Cats); */ + index++; + }; + Vect_write_line(Out, GV_LINE, Points, Cats); + }; + + G_free(parray); + G_free(point_index); + G_free(first); + G_free(line_index); + matrix_free(k); + matrix_free(kinv); + matrix_free(dx); + matrix_free(dy); + matrix_free(fx); + matrix_free(fy); + matrix_free(dx_old); + matrix_free(dy_old); + return 0; +}; Property changes on: trunk/grassaddons/v.generalize/displacement.c ___________________________________________________________________ Name: svn:executable + * Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-20 19:41:37 UTC (rev 974) +++ trunk/grassaddons/v.generalize/main.c 2007-07-22 22:39:21 UTC (rev 975) @@ -34,6 +34,8 @@ #define SNAKES 8 #define DOUGLAS_REDUCTION 9 #define SLIDING_AVERAGING 10 +#define NETWORK 100 +#define DISPLACEMENT 101 int main(int argc, char *argv[]) { @@ -46,11 +48,13 @@ struct Option *map_in, *map_out, *thresh_opt, *method_opt, *look_ahead_opt; struct Option *iterations_opt, *cat_opt, *alfa_opt, *beta_opt, *type_opt; struct Option *field_opt, *where_opt, *reduction_opt, *slide_opt; - struct Option *angle_thresh_opt; + struct Option *angle_thresh_opt, *degree_thresh_opt, *closeness_thresh_opt; + struct Option *betweeness_thresh_opt; struct Flag *ca_flag; int with_z; int total_input, total_output; /* Number of points in the input/output map respectively */ double thresh, alfa, beta, reduction, slide, angle_thresh; + double degree_thresh, closeness_thresh, betweeness_thresh; int method; int look_ahead, iterations; int chcat; @@ -84,7 +88,7 @@ method_opt->required = YES; method_opt->multiple = NO; method_opt->options = - "douglas,douglas_reduction,lang,reduction,reumann,boyle,sliding_averaging,distance_weighting,chaiken,hermite,snakes"; + "douglas,douglas_reduction,lang,reduction,reumann,boyle,sliding_averaging,distance_weighting,chaiken,hermite,snakes,network,displacement"; method_opt->answer = "douglas"; method_opt->descriptions = _("douglas;Douglas-Peucker Algorithm;" "douglas_reduction;Douglas-Peucker Algorithm with reduction parameter;" @@ -96,7 +100,10 @@ "distance_weighting;McMaster's Distance-Weighting Algorithm;" "chaiken;Chaiken's Algorithm;" "hermite;Interpolation by Cubic Hermite Splines;" - "snakes;Snakes method for line smoothing;"); + "snakes;Snakes method for line smoothing;" + "network;Network generalization;" + "displacement;Displacement of lines close to each other;"); + method_opt->description = _("Line simplification/smoothing algorithm"); thresh_opt = G_define_option(); @@ -142,6 +149,31 @@ angle_thresh_opt->description = _("Minimum angle between two consecutive segments in Hermite method"); + degree_thresh_opt = G_define_option(); + degree_thresh_opt->key = "degree_thresh"; + degree_thresh_opt->type = TYPE_INTEGER; + degree_thresh_opt->required = YES; + degree_thresh_opt->answer = "0"; + degree_thresh_opt->description = + _("Degree threshold in network generalization"); + + closeness_thresh_opt = G_define_option(); + closeness_thresh_opt->key = "closeness_thresh"; + closeness_thresh_opt->type = TYPE_DOUBLE; + closeness_thresh_opt->required = YES; + closeness_thresh_opt->answer = "0"; + closeness_thresh_opt->options = "0-1"; + closeness_thresh_opt->description = + _("Closeness threshold in network generalization"); + + betweeness_thresh_opt = G_define_option(); + betweeness_thresh_opt->key = "betweeness_thresh"; + betweeness_thresh_opt->type = TYPE_DOUBLE; + betweeness_thresh_opt->required = YES; + betweeness_thresh_opt->answer = "0"; + betweeness_thresh_opt->description = + _("Betweeness threshold in network generalization"); + alfa_opt = G_define_option(); alfa_opt->key = "alfa"; alfa_opt->type = TYPE_DOUBLE; @@ -184,6 +216,9 @@ iterations = atoi(iterations_opt->answer); slide = atof(slide_opt->answer); angle_thresh = atof(angle_thresh_opt->answer); + degree_thresh = atof(degree_thresh_opt->answer); + closeness_thresh = atof(closeness_thresh_opt->answer); + betweeness_thresh = atof(betweeness_thresh_opt->answer); mask_type = type_mask(type_opt); G_debug(3, "Method: %s", method_opt->answer); @@ -212,6 +247,10 @@ method = DOUGLAS_REDUCTION; else if (strcmp(s, "sliding_averaging") == 0) method = SLIDING_AVERAGING; + else if (strcmp(s, "network") == 0) + method = NETWORK; + else if (strcmp(s, "displacement") == 0) + method = DISPLACEMENT; else { G_fatal_error(_("Unknown method")); exit(EXIT_FAILURE); @@ -289,12 +328,31 @@ Vect_hist_command(&Out); total_input = total_output = 0; + + if (method == DISPLACEMENT) { + snakes_displacement(&In, &Out, thresh, alfa, beta, 1.0, 1.0, + iterations); + }; + + /* TODO: rearrange code below. It's really messy */ + if (method == NETWORK) { + total_output = + graph_generalization(&In, &Out, degree_thresh, closeness_thresh, + betweeness_thresh); + } + else { + G_message(_("Generalization ...")); + G_percent_reset(); + }; i = 0; - while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { + n_lines = Vect_get_num_lines(&In); + while (method < NETWORK && + (type = Vect_read_next_line(&In, Points, Cats)) > 0) { i++; - if (type == GV_CENTROID) + G_percent(i, n_lines, 1); + if (type == GV_CENTROID && !(mask_type & GV_BOUNDARY)) continue; /* skip old centroids, - * we calculate new */ + * we calculate new if we generalize boundarie */ total_input += Points->n_points; if ((type & mask_type) && (!chcat || varray->c[i])) { @@ -373,25 +431,26 @@ /* calculate new centroids - * TODO: Don't fiddle with centroid if !(mask_type & GV_BOUNDARY) - * There's no reason to recalculate them as the ares - * are unchanged + * We need to calculate them only if the boundaries + * were generalized */ - Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); - n_areas = Vect_get_num_areas(&Out); - for (i = 1; i <= n_areas; i++) { - /* skip dead area */ - if (!Vect_area_alive(&Out, i)) - continue; - Vect_get_area_cats(&In, i, Cats); - ret = Vect_get_point_in_area(&Out, i, &x, &y); - if (ret < 0) { - G_warning(_("Cannot calculate area centroid")); - continue; + if (mask_type & GV_BOUNDARY) { + Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); + n_areas = Vect_get_num_areas(&Out); + for (i = 1; i <= n_areas; i++) { + /* skip dead area */ + if (!Vect_area_alive(&Out, i)) + continue; + Vect_get_area_cats(&In, i, Cats); + ret = Vect_get_point_in_area(&Out, i, &x, &y); + if (ret < 0) { + G_warning(_("Cannot calculate area centroid")); + continue; + }; + Vect_reset_line(Points); + Vect_append_point(Points, x, y, 0.0); + Vect_write_line(&Out, GV_CENTROID, Points, Cats); }; - Vect_reset_line(Points); - Vect_append_point(Points, x, y, 0.0); - Vect_write_line(&Out, GV_CENTROID, Points, Cats); }; /* remove small areas */ @@ -406,8 +465,10 @@ if (ca_flag->answer) copy_tables_by_cats(&In, &Out); - G_message(_("Number of vertices was reduced from %d to %d[%d%%]"), - total_input, total_output, (total_output * 100) / total_input); + if (total_input != 0) + G_message(_("Number of vertices was reduced from %d to %d[%d%%]"), + total_input, total_output, + (total_output * 100) / total_input); Vect_close(&In); Vect_close(&Out); Modified: trunk/grassaddons/v.generalize/matrix.c =================================================================== --- trunk/grassaddons/v.generalize/matrix.c 2007-07-20 19:41:37 UTC (rev 974) +++ trunk/grassaddons/v.generalize/matrix.c 2007-07-22 22:39:21 UTC (rev 975) @@ -31,7 +31,7 @@ return 0; for (i = 0; i < rows; i++) { - res->a[i] = (double *)G_malloc(cols * sizeof(double)); + res->a[i] = (double *)G_calloc(cols, sizeof(double)); if (res->a[i] == NULL) { for (j = 0; j < i; j++) G_free(res->a[j]); @@ -57,8 +57,8 @@ if (a.cols != b.rows) return 0; - if (!matrix_init(a.rows, b.cols, res)) - return 0; + //if (!matrix_init(a.rows, b.cols, res)) + // return 0; int i, j, k; for (i = 0; i < a.rows; i++) @@ -120,7 +120,7 @@ }; /* TODO: don't test directly equality to zero */ -int matrix_inverse(MATRIX a, MATRIX * res) +int matrix_inverse(MATRIX a, MATRIX * res, int bandwidth) {; /* not a square matrix */ @@ -166,6 +166,8 @@ if (i == j) continue; double c = -a.a[j][i]; + if (c == 0.0) + continue; matrix_row_add_multiple(j, i, c, &a); matrix_row_add_multiple(j, i, c, res); }; @@ -174,6 +176,22 @@ return 1; }; +void matrix_mult_scalar(double s, MATRIX * m) +{ + int i, j; + for (i = 0; i < m->rows; i++) + for (j = 0; j < m->cols; j++) + m->a[i][j] *= s; +}; + +void matrix_add(MATRIX a, MATRIX b, MATRIX * res) +{ + int i, j; + for (i = 0; i < res->rows; i++) + for (j = 0; j < res->cols; j++) + res->a[i][j] = a.a[i][j] + b.a[i][j]; +}; + void matrix_print(MATRIX a) { int i, j; Modified: trunk/grassaddons/v.generalize/matrix.h =================================================================== --- trunk/grassaddons/v.generalize/matrix.h 2007-07-20 19:41:37 UTC (rev 974) +++ trunk/grassaddons/v.generalize/matrix.h 2007-07-22 22:39:21 UTC (rev 975) @@ -42,7 +42,11 @@ /* calculate the inverse of given (square) matrix. Returns 0 if * the matrix is not invertible or if an error occurs. * Otherwise it returns 1 */ -extern int matrix_inverse(MATRIX a, MATRIX * res); +extern int matrix_inverse(MATRIX a, MATRIX * res, int bandwidth); +/* multiplies matrix by a scalar */ +extern void matrix_mult_scalar(double s, MATRIX * m); +/* res = a + b. Does not cheack the dimensions */ +extern void matrix_add(MATRIX a, MATRIX b, MATRIX * res); /* debug function */ extern void matrix_print(MATRIX a); #endif Added: trunk/grassaddons/v.generalize/network.c =================================================================== --- trunk/grassaddons/v.generalize/network.c (rev 0) +++ trunk/grassaddons/v.generalize/network.c 2007-07-22 22:39:21 UTC (rev 975) @@ -0,0 +1,255 @@ + +/**************************************************************** + * + * MODULE: v.generalize + * + * AUTHOR(S): Daniel Bundala + * + * PURPOSE: Network generalization + * + * COPYRIGHT: (C) 2002-2005 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 +#include +#include +#include +#include + +typedef struct +{ + int **edge; /* edge for each vertex */ + int *degree; /* degree of vertices */ + int vertices; +} NGRAPH; + +void graph_free(NGRAPH * g) +{ + int i; + return; + G_free(g->degree); + if (g->edge) { + for (i = 0; i < g->vertices; g++) + G_free(g->edge[i]); + }; + G_free(g->edge); + return; +}; + +int graph_init(NGRAPH * g, int vertices) +{ + g->edge = NULL; + g->degree = NULL; + + g->vertices = vertices; + g->degree = (int *)G_calloc(vertices, sizeof(int)); + if (!g->degree) + return 0; + g->edge = (int **)G_calloc(vertices, sizeof(int *)); + if (!g->edge) { + graph_free(g); + return 0; + }; + + return 1; +}; + +/* writes the most important part of the In network to Out network + * according to the thresholds, output is bigger for smaller + * thresholds. Function returns the number of points written + TODO: rewrite ilist by somthing more space and time efficient + or at least, implement append which does not check whether + the value is already in the list*/ +int graph_generalization(struct Map_info *In, struct Map_info *Out, + double degree_thresh, double closeness_thresh, + double betweeness_thresh) +{ + + int i; + int output = 0; + dglGraph_s *gr; + NGRAPH g; + int nnodes; + struct line_pnts *Points; + struct line_cats *Cats; + int type; + int *closeness, *queue, *internal, *paths, *comp, *dist; + double *betw, *betweeness; + struct ilist **prev; + + Vect_net_build_graph(In, GV_LINE | GV_BOUNDARY, 0, 0, NULL, NULL, NULL, 0, + 0); + gr = &(In->graph); + /* build own graph by edge<->vertex */ + /* each vertex represents undirected edge */ + if (!graph_init(&g, dglGet_EdgeCount(gr) / 2 + 1)) { + G_fatal_error(_("Out of memory")); + return 0; + }; + + nnodes = dglGet_NodeCount(gr); + + for (i = 0; i < nnodes; i++) { + dglInt32_t *node, *edgeset, *edge; + dglEdgesetTraverser_s et; + node = dglGetNode(gr, (dglInt32_t) i); + edgeset = dglNodeGet_OutEdgeset(gr, node); + dglEdgeset_T_Initialize(&et, gr, edgeset); + for (edge = dglEdgeset_T_First(&et); edge; + edge = dglEdgeset_T_Next(&et)) { + int id, from_degree, to_degree; + dglInt32_t *to, *from, *to_edgeset, *to_edge; + dglEdgesetTraverser_s to_et; + from = dglEdgeGet_Head(gr, edge); + to = dglEdgeGet_Tail(gr, edge); + to_edgeset = dglNodeGet_OutEdgeset(gr, to); + dglEdgeset_T_Initialize(&to_et, gr, to_edgeset); + + + to_degree = dglNodeGet_OutDegree(gr, to); + from_degree = dglNodeGet_OutDegree(gr, from); + id = abs(dglEdgeGet_Id(gr, edge)); + + /* allocate memory, if it has not been not allocated already */ + if (!g.edge[id]) { + g.edge[id] = G_malloc(sizeof(int) * (to_degree + from_degree)); + if (!g.edge[id]) { + graph_free(&g); + G_fatal_error(_("Out of memory")); + return 0; + }; + }; + + for (to_edge = dglEdgeset_T_First(&to_et); to_edge; + to_edge = dglEdgeset_T_Next(&to_et)) { + int id2 = abs(dglEdgeGet_Id(gr, to_edge)); + g.edge[id][g.degree[id]++] = id2; + }; + + + dglEdgeset_T_Release(&to_et); + }; + dglEdgeset_T_Release(&et); + + }; + + closeness = (int *)G_calloc(g.vertices, sizeof(int)); + queue = (int *)G_calloc(g.vertices, sizeof(int)); + dist = (int *)G_calloc(g.vertices, sizeof(int)); + internal = (int *)G_calloc(g.vertices, sizeof(int)); + betweeness = (double *)G_calloc(g.vertices, sizeof(double)); + paths = (int *)G_calloc(g.vertices, sizeof(int)); + comp = (int *)G_calloc(g.vertices, sizeof(int)); + betw = (double *)G_calloc(g.vertices, sizeof(double)); + prev = (struct ilist **)G_calloc(g.vertices, sizeof(struct ilist *)); + for (i = 0; i < g.vertices; i++) + prev[i] = Vect_new_list(); + + + /* run BFS from each vertex and find the sum + * of the shortest paths from each vertex */ + G_percent_reset(); + G_message(_("Calculating centrality measures ...")); + for (i = 1; i < g.vertices; i++) { + int front, back, j; + G_percent(i, g.vertices - 1, 1); + front = 0; + back = 1; + queue[front] = i; + /* Is this portable? */ + memset(dist, 127, sizeof(int) * g.vertices); + dist[i] = 0; + closeness[i] = 0; + comp[i] = 0; + + memset(paths, 0, sizeof(int) * g.vertices); + paths[i] = 1; + memset(internal, 0, sizeof(int) * g.vertices); + for (j = 0; j < g.vertices; j++) + Vect_reset_list(prev[j]); + + while (front != back) { + int v, j; + v = queue[front]; + comp[i]++; + front = (front + 1) % g.vertices; + for (j = 0; j < g.degree[v]; j++) { + int to = g.edge[v][j]; + if (dist[to] > dist[v] + 1) { + paths[to] = paths[v]; + internal[v] = 1; + dist[to] = dist[v] + 1; + closeness[i] += dist[to]; + queue[back] = to; + Vect_reset_list(prev[to]); + Vect_list_append(prev[to], v); + back = (back + 1) % g.vertices; + } + else if (dist[to] == dist[v] + 1) { + internal[v] = 1; + paths[to] += paths[v]; + Vect_list_append(prev[to], v); + }; + }; + }; + /*finally run another BFS from the leaves in the BFS DAG + * and calculate betweeness centrality measure */ + front = 0; + back = 0; + for (j = 1; j < g.vertices; j++) + if (!internal[j] && dist[j] <= g.vertices) { + queue[back] = j; + back = (back + 1) % g.vertices; + }; + memset(betw, 0, sizeof(double) * g.vertices); + while (front != back) { + int v, j; + v = queue[front]; + front = (front + 1) % g.vertices; + betweeness[v] += betw[v]; + for (j = 0; j < prev[v]->n_values; j++) { + int to = prev[v]->value[j]; + if (betw[to] == 0) { + queue[back] = to; + back = (back + 1) % g.vertices; + }; + betw[to] += + (betw[v] + + (double)1.0) * ((double)paths[to] / (double)paths[v]); + }; + }; + }; + + + Points = Vect_new_line_struct(); + Cats = Vect_new_cats_struct(); + for (i = 1; i < g.vertices; i++) { + if (g.degree[i] >= degree_thresh && + (comp[i] - 1.0) / closeness[i] >= closeness_thresh && + betweeness[i] >= betweeness_thresh) { + type = Vect_read_line(In, Points, Cats, i); + output += Points->n_points; + Vect_write_line(Out, type, Points, Cats); + }; + }; + + G_free(dist); + G_free(closeness); + G_free(paths); + G_free(betweeness); + G_free(internal); + G_free(queue); + G_free(comp); + G_free(betw); + for (i = 0; i < g.vertices; i++) + Vect_destroy_list(prev[i]); + G_free(prev); + graph_free(&g); + return output; +}; Property changes on: trunk/grassaddons/v.generalize/network.c ___________________________________________________________________ Name: svn:executable + * Modified: trunk/grassaddons/v.generalize/smoothing.c =================================================================== --- trunk/grassaddons/v.generalize/smoothing.c 2007-07-20 19:41:37 UTC (rev 974) +++ trunk/grassaddons/v.generalize/smoothing.c 2007-07-22 22:39:21 UTC (rev 975) @@ -405,6 +405,9 @@ matrix_init(n + 2 * plus, 1, &xcoord); matrix_init(n + 2 * plus, 1, &ycoord); matrix_init(n + 2 * plus, 1, &zcoord); + matrix_init(n + 2 * plus, 1, &xout); + matrix_init(n + 2 * plus, 1, &yout); + matrix_init(n + 2 * plus, 1, &zout); double x0 = Points->x[0]; double y0 = Points->y[0]; @@ -451,7 +454,7 @@ matrix_add_identity((double)1.0, &g); /* find its inverse */ - if (!matrix_inverse(g, &ginv)) { + if (!matrix_inverse(g, &ginv, 5)) { G_fatal_error(_("Could not find the inverse matrix")); return n; }; From landa at grass.itc.it Mon Jul 23 09:49:50 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Mon Jul 23 09:49:51 2007 Subject: [grass-addons] r976 - trunk/grassaddons/gui/gui_modules Message-ID: <200707230749.l6N7noq2006825@grass.itc.it> Author: landa Date: 2007-07-23 09:49:50 +0200 (Mon, 23 Jul 2007) New Revision: 976 Modified: trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: Fix bug: inport module in digit.py Part of updates for digitization tool (still disabled). Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-07-22 22:39:21 UTC (rev 975) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-07-23 07:49:50 UTC (rev 976) @@ -55,9 +55,13 @@ "This only TEMPORARY solution (display driver based on SWIG-Python interface is EXTREMELY SLOW!\n" \ "Will be replaced by C/C++ display driver." else: - driverPath = os.path.join( os.getenv("GISBASE"), "etc","wx", "display_driver") - sys.path.append(driverPath) - from grass6_wxdriver import DisplayDriver + 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: """ @@ -71,28 +75,23 @@ #self.SetCategory() - if usePyDisplayDriver: - self.driver = PyDisplayDriver(self, mapwindow) - else: - self.driver = CDisplayDriver(self, mapwindow) - # is unique for map window instance if not settings: self.settings = {} # symbology - self.settings["symbolBackground"] = (None, "white") # enabled, color - self.settings["symbolHighlight"] = (None, "yellow") - self.settings["symbolPoint"] = (True, "black") - self.settings["symbolLine"] = (True, "black") - self.settings["symbolBoundaryNo"] = (True, "grey") - self.settings["symbolBoundaryOne"] = (True, "orange") - self.settings["symbolBoundaryTwo"] = (True, "green") - self.settings["symbolCentroidIn"] = (True, "blue") - self.settings["symbolCentroidOut"] = (True, "brown") - self.settings["symbolCentroidDup"] = (True, "violet") - self.settings["symbolNodeOne"] = (True, "red") - self.settings["symbolNodeTwo"] = (True, "dark green") - self.settings["symbolVertex"] = (True, "pink") + self.settings["symbolBackground"] = (None, (255,255,255, 255)) # white + self.settings["symbolHighlight"] = (None, (255, 255, 0, 255)) #yellow + self.settings["symbolPoint"] = (True, (0, 0, 0, 255)) # black + self.settings["symbolLine"] = (True, (0, 0, 0, 255)) # black + self.settings["symbolBoundaryNo"] = (True, (126, 126, 126, 255)) # grey + self.settings["symbolBoundaryOne"] = (True, (255, 135, 0, 255)) # orange + self.settings["symbolBoundaryTwo"] = (True, (0, 255, 0, 255)) # green + self.settings["symbolCentroidIn"] = (True, (0, 0, 255, 255)) # blue + self.settings["symbolCentroidOut"] = (True, (165, 42, 42, 255)) # brown + self.settings["symbolCentroidDup"] = (True, (156, 62, 206, 255)) # violet + self.settings["symbolNodeOne"] = (True, (255, 0, 0, 255)) # red + self.settings["symbolNodeTwo"] = (True, (0, 86, 45, 255)) # dark green + self.settings["symbolVertex"] = (True, (255, 20, 147, 255)) # deep pink # display self.settings["lineWidth"] = (2, "screen pixels") @@ -109,6 +108,11 @@ else: self.settings = settings + if usePyDisplayDriver: + self.driver = PyDisplayDriver(self, mapwindow) + else: + self.driver = CDisplayDriver(self, mapwindow) + self.threshold = self.driver.GetThreshold() def SetCategoryNextToUse(self): @@ -234,7 +238,7 @@ vedit = cmd.Command(cmd=command, stdin=input) # redraw map - self.driver.ReDrawMap(map) + #self.driver.ReDrawMap(map) def DeleteSelectedLines(self): """Delete selected vector features from the vector map""" @@ -255,7 +259,7 @@ vedit = cmd.Command(cmd=command) # redraw map - self.driver.ReDrawMap(self.map) + #self.driver.ReDrawMap(self.map) return True @@ -291,7 +295,7 @@ vedit = cmd.Command(cmd=command) # redraw map - self.driver.ReDrawMap(self.map) + #self.driver.ReDrawMap(self.map) return True @@ -313,7 +317,7 @@ vedit = cmd.Command(cmd=command) # redraw map - self.driver.ReDrawMap(self.map) + #self.driver.ReDrawMap(self.map) return True @@ -343,7 +347,7 @@ vedit = cmd.Command(cmd=command) # redraw map - self.driver.ReDrawMap(self.map) + #self.driver.ReDrawMap(self.map) return True @@ -429,20 +433,117 @@ """ def __init__(self, parent, mapwindow): AbstractDisplayDriver.__init__(self, parent, mapwindow) - self.display = DisplayDriver(None) - + + # initialize wx display driver + try: + self.display = DisplayDriver() + except: + self.display = None + + settings = self.parent.settings + self.UpdateSettings() + def Reset(self, map): if map: name, mapset = map.split('@') - self.display.Reset(name, mapset) + self.display.OpenMap(str(name), str(mapset)) else: - self.display.Reset1() + self.display.CloseMap() def DrawMap(self): - """Display content of the map in PseudoDC""" - nlines = self.display.DrawMap() + """Display content of the map in PseudoDC + + Return wx.Image + """ + bmp = wx.EmptyBitmap(self.mapwindow.Map.width, self.mapwindow.Map.height) + dc = wx.MemoryDC( bmp) + dc.Clear() + dc.SetBackgroundMode(wx.TRANSPARENT) + + nlines = self.display.DrawMap(dc) Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d" % nlines) + + return bmp.ConvertToImage() + + def SetRegion(self, reg): + """Set geographical region + + Needed for 'cell2pixel' conversion""" + Debug.msg(3, "CDisplayDriver.SetRegion(): %s" % reg) + self.display.SetRegion(reg['n'], + reg['s'], + reg['e'], + reg['w'], + reg['nsres'], + reg['ewres']) + def UpdateSettings(self): + """Update display driver settings""" + settings = self.parent.settings + # TODO map units + + if not self.display: + return + + self.display.SetSettings (0, + settings['symbolPoint'][0], + wx.Color(settings['symbolPoint'][1][0], + settings['symbolPoint'][1][1], + settings['symbolPoint'][1][2], + 255).GetRGB(), + settings['symbolLine'][0], + wx.Color(settings['symbolLine'][1][0], + settings['symbolLine'][1][1], + settings['symbolLine'][1][2], + 255).GetRGB(), + settings['symbolBoundaryNo'][0], + wx.Color(settings['symbolBoundaryNo'][1][0], + settings['symbolBoundaryNo'][1][1], + settings['symbolBoundaryNo'][1][2], + 255).GetRGB(), + settings['symbolBoundaryOne'][0], + wx.Color(settings['symbolBoundaryOne'][1][0], + settings['symbolBoundaryOne'][1][1], + settings['symbolBoundaryOne'][1][2], + 255).GetRGB(), + settings['symbolBoundaryTwo'][0], + wx.Color(settings['symbolBoundaryTwo'][1][0], + settings['symbolBoundaryTwo'][1][1], + settings['symbolBoundaryTwo'][1][2], + 255).GetRGB(), + settings['symbolCentroidIn'][0], + wx.Color(settings['symbolCentroidIn'][1][0], + settings['symbolCentroidIn'][1][1], + settings['symbolCentroidIn'][1][2], + 255).GetRGB(), + settings['symbolCentroidOut'][0], + wx.Color(settings['symbolCentroidOut'][1][0], + settings['symbolCentroidOut'][1][1], + settings['symbolCentroidOut'][1][2], + 255).GetRGB(), + settings['symbolCentroidDup'][0], + wx.Color(settings['symbolCentroidDup'][1][0], + settings['symbolCentroidDup'][1][1], + settings['symbolCentroidDup'][1][2], + 255).GetRGB(), + settings['symbolNodeOne'][0], + wx.Color(settings['symbolNodeOne'][1][0], + settings['symbolNodeOne'][1][1], + settings['symbolNodeOne'][1][2], + 255).GetRGB(), + settings['symbolNodeTwo'][0], + wx.Color(settings['symbolNodeTwo'][1][0], + settings['symbolNodeTwo'][1][1], + settings['symbolNodeTwo'][1][2], + 255).GetRGB(), + settings['symbolVertex'][0], + wx.Color(settings['symbolVertex'][1][0], + settings['symbolVertex'][1][1], + settings['symbolVertex'][1][2], + 255).GetRGB(), + settings['lineWidth'][0]) + + class PyDisplayDriver(AbstractDisplayDriver): """ Experimental display driver implemented in Python using @@ -993,3 +1094,7 @@ self.parent.digit.threshold = self.parent.digit.driver.GetThreshold() except: pass + + # update driver settings + if not usePyDisplayDriver: + self.parent.digit.driver.UpdateSettings() Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-22 22:39:21 UTC (rev 975) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-23 07:49:50 UTC (rev 976) @@ -169,6 +169,8 @@ # self.mapfile = None # image file to be rendered self.img = "" # wx.Image object (self.mapfile) + # used in digitization tool (do not redraw vector map) + self.imgVectorMap = None self.ovldict = {} # list of images for overlays self.ovlcoords = {} # positioning coordinates for decoration overlay self.ovlchk = {} # showing/hiding decorations @@ -205,11 +207,12 @@ # OnSize called to make sure the buffer is initialized. # This might result in OnSize getting called twice on some # platforms at initialization, but little harm done. - #!!! self.OnSize(None) + self.OnSize(None) # create a PseudoDC for map decorations like scales and legends self.pdc = wx.PseudoDC() - self._Buffer = '' # will store an off screen empty bitmap for saving to file + # will store an off screen empty bitmap for saving to file + self._Buffer = '' self.Map.SetRegion() # make sure that extents are updated at init self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None) @@ -236,12 +239,13 @@ self.select[drawid] = False pdc.BeginDrawing() - if drawid != 99: + + if drawid != 99 and drawid != 100: bg = wx.TRANSPARENT_BRUSH else: bg = wx.Brush(self.GetBackgroundColour()) pdc.SetBackground(bg) - #pdc.Clear() #FIXME (to avoid black background) + #pdc.Clear() self.Refresh() Debug.msg (5, "BufferedWindow.Draw(): id=%s, pdctype=%s, coord=%s" % (drawid, pdctype, coords)) @@ -361,29 +365,35 @@ def OnPaint(self, event): """ Draw psuedo DC to buffered paint DC + + Additionaly draw also vector map which is edited """ dc = wx.BufferedPaintDC(self, self._Buffer) - # use PrepareDC to set position correctly - self.PrepareDC(dc) # we need to clear the dc BEFORE calling PrepareDC bg = wx.Brush(self.GetBackgroundColour()) dc.SetBackground(bg) dc.Clear() + + # use PrepareDC to set position correctly + self.PrepareDC(dc) + # create a clipping rect from our position and size - # and the Update Region + # and update region rgn = self.GetUpdateRegion() r = rgn.GetBox() + dc.SetClippingRect(r) # draw to the dc using the calculated clipping rect self.pdc.DrawToDCClipped(dc,r) - - + def OnSize(self, event): """ Scale map image so that it is the same size as the Window """ + + Debug.msg(3, "BufferedWindow.OnSize():") # set size of the input image self.Map.width, self.Map.height = self.GetClientSize() @@ -454,7 +464,7 @@ return img - def UpdateMap(self, render=True, redrawAll=True, removeId=[]): + def UpdateMap(self, render=True, redraw=True, removeId=[]): """ Updates the canvas anytime there is a change to the underlying images or to the geometry of the canvas. @@ -470,6 +480,9 @@ self.img = self.GetImage() self.resize = False + if not self.img or redraw == False: + return + # paint images to PseudoDC if len(removeId) > 0: for id in removeId: @@ -479,16 +492,25 @@ self.pdc.Clear() self.pdc.RemoveAll() - if not self.img or redrawAll == False: - return - try: id = self.imagedict[self.img] except: return + + # render vector map layer which is edited + digitToolbar = self.parent.digittoolbar + if digitToolbar and \ + digitToolbar.layerSelectedID != None: + # set region + self.parent.digit.driver.SetRegion(self.Map.region) + # draw map + self.imgVectorMap = self.parent.digit.driver.DrawMap() + self.Draw(self.pdc, self.img, drawid=id) # draw map image background + if self.imgVectorMap: + self.Draw(self.pdc, self.imgVectorMap, drawid=100) # draw vector map image self.ovldict = self.GetOverlay() # list of decoration overlay images if self.ovldict != {}: # draw scale and legend overlays for id in self.ovldict: @@ -512,11 +534,6 @@ (self.Map.region["w"], self.Map.region["e"], self.Map.region["n"], self.Map.region["s"]), 0) - digitToolbar = self.parent.digittoolbar - if digitToolbar and self.parent.digit.driver: - self.pen = wx.Pen(colour='red', width=2, style=wx.SOLID) - self.parent.digit.driver.DrawMap() - def EraseMap(self): """ Erase the map display @@ -530,11 +547,16 @@ dc = wx.BufferedDC(wx.ClientDC(self)) 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) self.dragimg.GetImageRect(moveto) self.dragimg.Move(moveto) + dc.Clear() self.dragimg.DoDrawImage(dc, moveto) self.dragimg.EndDrag() @@ -682,7 +704,6 @@ self.mouse['end'] = event.GetPositionTuple()[:] self.MouseDraw() - # double click elif event.ButtonDClick(): self.OnButtonDClick(event) @@ -845,7 +866,7 @@ self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype) # redraw map - self.UpdateMap() + self.UpdateMap(redraw=True) elif self.mouse["use"] == "query": # querying @@ -881,7 +902,7 @@ if len(self.moveIds) > 0: self.UpdateMap(render=False) if digitToolbar.action in ["moveLine", "moveVertex"]: - self.UpdateMap(render=False, redrawAll=False, removeId=self.moveIds) + self.UpdateMap(render=False, redraw=False, removeId=self.moveIds) # get pseudoDC id of objects which should be redrawn if digitToolbar.action == "moveLine": self.moveIds = self.parent.digit.driver.GetSelected(grassId=False) @@ -1750,6 +1771,7 @@ type = wx.BITMAP_TYPE_TIF if ext != '.gif': path = base+'.gif' self.MapWindow.SaveToFile(path, type) + dlg.Destroy() def PrintMenu(self, event): Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-07-22 22:39:21 UTC (rev 975) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-07-23 07:49:50 UTC (rev 976) @@ -346,6 +346,8 @@ else: # tool already enabled pass + self.mapdisplay.imgVectorMap = None + def OnPopupProperties (self, event): """Popup properties dialog""" self.PropertiesDialog(self.layer_selected) From bundala at grass.itc.it Mon Jul 23 23:10:06 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Mon Jul 23 23:10:08 2007 Subject: [grass-addons] r977 - trunk/grassaddons/v.generalize Message-ID: <200707232110.l6NLA68K019048@grass.itc.it> Author: bundala Date: 2007-07-23 23:10:03 +0200 (Mon, 23 Jul 2007) New Revision: 977 Modified: trunk/grassaddons/v.generalize/displacement.c trunk/grassaddons/v.generalize/main.c Log: working version of displacement Modified: trunk/grassaddons/v.generalize/displacement.c =================================================================== --- trunk/grassaddons/v.generalize/displacement.c 2007-07-23 07:49:50 UTC (rev 976) +++ trunk/grassaddons/v.generalize/displacement.c 2007-07-23 21:10:03 UTC (rev 977) @@ -34,8 +34,7 @@ int n_points; int n_lines; - /*this is not THE final version, we need to threat the same - * points on the different lines (e.g croassroads) + /*this is not THE final version * * Also, we must be able to specify the lines we want to * displace. @@ -53,6 +52,7 @@ struct line_cats *Cats; MATRIX k, dx, dy, fx, fy, kinv, dx_old, dy_old; POINT *parray; + POINT *pset; int *point_index; int *first, *line_index; double threshold2; @@ -69,18 +69,14 @@ n_points += Points->n_points; }; - matrix_init(n_points, n_points, &k); - matrix_init(n_points, 1, &dx); - matrix_init(n_points, 1, &dy); - matrix_init(n_points, 1, &fx); - matrix_init(n_points, 1, &fy); - matrix_init(n_points, 1, &dx_old); - matrix_init(n_points, 1, &dy_old); parray = (POINT *) G_calloc(n_points, sizeof(POINT)); + pset = (POINT *) G_calloc(n_points, sizeof(POINT)); point_index = (int *)G_calloc(n_points, sizeof(int)); first = (int *)G_calloc(n_points, sizeof(int)); line_index = (int *)G_calloc(n_points, sizeof(int)); + /* read points + * TODO: some better/faster method for determining whether two points are the same */ index = 0; pindex = 0; from = to = 0; @@ -91,35 +87,61 @@ for (j = 0; j < Points->n_points; j++) { int q, w; double a, b, c, h; - point_assign(Points, j, with_z, &parray[pindex++]); - point_index[pindex - 1] = index; - first[pindex - 1] = (j == 0); - line_index[pindex - 1] = i; + POINT cur; + int findex; + point_assign(Points, j, with_z, &cur); + /* check whether we alerady have point with the same + * coordinates */ + findex = pindex; + for (q = 0; q < pindex; q++) + if (point_dist_square(cur, pset[q]) < 0.5) { + findex = q; + break; + }; - a = 2.0 * alfa + 6.0 * beta; - b = -alfa - 4.0 * beta; - c = beta; + point_index[index] = findex; + if (findex == pindex) { + point_assign(Points, j, with_z, &pset[pindex]); + pindex++; + }; + first[index] = (j == 0); + line_index[index] = i; + point_assign(Points, j, with_z, &parray[index]); + index++; + }; + }; - if (!first[pindex - 1]) { - h = point_dist(parray[pindex - 1], parray[pindex - 2]); - if (h == 0) - h = 1.0; - } - else - h = 1.0; - a /= h; - b /= h; - c /= h; - double ar[5] = { c, b, a, b, c }; - for (q = 0; q < 5; q++) - if (index + q - 2 >= from && index + q - 2 < to) - k.a[index][index + q - 2] = ar[q]; + matrix_init(pindex, pindex, &k); + matrix_init(pindex, 1, &dx); + matrix_init(pindex, 1, &dy); + matrix_init(pindex, 1, &fx); + matrix_init(pindex, 1, &fy); + matrix_init(pindex, 1, &dx_old); + matrix_init(pindex, 1, &dy_old); + matrix_mult_scalar(0.0, &k); - index++; - }; + double a = 2.0 * alfa + 6.0 * beta; + double b = -alfa - 4.0 * beta; + double c = beta; + + /* build matrix */ + for (i = 0; i < index; i++) { + int r = point_index[i]; + int l = line_index[i]; + k.a[r][r] += a; + if (i + 1 < index && line_index[i + 1] == l) + k.a[r][point_index[i + 1]] += b; + if (i + 2 < index && line_index[i + 2] == l) + k.a[r][point_index[i + 2]] += c; + if (i >= 1 && line_index[i - 1] == l) + k.a[r][point_index[i - 1]] += b; + if (i >= 2 && line_index[i - 2] == l) + k.a[r][point_index[i - 2]] += c; }; + // matrix_print(k); + threshold2 = threshold * threshold; matrix_add_identity(gama, &k); @@ -128,6 +150,7 @@ matrix_mult_scalar(0.0, &dy); /*calculate the inverse */ + G_message(_("Inverting matrix, be patient ...")); if (!matrix_inverse(k, &kinv, 4)) G_fatal_error(_("Could not calculate the inverse matrix")); @@ -145,7 +168,7 @@ matrix_add(dy_old, dy, &dy_old); /* calculate force vectors */ - for (i = 0; i < pindex; i++) { + for (i = 0; i < index; i++) { double cx, cy; cx = dx.a[point_index[i]][0]; @@ -155,8 +178,9 @@ fx.a[point_index[i]][0] -= cx * f; fy.a[point_index[i]][0] -= cy * f; - for (j = 1; j < pindex; j++) { - if (line_index[i] == line_index[j] || first[j]) + for (j = 1; j < index; j++) { + if (line_index[i] == line_index[j] || first[j] || + point_index[i] == point_index[j]) continue; /* if ith point is close to some segment then * apply force to ith point. If the distance @@ -184,6 +208,7 @@ conflicts++; }; }; + printf("Conflicts: %d\n", conflicts); matrix_mult_scalar(delta, &fx); matrix_mult_scalar(delta, &fy); @@ -196,7 +221,7 @@ matrix_mult(kinv, fx, &dx); matrix_mult(kinv, fy, &dy); - for (i = 0; i < pindex; i++) { + for (i = 0; i < index; i++) { parray[i].x += dx.a[point_index[i]][0] - dx_old.a[point_index[i]][0]; parray[i].y += @@ -224,6 +249,7 @@ }; G_free(parray); + G_free(pset); G_free(point_index); G_free(first); G_free(line_index); Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-23 07:49:50 UTC (rev 976) +++ trunk/grassaddons/v.generalize/main.c 2007-07-23 21:10:03 UTC (rev 977) @@ -330,7 +330,7 @@ total_input = total_output = 0; if (method == DISPLACEMENT) { - snakes_displacement(&In, &Out, thresh, alfa, beta, 1.0, 1.0, + snakes_displacement(&In, &Out, thresh, alfa, beta, 1.0, 10.0, iterations); }; From maldacker at grass.itc.it Tue Jul 24 15:37:37 2007 From: maldacker at grass.itc.it (maldacker@grass.itc.it) Date: Tue Jul 24 15:37:39 2007 Subject: [grass-addons] r978 - trunk/grassaddons/v.path.obstacles Message-ID: <200707241337.l6ODbbTv030067@grass.itc.it> Author: maldacker Date: 2007-07-24 15:37:18 +0200 (Tue, 24 Jul 2007) New Revision: 978 Modified: trunk/grassaddons/v.path.obstacles/geometry.c trunk/grassaddons/v.path.obstacles/main.c trunk/grassaddons/v.path.obstacles/visibility.c Log: correction of the point inside function. The problem was when the loaded primitives don't have any cat number Modified: trunk/grassaddons/v.path.obstacles/geometry.c =================================================================== --- trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-23 21:10:03 UTC (rev 977) +++ trunk/grassaddons/v.path.obstacles/geometry.c 2007-07-24 13:37:18 UTC (rev 978) @@ -81,7 +81,7 @@ n1 = other2(n1); n2 = other2(n2); - }while( n2 != p ); + }while( n1 != p ); return c; } Modified: trunk/grassaddons/v.path.obstacles/main.c =================================================================== --- trunk/grassaddons/v.path.obstacles/main.c 2007-07-23 21:10:03 UTC (rev 977) +++ trunk/grassaddons/v.path.obstacles/main.c 2007-07-24 13:37:18 UTC (rev 978) @@ -144,7 +144,7 @@ struct line_pnts* sites; int i; struct line_cats* cats; - int cat =0; + int cat = 0; int type; sites = Vect_new_line_struct(); @@ -163,8 +163,6 @@ if ( type != GV_LINE && type != GV_BOUNDARY && type != GV_POINT) continue; - Vect_cat_get (cats, 1, &cat); - if ( type == GV_LINE ) process_line(sites, points, &index_point, lines, &index_line, -1); else if ( type == GV_BOUNDARY ) @@ -275,7 +273,7 @@ if ( i == n-2 ) { (*lines)[*index_line].p1 = &((*points)[(*index_point)-1]); - (*lines)[*index_line].p2 = &((*points)[(*index_point)-n+1]); + (*lines)[*index_line].p2 = &((*points)[(*index_point)-n+2]); } else { Modified: trunk/grassaddons/v.path.obstacles/visibility.c =================================================================== --- trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-23 21:10:03 UTC (rev 977) +++ trunk/grassaddons/v.path.obstacles/visibility.c 2007-07-24 13:37:18 UTC (rev 978) @@ -59,8 +59,9 @@ /** for a pair (p, q) of points, add the edge pq if their are visibile to each other */ void handle( struct Point* p, struct Point* q, struct Map_info * out ) -{ +{ + /* if it's a point without segments, just report the edge */ if ( segment1(q) == NULL && segment2(q) == NULL && before(p,q, p->vis )) { report(p,q,out); From bundala at grass.itc.it Tue Jul 24 23:32:05 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Tue Jul 24 23:32:07 2007 Subject: [grass-addons] r979 - trunk/grassaddons/v.generalize Message-ID: <200707242132.l6OLW5bs006541@grass.itc.it> Author: bundala Date: 2007-07-24 23:32:00 +0200 (Tue, 24 Jul 2007) New Revision: 979 Modified: trunk/grassaddons/v.generalize/displacement.c trunk/grassaddons/v.generalize/matrix.c trunk/grassaddons/v.generalize/matrix.h trunk/grassaddons/v.generalize/point.c trunk/grassaddons/v.generalize/point.h trunk/grassaddons/v.generalize/smoothing.c Log: time and memory more efficient version of displacement Modified: trunk/grassaddons/v.generalize/displacement.c =================================================================== --- trunk/grassaddons/v.generalize/displacement.c 2007-07-24 13:37:18 UTC (rev 978) +++ trunk/grassaddons/v.generalize/displacement.c 2007-07-24 21:32:00 UTC (rev 979) @@ -39,14 +39,11 @@ * Also, we must be able to specify the lines we want to * displace. * - * Moreover, there is no reason to cnsider the lines/points - * which are OK - * * I just want to see the results, before i spend * two afternoons working...:) */ - int i, j, index, pindex, iter; + int i, j, index, pindex, iter, type; int with_z = 0; struct line_pnts *Points, *Write; struct line_cats *Cats; @@ -54,10 +51,11 @@ POINT *parray; POINT *pset; int *point_index; - int *first, *line_index; + int *first, *line_index, *need, *sel, *tmp_index; double threshold2; - int from, to; + int selected; + /* initialize structrures and read the number of points */ Points = Vect_new_line_struct(); Write = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); @@ -65,8 +63,9 @@ n_points = 0; for (i = 1; i <= n_lines; i++) { - Vect_read_line(In, Points, NULL, i); - n_points += Points->n_points; + type = Vect_read_line(In, Points, NULL, i); + if (type & GV_LINES) + n_points += Points->n_points; }; parray = (POINT *) G_calloc(n_points, sizeof(POINT)); @@ -74,21 +73,21 @@ point_index = (int *)G_calloc(n_points, sizeof(int)); first = (int *)G_calloc(n_points, sizeof(int)); line_index = (int *)G_calloc(n_points, sizeof(int)); + need = (int *)G_calloc(n_points, sizeof(int)); + sel = (int *)G_calloc(n_points, sizeof(int)); + tmp_index = (int *)G_calloc(n_points, sizeof(int)); /* read points * TODO: some better/faster method for determining whether two points are the same */ index = 0; pindex = 0; - from = to = 0; for (i = 1; i <= n_lines; i++) { - Vect_read_line(In, Points, NULL, i); - from = to; - to = from + Points->n_points; + type = Vect_read_line(In, Points, NULL, i); + if (!(type & GV_LINES)) + continue; for (j = 0; j < Points->n_points; j++) { - int q, w; - double a, b, c, h; + int q, findex; POINT cur; - int findex; point_assign(Points, j, with_z, &cur); /* check whether we alerady have point with the same * coordinates */ @@ -111,6 +110,50 @@ }; }; + + threshold2 = threshold * threshold; + /*select only the points which need to be displace */ + for (i = 0; i < index; i++) { + if (need[point_index[i]]) + continue; + for (j = 1; j < index; j++) { + if (line_index[i] == line_index[j] || first[j] || + point_index[i] == point_index[j] || + point_index[i] == point_index[j - 1]) + continue; + double d = + point_dist_segment_square(parray[i], parray[j], parray[j - 1], + with_z); + if (d < 4 * threshold2) + need[point_index[i]] = 1; + }; + }; + + /* then for each selected point ensure that the neighbours to the both + * sides are selected as well */ + for (i = 0; i < index; i++) { + int l = line_index[i]; + tmp_index[i] = -1; + if (!need[point_index[i]]) + continue; + for (j = -2; j <= 2; j++) + if (i + j >= 0 && i + j < index && line_index[i + j] == l) + sel[point_index[i + j]] = 1; + }; + + /* finally, recalculate indices */ + selected = 0; + for (i = 0; i < pindex; i++) + if (sel[i]) + tmp_index[i] = selected++; + + for (i = 0; i < index; i++) + point_index[i] = tmp_index[point_index[i]]; + pindex = selected; + + printf("%d\n", pindex); + + /* initialize matrices */ matrix_init(pindex, pindex, &k); matrix_init(pindex, 1, &dx); matrix_init(pindex, 1, &dy); @@ -129,34 +172,33 @@ for (i = 0; i < index; i++) { int r = point_index[i]; int l = line_index[i]; + if (r == -1) + continue; k.a[r][r] += a; - if (i + 1 < index && line_index[i + 1] == l) + if (i + 1 < index && line_index[i + 1] == l && point_index[i + 1] != -1) k.a[r][point_index[i + 1]] += b; - if (i + 2 < index && line_index[i + 2] == l) + if (i + 2 < index && line_index[i + 2] == l && point_index[i + 2] != -1) k.a[r][point_index[i + 2]] += c; - if (i >= 1 && line_index[i - 1] == l) + if (i >= 1 && line_index[i - 1] == l && point_index[i - 1] != -1) k.a[r][point_index[i - 1]] += b; - if (i >= 2 && line_index[i - 2] == l) + if (i >= 2 && line_index[i - 2] == l && point_index[i - 2] != -1) k.a[r][point_index[i - 2]] += c; }; - // matrix_print(k); - - threshold2 = threshold * threshold; - matrix_add_identity(gama, &k); - matrix_mult_scalar(0.0, &dx); matrix_mult_scalar(0.0, &dy); /*calculate the inverse */ G_message(_("Inverting matrix, be patient ...")); - if (!matrix_inverse(k, &kinv, 4)) + if (!matrix_inverse(k, &kinv, 1)) G_fatal_error(_("Could not calculate the inverse matrix")); + G_percent_reset(); + G_message(_("Resolving conflicts ...")); for (iter = 0; iter < iterations; iter++) { - int conflicts = 0; + G_percent(iter, iterations, 1); matrix_mult_scalar(0.0, &fx); matrix_mult_scalar(0.0, &fy); @@ -170,17 +212,20 @@ /* calculate force vectors */ for (i = 0; i < index; i++) { - double cx, cy; + double cx, cy, f; + if (point_index[i] == -1) + continue; cx = dx.a[point_index[i]][0]; cy = dy.a[point_index[i]][0]; - double f = sqrt(cx * cx + cy * cy); + f = sqrt(cx * cx + cy * cy) * alfa; f /= threshold2; fx.a[point_index[i]][0] -= cx * f; fy.a[point_index[i]][0] -= cy * f; for (j = 1; j < index; j++) { if (line_index[i] == line_index[j] || first[j] || - point_index[i] == point_index[j]) + point_index[i] == point_index[j] || + point_index[i] == point_index[j - 1]) continue; /* if ith point is close to some segment then * apply force to ith point. If the distance @@ -208,8 +253,8 @@ conflicts++; }; }; - printf("Conflicts: %d\n", conflicts); + /* calculate new displacement */ matrix_mult_scalar(delta, &fx); matrix_mult_scalar(delta, &fy); matrix_mult_scalar(gama, &dx); @@ -222,6 +267,8 @@ matrix_mult(kinv, fy, &dy); for (i = 0; i < index; i++) { + if (point_index[i] == -1) + continue; parray[i].x += dx.a[point_index[i]][0] - dx_old.a[point_index[i]][0]; parray[i].y += @@ -233,19 +280,16 @@ index = 0; for (i = 1; i <= n_lines; i++) { int type = Vect_read_line(In, Points, Cats, i); - /*Vect_read_line(In, Write, NULL, i); - * Write->n_points = 2; */ + if (!(type & GV_LINES)) { + Vect_write_line(Out, type, Points, Cats); + continue; + }; for (j = 0; j < Points->n_points; j++) { - /* Write->x[0] = Points->x[j]; - * Write->y[0] = Points->y[j]; */ Points->x[j] = parray[index].x; Points->y[j] = parray[index].y; - /* Write->x[1] = Points->x[j]; - * Write->y[1] = Points->y[j]; - * Vect_write_line(Out, GV_LINE, Write, Cats); */ index++; }; - Vect_write_line(Out, GV_LINE, Points, Cats); + Vect_write_line(Out, type, Points, Cats); }; G_free(parray); @@ -253,6 +297,9 @@ G_free(point_index); G_free(first); G_free(line_index); + G_free(need); + G_free(sel); + G_free(tmp_index); matrix_free(k); matrix_free(kinv); matrix_free(dx); Modified: trunk/grassaddons/v.generalize/matrix.c =================================================================== --- trunk/grassaddons/v.generalize/matrix.c 2007-07-24 13:37:18 UTC (rev 978) +++ trunk/grassaddons/v.generalize/matrix.c 2007-07-24 21:32:00 UTC (rev 979) @@ -57,8 +57,9 @@ if (a.cols != b.rows) return 0; - //if (!matrix_init(a.rows, b.cols, res)) - // return 0; + /*if (!matrix_init(a.rows, b.cols, res)) + * return 0; + */ int i, j, k; for (i = 0; i < a.rows; i++) @@ -120,7 +121,7 @@ }; /* TODO: don't test directly equality to zero */ -int matrix_inverse(MATRIX a, MATRIX * res, int bandwidth) +int matrix_inverse(MATRIX a, MATRIX * res, int percents) {; /* not a square matrix */ @@ -147,8 +148,14 @@ */ int n = a.rows; + + if (percents) + G_percent_reset(); + for (i = 0; i < n; i++) { int found = 0; + if (percents) + G_percent(i, n, 1); for (j = i; j < n; j++) { if (a.a[j][i] != 0) { /* need to change this row to something */ found = 1; /* more sensible */ Modified: trunk/grassaddons/v.generalize/matrix.h =================================================================== --- trunk/grassaddons/v.generalize/matrix.h 2007-07-24 13:37:18 UTC (rev 978) +++ trunk/grassaddons/v.generalize/matrix.h 2007-07-24 21:32:00 UTC (rev 979) @@ -32,17 +32,18 @@ extern int matrix_init(int rows, int cols, MATRIX * res); /* free the memory occupied by the values of m */ extern void matrix_free(MATRIX m); -/* multiply two matrices, initialize the dimensions of res - * to correct values. Return 1 on success, 0 on failure. - * return value 0 means - bad dimensions or out of memory */ +/* multiply two matrices, Return 1 on success, 0 on failure. + * return value 0 means - bad dimensions */ extern int matrix_mult(MATRIX a, MATRIX b, MATRIX * res); /* adds a multiple of the identity matrix to the given matrix * M = M + s * Id. Returns 1 on success, 0 otherwise */ extern int matrix_add_identity(double s, MATRIX * m); /* calculate the inverse of given (square) matrix. Returns 0 if - * the matrix is not invertible or if an error occurs. + * the matrix is not invertible or if an error occurs. + * percents indicates whether we want to show the progress of + * computation * Otherwise it returns 1 */ -extern int matrix_inverse(MATRIX a, MATRIX * res, int bandwidth); +extern int matrix_inverse(MATRIX a, MATRIX * res, int percents); /* multiplies matrix by a scalar */ extern void matrix_mult_scalar(double s, MATRIX * m); /* res = a + b. Does not cheack the dimensions */ Modified: trunk/grassaddons/v.generalize/point.c =================================================================== --- trunk/grassaddons/v.generalize/point.c 2007-07-24 13:37:18 UTC (rev 978) +++ trunk/grassaddons/v.generalize/point.c 2007-07-24 21:32:00 UTC (rev 979) @@ -99,6 +99,15 @@ return acos(point_dot(a, b) / sqrt(point_dist2(a) * point_dist2(b))); }; +inline double point_dist_segment_square(POINT a, POINT b, POINT c, int with_z) +{ + double px, py, pz, pdist; + int status; + return dig_distance2_point_to_line(a.x, a.y, a.z, b.x, b.y, b.z, + c.x, c.y, c.z, with_z, &px, &py, &pz, + &pdist, &status); +}; + POINT_LIST *point_list_new(POINT p) { POINT_LIST *pl; Modified: trunk/grassaddons/v.generalize/point.h =================================================================== --- trunk/grassaddons/v.generalize/point.h 2007-07-24 13:37:18 UTC (rev 978) +++ trunk/grassaddons/v.generalize/point.h 2007-07-24 21:32:00 UTC (rev 979) @@ -56,6 +56,9 @@ extern inline double point_dist_square(POINT a, POINT b); /* angle in radians between vectors ab and bc */ extern inline double point_angle_between(POINT a, POINT b, POINT c); +/* distance squared between a and segment bc */ +extern inline double point_dist_segment_square(POINT a, POINT b, POINT c, + int with_z); /* creates empty list of points */ extern POINT_LIST *point_list_new(POINT p); /* insert new value to the list just after the l. i.e l->next.p = p */ Modified: trunk/grassaddons/v.generalize/smoothing.c =================================================================== --- trunk/grassaddons/v.generalize/smoothing.c 2007-07-24 13:37:18 UTC (rev 978) +++ trunk/grassaddons/v.generalize/smoothing.c 2007-07-24 21:32:00 UTC (rev 979) @@ -454,7 +454,7 @@ matrix_add_identity((double)1.0, &g); /* find its inverse */ - if (!matrix_inverse(g, &ginv, 5)) { + if (!matrix_inverse(g, &ginv, 0)) { G_fatal_error(_("Could not find the inverse matrix")); return n; }; From bundala at grass.itc.it Thu Jul 26 10:49:00 2007 From: bundala at grass.itc.it (bundala@grass.itc.it) Date: Thu Jul 26 10:49:02 2007 Subject: [grass-addons] r980 - trunk/grassaddons/v.generalize Message-ID: <200707260849.l6Q8n0lD032676@grass.itc.it> Author: bundala Date: 2007-07-26 10:48:56 +0200 (Thu, 26 Jul 2007) New Revision: 980 Modified: trunk/grassaddons/v.generalize/displacement.c trunk/grassaddons/v.generalize/main.c trunk/grassaddons/v.generalize/network.c Log: minor fixes and improvements of displacement algorithm Modified: trunk/grassaddons/v.generalize/displacement.c =================================================================== --- trunk/grassaddons/v.generalize/displacement.c 2007-07-24 21:32:00 UTC (rev 979) +++ trunk/grassaddons/v.generalize/displacement.c 2007-07-26 08:48:56 UTC (rev 980) @@ -28,21 +28,11 @@ * Function returns somthing */ int snakes_displacement(struct Map_info *In, struct Map_info *Out, double threshold, double alfa, double beta, double gama, - double delta, int iterations) + double delta, int iterations, VARRAY * varray) { int n_points; int n_lines; - - /*this is not THE final version - * - * Also, we must be able to specify the lines we want to - * displace. - * - * I just want to see the results, before i spend - * two afternoons working...:) - */ - int i, j, index, pindex, iter, type; int with_z = 0; struct line_pnts *Points, *Write; @@ -64,7 +54,9 @@ for (i = 1; i <= n_lines; i++) { type = Vect_read_line(In, Points, NULL, i); - if (type & GV_LINES) + if (varray && !varray->c[i]) + continue; + if (type & GV_LINE) n_points += Points->n_points; }; @@ -83,7 +75,7 @@ pindex = 0; for (i = 1; i <= n_lines; i++) { type = Vect_read_line(In, Points, NULL, i); - if (!(type & GV_LINES)) + if (type != GV_LINE || (varray && !varray->c[i])) continue; for (j = 0; j < Points->n_points; j++) { int q, findex; @@ -280,7 +272,7 @@ index = 0; for (i = 1; i <= n_lines; i++) { int type = Vect_read_line(In, Points, Cats, i); - if (!(type & GV_LINES)) { + if (type != GV_LINE || (varray && !varray->c[i])) { Vect_write_line(Out, type, Points, Cats); continue; }; Modified: trunk/grassaddons/v.generalize/main.c =================================================================== --- trunk/grassaddons/v.generalize/main.c 2007-07-24 21:32:00 UTC (rev 979) +++ trunk/grassaddons/v.generalize/main.c 2007-07-26 08:48:56 UTC (rev 980) @@ -319,8 +319,10 @@ G_warning(_("Problem loading category values")); }; } - else + else { chcat = 0; + varray = NULL; + }; Vect_copy_head_data(&In, &Out); @@ -331,7 +333,7 @@ if (method == DISPLACEMENT) { snakes_displacement(&In, &Out, thresh, alfa, beta, 1.0, 10.0, - iterations); + iterations, varray); }; /* TODO: rearrange code below. It's really messy */ @@ -350,7 +352,7 @@ (type = Vect_read_next_line(&In, Points, Cats)) > 0) { i++; G_percent(i, n_lines, 1); - if (type == GV_CENTROID && !(mask_type & GV_BOUNDARY)) + if (type == GV_CENTROID && (mask_type & GV_BOUNDARY)) continue; /* skip old centroids, * we calculate new if we generalize boundarie */ total_input += Points->n_points; @@ -434,7 +436,7 @@ * We need to calculate them only if the boundaries * were generalized */ - if (mask_type & GV_BOUNDARY) { + if ((mask_type & GV_BOUNDARY) && method != DISPLACEMENT) { Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES, NULL); n_areas = Vect_get_num_areas(&Out); for (i = 1; i <= n_areas; i++) { Modified: trunk/grassaddons/v.generalize/network.c =================================================================== --- trunk/grassaddons/v.generalize/network.c 2007-07-24 21:32:00 UTC (rev 979) +++ trunk/grassaddons/v.generalize/network.c 2007-07-26 08:48:56 UTC (rev 980) @@ -230,9 +230,9 @@ Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); for (i = 1; i < g.vertices; i++) { - if (g.degree[i] >= degree_thresh && - (comp[i] - 1.0) / closeness[i] >= closeness_thresh && - betweeness[i] >= betweeness_thresh) { + if ((g.degree[i] >= degree_thresh && + (comp[i] - 1.0) / closeness[i] >= closeness_thresh && + betweeness[i] >= betweeness_thresh)) { type = Vect_read_line(In, Points, Cats, i); output += Points->n_points; Vect_write_line(Out, type, Points, Cats); From neteler at grass.itc.it Thu Jul 26 12:12:36 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Thu Jul 26 12:12:37 2007 Subject: [grass-addons] r981 - trunk/grassaddons Message-ID: <200707261012.l6QACanq002143@grass.itc.it> Author: neteler Date: 2007-07-26 12:12:36 +0200 (Thu, 26 Jul 2007) New Revision: 981 Modified: trunk/grassaddons/contributors.csv Log: +Laura Toma Modified: trunk/grassaddons/contributors.csv =================================================================== --- trunk/grassaddons/contributors.csv 2007-07-26 08:48:56 UTC (rev 980) +++ trunk/grassaddons/contributors.csv 2007-07-26 10:12:36 UTC (rev 981) @@ -11,4 +11,5 @@ maldacker,Maximilian Maldacker neteler,Markus Neteler -------,E. Jorge Tizado +toma,Laura Toma ullah,Isaac Ullah From cannata at grass.itc.it Thu Jul 26 12:47:35 2007 From: cannata at grass.itc.it (cannata@grass.itc.it) Date: Thu Jul 26 12:47:36 2007 Subject: [grass-addons] r982 - in trunk/grassaddons/HydroFOSS: . r.evapo.PM Message-ID: <200707261047.l6QAlZat002275@grass.itc.it> Author: cannata Date: 2007-07-26 12:47:31 +0200 (Thu, 26 Jul 2007) New Revision: 982 Modified: trunk/grassaddons/HydroFOSS/Makefile trunk/grassaddons/HydroFOSS/r.evapo.PM/Makefile trunk/grassaddons/HydroFOSS/r.evapo.PM/local_proto.h Log: added new command r.snow Modified: trunk/grassaddons/HydroFOSS/Makefile =================================================================== --- trunk/grassaddons/HydroFOSS/Makefile 2007-07-26 10:12:36 UTC (rev 981) +++ trunk/grassaddons/HydroFOSS/Makefile 2007-07-26 10:47:31 UTC (rev 982) @@ -1,9 +1,10 @@ -MODULE_TOPDIR = .. +MODULE_TOPDIR = ../.. include $(MODULE_TOPDIR)/include/Make/Dir.make SUBDIRS = \ r.evapo.PM \ + r.snow \ default: subdirs Modified: trunk/grassaddons/HydroFOSS/r.evapo.PM/Makefile =================================================================== --- trunk/grassaddons/HydroFOSS/r.evapo.PM/Makefile 2007-07-26 10:12:36 UTC (rev 981) +++ trunk/grassaddons/HydroFOSS/r.evapo.PM/Makefile 2007-07-26 10:47:31 UTC (rev 982) @@ -1,4 +1,4 @@ -MODULE_TOPDIR = ../.. +MODULE_TOPDIR = ../../.. PGM = r.evapo.PM Modified: trunk/grassaddons/HydroFOSS/r.evapo.PM/local_proto.h =================================================================== --- trunk/grassaddons/HydroFOSS/r.evapo.PM/local_proto.h 2007-07-26 10:12:36 UTC (rev 981) +++ trunk/grassaddons/HydroFOSS/r.evapo.PM/local_proto.h 2007-07-26 10:47:31 UTC (rev 982) @@ -5,4 +5,4 @@ DCELL calc_Ea (DCELL Eo,DCELL RH); DCELL calc_G (DCELL Rn, int t); DCELL calc_ETp (DCELL T,DCELL Z,DCELL u2,DCELL Rn,int day,DCELL Rh,DCELL hc); -DCELL calc_openwaterETp (DCELL T,DCELL Z,DCELL u2,DCELL Rn,int day,DCELL Rh,DCELL hc); +DCELL calc_openwaterETp (DCELL T,DCELL Z,DCELL u2,DCELL Rn,int day,DCELL Rh,DCELL hc); From cannata at grass.itc.it Thu Jul 26 12:49:50 2007 From: cannata at grass.itc.it (cannata@grass.itc.it) Date: Thu Jul 26 12:49:52 2007 Subject: [grass-addons] r983 - in trunk/grassaddons/HydroFOSS: . r.snow Message-ID: <200707261049.l6QAnog7002315@grass.itc.it> Author: cannata Date: 2007-07-26 12:49:46 +0200 (Thu, 26 Jul 2007) New Revision: 983 Added: trunk/grassaddons/HydroFOSS/r.snow/ trunk/grassaddons/HydroFOSS/r.snow/Makefile trunk/grassaddons/HydroFOSS/r.snow/description.html trunk/grassaddons/HydroFOSS/r.snow/main.c Log: added new command r.snow Added: trunk/grassaddons/HydroFOSS/r.snow/Makefile =================================================================== --- trunk/grassaddons/HydroFOSS/r.snow/Makefile (rev 0) +++ trunk/grassaddons/HydroFOSS/r.snow/Makefile 2007-07-26 10:49:46 UTC (rev 983) @@ -0,0 +1,10 @@ +MODULE_TOPDIR = ../../.. + +PGM = r.snow + +LIBES = $(GISLIB) +DEPENDENCIES= $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +default: cmd Property changes on: trunk/grassaddons/HydroFOSS/r.snow/Makefile ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/HydroFOSS/r.snow/description.html =================================================================== --- trunk/grassaddons/HydroFOSS/r.snow/description.html (rev 0) +++ trunk/grassaddons/HydroFOSS/r.snow/description.html 2007-07-26 10:49:46 UTC (rev 983) @@ -0,0 +1,151 @@ + + + +r.snow + + + + + +GRASS logo
      + +

      NAME

      r.snow +- computation of the snowpack water equivalent, +the snowamelt and the snowpack energy content. + +

      (GRASS Raster Program) + +

      SYNOPSIS

      +r.snow
      +r.snow help
      +r.snow +temp=name +RAD=name +rain=name +in_snow=name +in_energy=name +out_snow=name +out_energy=name +out_snowmelt=name + +

      DESCRIPTION

      + +

      r.snow +given the temperature (temp) [°C], the radiation (RAD) [W/(m^2*t)], +the rain (rain) [mm/t], the initial snowpack water content (in_snow) [mm] and +the initial snowpack energy content (in_energy) [Kcal/m^2] calculates the +snowpack water equivalent (out_snow) [mm], the snowpack energy content +(out_energy) [Kcal/m^2], and the snowmelt (out_snowmelt) [mm/t] at +the end of the timestep t. + + +

      This algorithm has been developed following the SHE model approach +with some modification.
      + +

      For more details on the algorithms see the references. + + +

      OPTIONS

      + +The program will run non-interactively if the user specifies program +arguments settings on the command line using the following +form:
      + +r.snow +temp=name +RAD=name +rain=name +in_snow=name +in_energy=name +out_snow=name +out_energy=name +out_snowmelt=name + + + +

      Alternatively, the user can simply type r.snow on the +command line and the program will ask for parameter values +settings interactively, using the standard GRASS parser interface. + +

      Parameters:

      +
      +
      temp=name +
      Input: temperature raster map [°C]. Required.
      + +
      RAD=name +
      Input: global radiation raster map [W/(m^2*t)]. Required.
      + +
      rain =name +
      Input: rainfall raster map [mm/t]. Required.
      + +
      in_snow =name +
      Input: initial snowpack water content raster map [mm]. Required.
      + +
      in_energy =name +
      Input: initial snowpack energy content raster map [Kcal/m^2]. Required.
      + +
      out_snow =name +
      Output: final snowpack water content raster map [mm]. Required.
      + +
      out_energy =name +
      Output: final snowpack energy content raster map [Kcal/m^2]. Required.
      + +
      out_snowmelt =name +
      Output: snowmelt raster map [mm/t]. Required.
      + +
      + + +

      NOTES

      + +

      The algorithm basically estimates the needed energy to maintain the snowpack +in a solid phase (in a zero snowmelt hypothesis). If the available energy is +enough to melt part of the snowpack then the snow is melted and the enrgy is +depleted, otherwise no melting occurs the enrgy remain available in the +snowpack for further step. + + +

      SEE ALSO

      +
        +
      • The HydroFOSS +project at IST-SUPSI (Institute of Earth Sciences - University school of applied science for the Southern Switzerland) + +
      • h.evapo.PM, + r.sun. +
      + + + +

      AUTHORS

      + +

      Original version of program: The HydroFOSS project, 2006, IST-SUPSI. +
      Massimiliano Cannata, + Istituto Scienze della Terra - Scuola Universitaria Professionale della Svizzera Italiana +
      Maria A. Brovelli, Politecnico di Milano - Polo regionale di Como
      + +

      Contact: Massimiliano Cannata + + +

      REFERENCES

      + +

      Cannata M., 2006. + A GIS embedded approach for Free & Open Source Hydrological Modelling. + PhD dissertation in Geodesy and Geomatic engineering, Politecnico di Milano. + +

      Abbott, M. et al., 1986a, An introduction to the European Hydrological + System – Système Hydrologique Européen, SHE; 1. History and philosophy of + a physically based distributed modeling system, Journal of Hydrology, + Vol. 87, 45-59. + +

      Abbott, M. et al., 1986b, Physically based distributed modelling of an + upland catchment using the Système Hydrologique Européen, Journal of + Hydrology, Vol. 87, 79-102. + +

      Tarboton, D. G. and C. H. Luce, 1996. Utah Energy Balance Snow Accumulation + and Melt Model (UEB): Computer model technical description and user’s guide, + Utah Water Research Laboratory and USDA Forest Service Intermountain Research + Station. + +

      Last changed: $Date: 2005/11/15 08:14:53 $ + + Property changes on: trunk/grassaddons/HydroFOSS/r.snow/description.html ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/HydroFOSS/r.snow/main.c =================================================================== --- trunk/grassaddons/HydroFOSS/r.snow/main.c (rev 0) +++ trunk/grassaddons/HydroFOSS/r.snow/main.c 2007-07-26 10:49:46 UTC (rev 983) @@ -0,0 +1,333 @@ +/***************************************************************************** +* +* MODULE: r.snow +* +* AUTHOR: Massimiliano Cannata - massimiliano.cannata[]supsi.ch (2005) +* +* PURPOSE: Estimate the snowpack water equivalent, +* the snowamelt and the snowpack energy with a modified +* SHE model approach. +* +* COPYRIGHT: (C) 2006 by Istituto Scienze della Terra +* +* This program is free software under the GNU General Public +* Licence (>=2). Read the file COPYING that cames with GRASS +* for details. +* +/***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) + +#define Tr 3 /* °C */ +#define Tb -1 /* °C */ +#define Cs 2.09 /* KJ*Kg¯¹*°C-¹*/ +#define rhoW 1000 /* Kg*m¯³ */ +#define hf 333.5 /* KJ*Kg¯¹ */ +#define cW 4.18 /* [KJ*Kg¯¹*°C¯¹] */ +#define cs 0.5 /* ice heat capacity [Kcal*Kg¯¹*°K¯¹]*/ +#define cf 79.6 /* [Kcal*Kg¯¹] */ +#define T0 273.15 /* [°K] */ + + +int main(int argc, char *argv[]){ + + struct Cell_head cellhd; + + /* input-output raster files */ + int infd_TEMP,infd_RAD,infd_RAIN,infd_SNOW,infd_ENERGY; + int outfd_SNOW,outfd_ENERGY,outfd_SNOWMELT; + + /* mapset name locator */ + char *mapset_TEMP,*mapset_RAD,*mapset_RAIN,*mapset_SNOW,*mapset_ENERGY; + + /* buffer for input-output raster */ + DCELL *inrast_TEMP; /* temperature map [°C]*/ + DCELL *inrast_RAD; /* radiation map with rigth albedo! [W/m²]*/ + DCELL *inrast_RAIN; /* precipitation intensity map [mm/h] */ + DCELL *inrast_SNOW; /* snowpack heigth at previous step [mm] */ + DCELL *inrast_ENERGY; /* energy at previous step [Kcal*m¯²*h¯¹] */ + DCELL *outrast_SNOW; /* snowpack heigth at previous step [mm] */ + DCELL *outrast_ENERGY; /* energy at previous step [Kcal*m¯²*h¯¹] */ + DCELL *outrast_SNOWMELT; /* snowmelt for the current timestep */ + + /* cell values */ + DCELL d_TEMP,d_RAD,d_RAIN,d_SNOW,d_ENERGY; + DCELL d_SNOWt,d_ENERGYt,d_SNOWMELT; + + double Pr=0, Ps=0; + double E0,Qp,Z0,En; + + /* cell counters */ + int nrows, ncols; + int row, col; + + /* variables to handle user inputs */ + char *TEMP,*RAD, *RAIN, *SNOW, *ENERGY, *SNOWt, *ENERGYt, *SNOWMELT; + + /* GRASS structure */ + struct GModule *module; + struct Option *input_TEMP, *input_RAD, *input_RAIN, *input_SNOW, *input_ENERGY; + struct Option *output_SNOW, *output_ENERGY, *output_SNOWMELT; + + G_gisinit(argv[0]); + + module = G_define_module(); + module->description = + "Snowmelt and Accumulation Model along a timestep t"; + + /* Define different options */ + input_TEMP = G_define_option(); + input_TEMP->key = "temp"; + input_TEMP->type = TYPE_STRING; + input_TEMP->required = YES; + input_TEMP->gisprompt = "old,cell,raster"; + input_TEMP->description = _("Name of temperature raster map in [°C]"); + + input_RAD = G_define_option(); + input_RAD->key = "RAD"; + input_RAD->type = TYPE_STRING; + input_RAD->required = YES; + input_RAD->gisprompt = "old,cell,raster"; + input_RAD->description = _("Name of net solar radiation raster map in [W*m¯²*t¯¹]"); + + input_RAIN = G_define_option(); + input_RAIN->key = "rain"; + input_RAIN->type = TYPE_STRING; + input_RAIN->required = YES; + input_RAIN->gisprompt = "old,cell,raster"; + input_RAIN->description = _("Name of rain intensity raster map in [mm*t¯¹]"); + + input_SNOW = G_define_option(); + input_SNOW->key = "in_snow"; + input_SNOW->type = TYPE_STRING; + input_SNOW->required = YES; + input_SNOW->gisprompt = "old,cell,raster"; + input_SNOW->description = _("Name of snow width raster map in [mm] of water equivalent"); + + input_ENERGY = G_define_option(); + input_ENERGY->key = "in_energy"; + input_ENERGY->type = TYPE_STRING; + input_ENERGY->required = YES; + input_ENERGY->gisprompt = "old,cell,raster"; + input_ENERGY->description = _("Name of snow energy raster map in [Kcal*m¯²*t¯¹]"); + + output_SNOW = G_define_option() ; + output_SNOW->key = "out_snow"; + output_SNOW->type = TYPE_STRING; + output_SNOW->required = YES; + output_SNOW->gisprompt = "new,cell,raster" ; + output_SNOW->description= _("Name of output snow width raster map in [mm] of water equivalent"); + + output_ENERGY = G_define_option() ; + output_ENERGY->key = "out_energy"; + output_ENERGY->type = TYPE_STRING; + output_ENERGY->required = YES; + output_ENERGY->gisprompt = "new,cell,raster" ; + output_ENERGY->description= _("Name of output snow energy raster map in [Kcal*m¯²*t¯¹]"); + + output_SNOWMELT = G_define_option() ; + output_SNOWMELT->key = "out_snowmelt"; + output_SNOWMELT->type = TYPE_STRING; + output_SNOWMELT->required = YES; + output_SNOWMELT->gisprompt = "new,cell,raster" ; + output_SNOWMELT->description= _("Name of output snowmelt raster map in [mm*t¯¹]"); + + if (G_parser(argc, argv)) + exit (-1); + + /* get entered parameters */ + TEMP=input_TEMP->answer; + RAD=input_RAD->answer; + RAIN=input_RAIN->answer; + SNOW=input_SNOW->answer; + ENERGY=input_ENERGY->answer; + SNOWt=output_SNOW->answer; + ENERGYt=output_ENERGY->answer; + SNOWMELT=output_SNOWMELT->answer; + + /* find maps in mapset */ + mapset_TEMP = G_find_cell2 (TEMP, ""); + if (mapset_TEMP == NULL) + G_fatal_error (_("cell file [%s] not found"), TEMP); + mapset_RAD = G_find_cell2 (RAD, ""); + if (mapset_RAD == NULL) + G_fatal_error (_("cell file [%s] not found"), RAD); + mapset_RAIN = G_find_cell2 (RAIN, ""); + if (mapset_RAIN == NULL) + G_fatal_error (_("cell file [%s] not found"), RAIN); + mapset_SNOW = G_find_cell2 (SNOW, ""); + if (mapset_SNOW == NULL) + G_fatal_error (_("cell file [%s] not found"), SNOW); + mapset_ENERGY = G_find_cell2 (ENERGY, ""); + if (mapset_ENERGY == NULL) + G_fatal_error (_("cell file [%s] not found"), ENERGY); + + /* check legal output name */ + if (G_legal_filename (ENERGYt) < 0) + G_fatal_error (_("[%s] is an illegal name"), ENERGYt); + if (G_legal_filename (SNOWt) < 0) + G_fatal_error (_("[%s] is an illegal name"), SNOWt); + if (G_legal_filename (SNOWMELT) < 0) + G_fatal_error (_("[%s] is an illegal name"), SNOWMELT); + + /* open input raster files */ + if ( (infd_TEMP = G_open_cell_old (TEMP, mapset_TEMP)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), TEMP); + if ( (infd_RAD = G_open_cell_old (RAD, mapset_RAD)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),RAD); + if ( (infd_RAIN = G_open_cell_old (RAIN, mapset_RAIN)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),RAIN); + if ( (infd_SNOW = G_open_cell_old (SNOW, mapset_SNOW)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),SNOW); + if ( (infd_ENERGY = G_open_cell_old (ENERGY, mapset_ENERGY)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),ENERGY); + + if (G_get_cellhd (TEMP, mapset_TEMP, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), TEMP); + if (G_get_cellhd (RAD, mapset_RAD, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), RAD); + if (G_get_cellhd (RAIN, mapset_RAIN, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), RAIN); + if (G_get_cellhd (SNOW, mapset_SNOW, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), SNOW); + if (G_get_cellhd (ENERGY, mapset_ENERGY, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), ENERGY); + + /* open output raster */ + if ( (outfd_SNOW = G_open_raster_new (SNOWt,DCELL_TYPE)) < 0) + G_fatal_error (_("Could not open <%s>"),SNOWt); + if ( (outfd_ENERGY = G_open_raster_new (ENERGYt,DCELL_TYPE)) < 0) + G_fatal_error (_("Could not open <%s>"),ENERGYt); + if ( (outfd_SNOWMELT = G_open_raster_new (SNOWMELT,DCELL_TYPE)) < 0) + G_fatal_error (_("Could not open <%s>"),SNOWMELT); + + + /* Allocate input buffer */ + inrast_TEMP = G_allocate_d_raster_buf(); + inrast_RAD = G_allocate_d_raster_buf(); + inrast_RAIN = G_allocate_d_raster_buf(); + inrast_SNOW = G_allocate_d_raster_buf(); + inrast_ENERGY = G_allocate_d_raster_buf(); + + /* Allocate output buffer */ + outrast_SNOW = G_allocate_d_raster_buf(); + outrast_ENERGY = G_allocate_d_raster_buf(); + outrast_SNOWMELT = G_allocate_d_raster_buf(); + + /* get windows rows & cols */ + nrows = G_window_rows(); + ncols = G_window_cols(); + + for (row = 0; row < nrows; row++) + { + G_percent (row, nrows, 2); + + /* read a line input maps into buffers*/ + if (G_get_d_raster_row (infd_TEMP, inrast_TEMP, row) < 0) + G_fatal_error (_("Could not read from <%s>"),TEMP); + if (G_get_d_raster_row (infd_RAD, inrast_RAD, row) < 0) + G_fatal_error (_("Could not read from <%s>"),RAD); + if (G_get_d_raster_row (infd_RAIN, inrast_RAIN, row) < 0) + G_fatal_error (_("Could not read from <%s>"),RAIN); + if (G_get_d_raster_row (infd_SNOW, inrast_SNOW, row) < 0) + G_fatal_error (_("Could not read from <%s>"),SNOW); + if (G_get_d_raster_row (infd_ENERGY, inrast_ENERGY, row) < 0) + G_fatal_error (_("Could not read from <%s>"),ENERGY); + + /* read every cell in the line buffers */ + for (col=0; col < ncols; col++) + { + d_TEMP = ((DCELL *) inrast_TEMP)[col]; /* [°C] */ + d_RAD = ((DCELL *) inrast_RAD)[col]; /* [W/m²] */ + d_RAIN = ((DCELL *) inrast_RAIN)[col]; /* [mm] */ + d_SNOW = ((DCELL *) inrast_SNOW)[col]; /* [mm] */ + d_ENERGY = ((DCELL *) inrast_ENERGY)[col]; /* [Kcal*m¯²] */ + + + /* partition of the precipitations in rain (Pr)and snow (Ps) */ + if (d_TEMP>=Tr) + Pr = d_RAIN; + if (d_TEMPTb) + Pr = d_RAIN*(d_TEMP-Tb)/(Tr-Tb); + if (d_TEMP<=Tb) + Pr = 0; + + /* Ps = (d_RAIN-Pr)*F; it accounts for wind drift */ + Ps = (d_RAIN-Pr); /* [mm] */ + + /* water and energy estimation with zero snowmelt hypotesis */ + Z0 = d_SNOW + Ps; /* [mm] */ + Qp = 0.001*((Ps*Cs*rhoW*min(d_TEMP,0)) + (Pr*(hf*rhoW + (cW*rhoW*max(d_TEMP,0))))); /* [KJ*m¯²]*/ + E0 = d_ENERGY + (d_RAD*0.8604206501) + (Qp/4.184); /* [Kcal*m¯²] */ + En = cs*Z0*T0; + /* E0=available energy; En=energy to maintain the solid phase */ + + G_debug ( 5, _("Z0=%lf, E0=%lf, d_RAD=%lf, Qp=%lf, Pr=%lf, Ps=%lf\n"),Z0,E0,d_RAD,Qp,Pr,Ps); + + + if (Z0==0) { + d_SNOWMELT = 0; + d_SNOWt = 0; + d_ENERGYt = 0; + } + + /* estimation of output values at the end of timestep (SNOW;ENERGY;SNOMELT) */ + else if (En>=E0) { + d_SNOWMELT = 0; + d_SNOWt = Z0; + d_ENERGYt = E0; + + G_debug ( 5, _("Melt=%lf, Snow=%lf, Ener=%lf, Ps=%lf,cs*T0*Z0=%lf\n"),d_SNOWMELT,d_SNOWt,d_ENERGYt,Ps,cs*T0*Z0 ); + } + else { + d_SNOWMELT = min((E0-En)/cf,Z0); + d_SNOWt = max(0,Z0-d_SNOWMELT); + d_ENERGYt = E0 - ((cs*T0+cf)*d_SNOWMELT); + + G_debug ( 5, _("Melt=%lf, Snow=%lf, Ener=%lf, Ps=%lf,cs*T0*Z0=%lf\n"),d_SNOWMELT,d_SNOWt,d_ENERGYt,Ps,cs*T0*Z0 ); + G_debug ( 5, _("Z0=%lf, E0=%lf, d_RAD=%lf, Qp=%lf, Pr=%lf, Ps=%lf\n"),Z0,E0,d_RAD,Qp,Pr,Ps ); + } + + ((DCELL *) outrast_SNOWMELT)[col] = d_SNOWMELT; + ((DCELL *) outrast_SNOW)[col] = d_SNOWt; + ((DCELL *) outrast_ENERGY)[col] = d_ENERGYt; + + } + + if (G_put_d_raster_row (outfd_SNOW, outrast_SNOW) < 0) + G_fatal_error (_("Cannot write to <%s>"),SNOWt); + if (G_put_d_raster_row (outfd_ENERGY, outrast_ENERGY) < 0) + G_fatal_error (_("Cannot write to <%s>"),ENERGYt); + if (G_put_d_raster_row (outfd_SNOWMELT, outrast_SNOWMELT) < 0) + G_fatal_error (_("Cannot write to <%s>"),SNOWMELT); + + } +G_free(inrast_TEMP); +G_free(inrast_RAD); +G_free(inrast_RAIN); +G_free(inrast_SNOW); +G_free(inrast_ENERGY); +G_free(outrast_SNOW); +G_free(outrast_ENERGY); +G_free(outrast_SNOWMELT); + +G_close_cell (infd_TEMP); +G_close_cell (infd_RAD); +G_close_cell (infd_RAIN); +G_close_cell (infd_SNOW); +G_close_cell (infd_ENERGY); +G_close_cell (outfd_SNOW); +G_close_cell (outfd_ENERGY); +G_close_cell (outfd_SNOWMELT); + +return (0); +} Property changes on: trunk/grassaddons/HydroFOSS/r.snow/main.c ___________________________________________________________________ Name: svn:executable + * From barton at grass.itc.it Sun Jul 29 23:55:35 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Jul 29 23:55:37 2007 Subject: [grass-addons] r984 - trunk/grassaddons/gui/gui_modules Message-ID: <200707292155.l6TLtZfn028787@grass.itc.it> Author: barton Date: 2007-07-29 23:55:22 +0200 (Sun, 29 Jul 2007) New Revision: 984 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: A call to self.OnSize() in BufferedWindow init was un-commented in the latest revision. This caused render.Map.width to be set to 0 initially because OnSize was called before the map display window was created. The result was a crash on init due to division by 0. I don't know why this was uncommented, but I left it in. I moved the call to render.SetRegion to PRIOR to the OnSize call to make sure that the window was creaated before calling OnSize. This seems to have solved the crash and doesn't seem to have any adverse effects. The alternative solution would be to comment out the inital call to Onsize again. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-26 10:49:46 UTC (rev 983) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-07-29 21:55:22 UTC (rev 984) @@ -170,7 +170,7 @@ self.mapfile = None # image file to be rendered self.img = "" # wx.Image object (self.mapfile) # used in digitization tool (do not redraw vector map) - self.imgVectorMap = None + self.imgVectorMap = None self.ovldict = {} # list of images for overlays self.ovlcoords = {} # positioning coordinates for decoration overlay self.ovlchk = {} # showing/hiding decorations @@ -204,6 +204,8 @@ self.zoomtype = 1 # 1 zoom in, 0 no zoom, -1 zoom out self.hitradius = 10 # distance for selecting map decorations + self.Map.SetRegion() # make sure that extents are updated at init + # OnSize called to make sure the buffer is initialized. # This might result in OnSize getting called twice on some # platforms at initialization, but little harm done. @@ -213,7 +215,6 @@ self.pdc = wx.PseudoDC() # will store an off screen empty bitmap for saving to file self._Buffer = '' - self.Map.SetRegion() # make sure that extents are updated at init self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None) @@ -293,7 +294,7 @@ pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) pdc.SetPen(self.polypen) pdc.DrawLines(coords) - + # get bounding rectangle for polyline xlist = [] ylist = [] @@ -338,7 +339,7 @@ self.Refresh() return drawid - + def TextBounds(self, textinfo, coords): """ Return text boundary data @@ -386,13 +387,13 @@ dc.SetClippingRect(r) # draw to the dc using the calculated clipping rect self.pdc.DrawToDCClipped(dc,r) - + def OnSize(self, event): """ Scale map image so that it is the same size as the Window """ - + Debug.msg(3, "BufferedWindow.OnSize():") # set size of the input image @@ -472,7 +473,7 @@ Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s" % \ (render)) - + if render: # render new map images self.Map.width, self.Map.height = self.GetClientSize() @@ -507,7 +508,7 @@ # draw map self.imgVectorMap = self.parent.digit.driver.DrawMap() - + self.Draw(self.pdc, self.img, drawid=id) # draw map image background if self.imgVectorMap: self.Draw(self.pdc, self.imgVectorMap, drawid=100) # draw vector map image @@ -624,7 +625,7 @@ """Draw polyline in PseudoDC""" if not polycoords: # alternative coordinates polycoords = self.polycoords - + #Debug.msg (4, "BufferedWindow.DrawLines(): coords=%s" % \ # polycoords) @@ -650,7 +651,7 @@ self.Draw(self.pdc, drawid=self.lineid, pdctype='line', coords=lineCoords) return self.lineid - + def MouseActions(self, event): """ Mouse motion and button click notifier @@ -734,7 +735,7 @@ self.mouse["use"]) self.mouse['begin'] = event.GetPositionTuple()[:] - + if self.mouse["use"] in ["measure", "profile"]: # measure || profile if len(self.polycoords) == 0: @@ -750,7 +751,7 @@ digitToolbar = self.parent.digittoolbar east, north = self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]) - + try: map = digitToolbar.layers[digitToolbar.layerSelectedID].name except: @@ -760,9 +761,9 @@ dlg.ShowModal() dlg.Destroy() event.Skip() - return + return - # calculate position of 'update record' dialog + # calculate position of 'update record' dialog offset = 5 posWindow = self.ClientToScreen((self.mouse['begin'][0] + offset, self.mouse['begin'][1] + offset)) @@ -778,7 +779,7 @@ self.parent.digit.AddPoint(map=map, type=digitToolbar.type, x=east, y=north) - + # add new record into atribute table if self.parent.digit.settings["addRecord"]: # select attributes based on layer and category @@ -830,7 +831,7 @@ # highlight feature & re-draw map self.parent.digit.driver.SetSelected(updateRecordDlg.selectedLines) self.UpdateMap() - + if updateRecordDlg.ShowModal() == wx.ID_OK: sqlfile = tempfile.NamedTemporaryFile(mode="w") sqlfile.file.write(updateRecordDlg.GetSQLString()) @@ -1014,14 +1015,14 @@ _("Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() - + if map: # add new line mapcoords = [] # xy -> EN for coord in self.polycoords: mapcoords.append(self.Pixel2Cell (coord[0], coord[1])) - + self.parent.digit.AddLine(map=map, type=self.parent.digittoolbar.type, coords=mapcoords) @@ -1031,7 +1032,7 @@ offset = 5 posWindow = self.ClientToScreen((self.polycoords[-1][0] + offset, self.polycoords[-1][1] + offset)) - + # select attributes based on layer and category addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, layer=self.parent.digit.settings["layer"], @@ -1065,7 +1066,7 @@ self.parent.digit.MoveSelectedLines(move) else: # moveVertex self.parent.digit.MoveSelectedVertex(self.Pixel2Cell (self.moveCoords[0], self.moveCoords[1]),move) - + del self.moveBegin del self.moveCoords del self.moveIds @@ -1075,10 +1076,10 @@ self.parent.digit.AddVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) elif digit.action == "removeVertex": self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) - + self.parent.digit.driver.SetSelected([]) self.UpdateMap(render=False) - + event.Skip() def OnMiddleDown(self, event): @@ -1159,7 +1160,7 @@ 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"]) @@ -1405,7 +1406,7 @@ x2, y2 = endpt dEast = (x2-x1) * self.Map.region["ewres"] dNorth = (y2-y1) * self.Map.region["nsres"] - + return (math.sqrt(math.pow((dEast),2) + math.pow((dNorth),2)), (dEast, dNorth)) class MapFrame(wx.Frame): @@ -1557,7 +1558,7 @@ # Initialization of digitization tool # self.digit = Digit(mapwindow=self.MapWindow) - + def AddToolbar(self, name): """ Add defined toolbar to the window @@ -1588,7 +1589,7 @@ LeftDockable(False).RightDockable(False). BottomDockable(False).TopDockable(True). CloseButton(False).Layer(2)) - + # change mouse to draw digitized line self.MapWindow.mouse['box'] = "point" self.MapWindow.zoomtype = 0 From barton at grass.itc.it Mon Jul 30 04:53:40 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Jul 30 04:53:42 2007 Subject: [grass-addons] r985 - trunk/grassaddons/gui/gui_modules Message-ID: <200707300253.l6U2reV0000555@grass.itc.it> Author: barton Date: 2007-07-30 04:53:26 +0200 (Mon, 30 Jul 2007) New Revision: 985 Modified: trunk/grassaddons/gui/gui_modules/render.py Log: Checks for valid layer type from list of layer types before writing message that layer type not supported. Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-07-29 21:55:22 UTC (rev 984) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-07-30 02:53:26 UTC (rev 985) @@ -102,7 +102,8 @@ # # prepare command for each layer # - if self.type == "command" or self.type == "raster" or self.type == "vector" or self.type == "overlay": + layertypes = ['raster','rgb','his','vector','thememap','themechart','grid','labels','command','overlay'] + if self.type in layertypes: self.__renderLayer() elif self.type == "wms": print "Type wms is not supported yet" From cannata at grass.itc.it Mon Jul 30 19:58:10 2007 From: cannata at grass.itc.it (cannata@grass.itc.it) Date: Mon Jul 30 19:58:14 2007 Subject: [grass-addons] r986 - in trunk/grassaddons/HydroFOSS: . r.evapo.PM r.interception r.snow Message-ID: <200707301758.l6UHwAhn011668@grass.itc.it> Author: cannata Date: 2007-07-30 19:58:03 +0200 (Mon, 30 Jul 2007) New Revision: 986 Added: trunk/grassaddons/HydroFOSS/r.interception/ trunk/grassaddons/HydroFOSS/r.interception/Makefile trunk/grassaddons/HydroFOSS/r.interception/description.html trunk/grassaddons/HydroFOSS/r.interception/main.c Modified: trunk/grassaddons/HydroFOSS/Makefile trunk/grassaddons/HydroFOSS/r.evapo.PM/description.html trunk/grassaddons/HydroFOSS/r.snow/description.html trunk/grassaddons/HydroFOSS/r.snow/main.c Log: added new command r.interception and minor changes to description files Modified: trunk/grassaddons/HydroFOSS/Makefile =================================================================== --- trunk/grassaddons/HydroFOSS/Makefile 2007-07-30 02:53:26 UTC (rev 985) +++ trunk/grassaddons/HydroFOSS/Makefile 2007-07-30 17:58:03 UTC (rev 986) @@ -5,6 +5,7 @@ SUBDIRS = \ r.evapo.PM \ r.snow \ + r.interception \ default: subdirs Modified: trunk/grassaddons/HydroFOSS/r.evapo.PM/description.html =================================================================== --- trunk/grassaddons/HydroFOSS/r.evapo.PM/description.html 2007-07-30 02:53:26 UTC (rev 985) +++ trunk/grassaddons/HydroFOSS/r.evapo.PM/description.html 2007-07-30 17:58:03 UTC (rev 986) @@ -141,8 +141,7 @@

      AUTHORS

      -

      Original version of program: The HydroFOSS - project, 2006, IST-SUPSI. (http://istgis.ist.supsi.ch:8001/geomatica/index.php?id=1) +

      Original version of program: The HydroFOSS project, 2006, IST-SUPSI. (http://istgis.ist.supsi.ch:8001/geomatica/index.php?id=1)
      Massimiliano Cannata, Scuola Universitaria Professionale della Svizzera Italiana - Istituto Scienze della Terra
      Maria A. Brovelli, Politecnico di Milano - Polo regionale di Como @@ -154,8 +153,7 @@

      REFERENCES

      [1] Cannata M., 2006. - GIS embedded approach for Free & Open Source Hydrological Modelling. PhD thesis, Department of Geodesy and - Geomatics, Polytechnic of Milan, Italy. + GIS embedded approach for Free & Open Source Hydrological Modelling. PhD thesis, Department of Geodesy and Geomatics, Polytechnic of Milan, Italy.

      [2] Allen, R.G., L.S. Pereira, D. Raes, and M. Smith. 1998. Crop Evapotranspiration: Guidelines for computing crop water requirements. @@ -164,6 +162,6 @@

      [3] Penman, H. L. 1948. Natural evaporation from open water, bare soil and grass. Proc. Roy. Soc. London, A193, pp. 120-146. -

      Last changed: $Date: 2007/04/27 12:14:53 $ +

      Last changed: $Date: 2007/07/29 19:30:00 $ Added: trunk/grassaddons/HydroFOSS/r.interception/Makefile =================================================================== --- trunk/grassaddons/HydroFOSS/r.interception/Makefile (rev 0) +++ trunk/grassaddons/HydroFOSS/r.interception/Makefile 2007-07-30 17:58:03 UTC (rev 986) @@ -0,0 +1,10 @@ +MODULE_TOPDIR = ../../.. + +PGM = r.interception + +LIBES = $(GISLIB) +DEPENDENCIES= $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +default: cmd Property changes on: trunk/grassaddons/HydroFOSS/r.interception/Makefile ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/HydroFOSS/r.interception/description.html =================================================================== --- trunk/grassaddons/HydroFOSS/r.interception/description.html (rev 0) +++ trunk/grassaddons/HydroFOSS/r.interception/description.html 2007-07-30 17:58:03 UTC (rev 986) @@ -0,0 +1,152 @@ + + + +h.interception + + + + + +GRASS logo


      + +

      NAME

      h.interception +- computation of the water loss, drainage, and storage due +to canopy rainfall interception. + +

      (GRASS Raster Program) + +

      SYNOPSIS

      +h.interception
      +h.interception help
      +h.interception +LAI=name +ETPls=name +Co=name +R=name +[Ts=name] +Vc=name +IL=name +D=name +Ct=name + +

      DESCRIPTION

      + +

      h.interception +given the LAI [-], the ETPls [mm/h], the leaf storage level at +the previous step Co [mm], the rain R [mm/h], the timestep Ts [h], +and the vegetation density Vc [%] the command estimates the interception +losses IL [mm], the drainage D [mm] and the canopy storage level at +the end of the step Ct [mm]. + +

      This algorithm is a modification of the Rutter model +in order to take into account the temporal variability of the rainfall.
      + +

      For more details on the algorithms see the references. + + +

      OPTIONS

      + +The program will run non-interactively if the user specifies program +arguments settings on the command line using the following +form:
      + +h.interception +LAI=name +ETPls=name +Co=name +R=name +[Ts=name] +Vc=name +IL=name +D=name +Ct=name + + + +

      Alternatively, the user can simply type h.interception on the +command line and the program will ask for parameter values +settings interactively, using the standard GRASS parser interface. + +

      Parameters:

      +
      +
      LAI=name +
      Input: Leaf Area Index raster map [-]. Required.
      + +
      ETPls=name +
      Input: Potential Evapotranspiration for a liquid surface raster map [mm/h]. Required.
      + +
      Co =name +
      Input: initial canopy storage level raster map [mm]. Required.
      + +
      R =name +
      Input: rainfall intensity raster map [mm/h]. Required.
      + +
      Ts =name +
      Input: camputational time step value [h]. Optional (default 1).
      + +
      Vc =name +
      Input: vegetatin cover raster map [%]. Required.
      + +
      IL =name +
      Output: estimated interception losses raster map [mm]. Required.
      + +
      D =name +
      Output: estimated drained water raster map [mm]. Required.
      + +
      Ct =name +
      Output: estimated canopy storage level raster map [mm] at the end of the timestep. Required.
      + +
      + + +

      NOTES

      + +

      The estimated D raster map (water drained from the vegetation to the groud) +is calculated for each cell on the basis of the vegetation cover fraction. +In order to evaluate the total water reaching the groud, and therefore +available for runoff and infiltration, this quantity should be sommed to +the rain directly falling to the ground, and eventually to the water +caming from the snowmelt. + +

      The sum of these three components outputted can be calculated by means + of teh r.mapcalc command. +

      example: +
      r.mapcalc 'NETrain = D + (1-Vc)*R + snowmelt'; + + +

      SEE ALSO

      +
        +
      • The HydroFOSS +project at IST-SUPSI (Institute of Earth Sciences - University school of applied science for the Southern Switzerland) + +
      • r.evapo.PM, + r.mapcal, + r.snow. +
      + + + +

      AUTHORS

      + +

      Original version of program: The HydroFOSS project, 2006, IST-SUPSI. (http://istgis.ist.supsi.ch:8001/geomatica/index.php?id=1) + +
      Massimiliano Cannata, Scuola Universitaria Professionale della Svizzera Italiana - Istituto Scienze della Terra +
      Maria A. Brovelli, Politecnico di Milano - Polo regionale di Como +
      + +

      Contact: Massimiliano Cannata + + + +

      REFERENCES

      + +

      [1] Cannata M., 2006. + GIS embedded approach for Free & Open Source Hydrological Modelling. PhD thesis, Department of Geodesy and Geomatics, Polytechnic of Milan, Italy. + +

      Zeng, N., JW Shuttleworth, and J. Gash, 2000. + Influence of temporal variability of rainfall on interception loss. + J. of Hydrology, 228 3-4, 228-241. + +

      Last changed: $Date: 2007/07/29 19:30:00 $ + + Property changes on: trunk/grassaddons/HydroFOSS/r.interception/description.html ___________________________________________________________________ Name: svn:executable + * Added: trunk/grassaddons/HydroFOSS/r.interception/main.c =================================================================== --- trunk/grassaddons/HydroFOSS/r.interception/main.c (rev 0) +++ trunk/grassaddons/HydroFOSS/r.interception/main.c 2007-07-30 17:58:03 UTC (rev 986) @@ -0,0 +1,453 @@ +/***************************************************************************** +* +* MODULE: h.interception +* +* AUTHOR: Massimiliano Cannata - massimiliano.cannata@supsi.ch (2005) +* +* PURPOSE: To estimate the water loss, drainage, and storage due +* to canopy rainfall interception. +* +* COPYRIGHT: (C) 2006 by Istituto Scienze della Terra (www.ist.supsi.ch) +* +* This program is free software under the GNU General Public +* Licence (>=2). Read the file COPYING that cames with GRASS +* for details. +* +/***************************************************************************/ + +#include +#include +#include +#include +#include + +static float maxarg1,maxarg2; +#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\ + (maxarg1) : (maxarg2)) + +static float minarg1,minarg2; +#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\ + (minarg1) : (minarg2)) + +int main(int argc, char *argv[]){ + + /* region informations and handler */ + struct Cell_head cellhd; + int nrows, ncols; + int row, col; + + /* buffer for in out raster */ + DCELL *inrast_LAI,*inrast_Eo,*inrast_Wo,*inrast_R,*inrast_F,*outrast,*outrast_D,*outrast_Wt; + unsigned char *IntLoss, *Drainage, *Wt; + + /* pointers to input-output raster files */ + int infd_LAI,infd_Eo,infd_Wo,infd_R,infd_F; + int outfd, outfd_D, outfd_Wt; + + /* mapsets for input raster files */ + char *mapset_LAI,*mapset_Eo,*mapset_Wo,*mapset_R,*mapset_F; + + /* names of input-output raster files */ + char *LAI, *Eo, *Wo, *R, *F; + + int err=0; + + /* input-output cell values */ + DCELL d_LAI,d_Eo,d_Wo,d_R,d_Wc,d_tao,dt,d_F,i_sat,d_Wr; + DCELL d_Ts; //timestep + DCELL d_IntLoss, d_Drainage, d_Wt; + + /* parser stuctures definition */ + struct GModule *module; + struct Option *input_LAI,*input_Eo,*input_Wo,*input_R,*input_F,*output,*output_D,*output_Wt,*timestep; + +/*-TO DO: INSERIRE TIMESTEP IN ORE-*/ + + /* Initialize the GIS calls */ + G_gisinit(argv[0]); + + module = G_define_module(); + module->description = + _("Interception module for a single time step with constant rain intensity"); + + /* Define different options */ + input_LAI = G_define_option(); + input_LAI->key = "LAI"; + input_LAI->type = TYPE_STRING; + input_LAI->required = YES; + input_LAI->gisprompt = "old,cell,raster"; + input_LAI->description = _("Name of LAI raster map"); + + input_Eo = G_define_option(); + input_Eo->key = "ETPls"; + input_Eo->type = TYPE_STRING; + input_Eo->required = YES; + input_Eo->gisprompt = "old,cell,raster"; + input_Eo->description = _("Name of Potential Evaporation raster map"); + + input_Wo = G_define_option(); + input_Wo->key = "Co"; + input_Wo->type = TYPE_STRING; + input_Wo->required = YES; + input_Wo->gisprompt = "old,cell,raster"; + input_Wo->description = _("Name of Initial Canopy Storage Level raster map"); + + input_R = G_define_option(); + input_R->key = "R"; + input_R->type = TYPE_STRING; + input_R->required = YES; + input_R->gisprompt = "old,cell,raster"; + input_R->description = _("Name of Rain raster map"); + + input_F = G_define_option(); + input_F->key = "Vc"; + input_F->type = TYPE_STRING; + input_F->required = YES; + input_F->gisprompt = "old,cell,raster"; + input_F->description = _("Name of the fraction of vegetated area raster map"); + + timestep = G_define_option(); + timestep->key = "Ts"; + timestep->type = TYPE_STRING; + timestep->required= NO; + timestep->description= _("timestep"); + timestep->answer= "1"; + + output = G_define_option() ; + output->key = "IL"; + output->type = TYPE_STRING; + output->required = YES; + output->gisprompt = "new,cell,raster" ; + output->description= _("Name of output Interception Loss raster map"); + + output_D = G_define_option() ; + output_D->key = "D"; + output_D->type = TYPE_STRING; + output_D->required = YES; + output_D->gisprompt = "new,cell,raster" ; + output_D->description= _("Name of output Drainage raster map"); + + output_Wt = G_define_option() ; + output_Wt->key = "Ct"; + output_Wt->type = TYPE_STRING; + output_Wt->required = YES; + output_Wt->gisprompt = "new,cell,raster" ; + output_Wt->description= _("Name of output Final Canopy Storage Level raster map"); + +if (G_parser(argc, argv)) + exit(EXIT_FAILURE); + + /* get entered parameters */ + LAI=input_LAI->answer; + Eo=input_Eo->answer; + Wo=input_Wo->answer; + R=input_R->answer; + F=input_F->answer; + IntLoss=output->answer; + Drainage=output_D->answer; + d_Ts=atof(timestep->answer); + Wt=output_Wt->answer; + + /* find maps in mapset */ + mapset_LAI = G_find_cell2 (LAI, ""); + if (mapset_LAI == NULL) + G_fatal_error (_("cell file [%s] not found"), LAI); + mapset_Eo = G_find_cell2 (Eo, ""); + if (mapset_Eo == NULL) + G_fatal_error (_("cell file [%s] not found"), Eo); + mapset_Wo = G_find_cell2 (Wo, ""); + if (mapset_Wo == NULL) + G_fatal_error (_("cell file [%s] not found"), Wo); + mapset_R = G_find_cell2 (R, ""); + if (mapset_R == NULL) + G_fatal_error (_("cell file [%s] not found"), R); + mapset_F = G_find_cell2 (F, ""); + if (mapset_F == NULL) + G_fatal_error (_("cell file [%s] not found"), F); + + /* check legal outputs name */ + if (G_legal_filename (IntLoss) < 0) + G_fatal_error (_("[%s] is an illegal name"), IntLoss); + if (G_legal_filename (Drainage) < 0) + G_fatal_error (_("[%s] is an illegal name"), Drainage); + if (G_legal_filename (Wt) < 0) + G_fatal_error (_("[%s] is an illegal name"), Wt); + + /* open input map (DCELL) */ + if ( (infd_LAI = G_open_cell_old (LAI, mapset_LAI)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), LAI); + if ( (infd_Eo = G_open_cell_old (Eo, mapset_Eo)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),Eo); + if ( (infd_Wo = G_open_cell_old (Wo, mapset_Wo)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),Wo); + if ( (infd_R = G_open_cell_old (R, mapset_R)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),R); + if ( (infd_F = G_open_cell_old (F, mapset_F)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"),F); + + /* read header of the input map */ + if (G_get_cellhd (LAI, mapset_LAI, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), LAI); + if (G_get_cellhd (Eo, mapset_Eo, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), Eo); + if (G_get_cellhd (Wo, mapset_Wo, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), Wo); + if (G_get_cellhd (R, mapset_R, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), R); + if (G_get_cellhd (F, mapset_F, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s]"), F); + + /* Allocate input buffer */ + inrast_LAI = G_allocate_d_raster_buf(); + inrast_Eo = G_allocate_d_raster_buf(); + inrast_Wo = G_allocate_d_raster_buf(); + inrast_R = G_allocate_d_raster_buf(); + inrast_F = G_allocate_d_raster_buf(); + + /* Allocate output buffer */ + outrast = G_allocate_d_raster_buf(); + outrast_D = G_allocate_d_raster_buf(); + outrast_Wt = G_allocate_d_raster_buf(); + + /* open output map (DCELL) */ + if ( (outfd = G_open_raster_new (IntLoss,DCELL_TYPE)) < 0) + G_fatal_error (_("Could not open <%s>"),IntLoss); + if ( (outfd_D = G_open_raster_new (Drainage,DCELL_TYPE)) < 0) + G_fatal_error (_("Could not open <%s>"),Drainage); + if ( (outfd_Wt = G_open_raster_new (Wt,DCELL_TYPE)) < 0) + G_fatal_error (_("Could not open <%s>"),Wt); + + /* get rows & colums number of the active region*/ + nrows = G_window_rows(); + ncols = G_window_cols(); + + /* loop along all the rows of the region*/ + for (row = 0; row < nrows; row++) + { + + /* read a line input maps into buffers*/ + if (G_get_d_raster_row (infd_LAI, inrast_LAI, row) < 0) + G_fatal_error (_("Could not read from <%s>"),LAI); + if (G_get_d_raster_row (infd_Eo, inrast_Eo, row) < 0) + G_fatal_error (_("Could not read from <%s>"),Eo); + if (G_get_d_raster_row (infd_Wo, inrast_Wo, row) < 0) + G_fatal_error (_("Could not read from <%s>"),Wo); + if (G_get_d_raster_row (infd_R, inrast_R, row) < 0) + G_fatal_error (_("Could not read from <%s>"),R); + if (G_get_d_raster_row (infd_F, inrast_F, row) < 0) + G_fatal_error (_("Could not read from <%s>"),F); + + + /* loop along all the columns of the line buffers */ + for (col=0; col < ncols; col++) + { + + /* read a cell from the line buffers */ + d_LAI = ((DCELL *) inrast_LAI)[col]; + d_Eo = ((DCELL *) inrast_Eo)[col]; + d_Wo = ((DCELL *) inrast_Wo)[col]; + d_R = ((DCELL *) inrast_R)[col]; + d_F = ((DCELL *) inrast_F)[col]; + + //d_R = d_F * d_R; ma io ho mm/h e quindi calcolo per cella + + /* canopy storage capacity */ + d_Wc = 0.35*d_LAI; + + /* calculate time to evaporate a saturated canopy */ + if (d_Eo>0) + d_tao = d_Wc/d_Eo; + else + d_tao = d_Ts*1000; /* it avoids division by zero if no evaporation */ + + /* cecking for input error! */ + if (d_Wo>d_Wc) { + err=1; + //d_Wo=d_Wc; + } + if (d_Wo<0) { + err=2; + //d_Wo=0; + } + + // G_fatal_error ("Input <%s> error at CELL[%d,%d]\nCanopy starting storage cannot exceed maximum storage: ",Wo,row,col); + //if (d_Wo<0) + // G_fatal_error ("Input <%s> error at CELL[%d,%d]\nCanopy starting storage cannot be negative: ",Wo,row,col); + if (d_R<0) + G_fatal_error (_("Input <%s> error at CELL[%d,%d]\nRain cannot be negative: "),R,row,col); + if (d_Eo<0) + G_fatal_error (_("Input <%s> error at CELL[%d,%d]\nPotential evaporation cannot be negative: "),Eo,row,col); + if (d_Ts<0) + G_fatal_error (_("Input <%f> error\nTimestep cannot be negative: "),d_Ts); + if (d_F<0||d_F>100) + G_fatal_error (_("Input <%f> error\nFraction a canopy vegetation cover cannot be F>100 or F<0: "),d_F); + + /* for debugging propouse: */ + G_debug ( 5, _("LAI=%lf - Eo=%lf - Wo=%lf - R=%lf - Wc=%lf - tao=%lf\n"),d_LAI,d_Eo,d_Wo,d_R,d_Wc,d_tao); + + /* calculate interception loss */ + /*******************************/ + d_Drainage = 0; + d_IntLoss = 0; + d_Wt = 0; + dt = 0; + i_sat = 0; + int ciclo = 0; + + /* if it is raining more than evapo rate it is in an increasing phase*/ + if (d_R>0 && d_Eo0\n") ); + + /* if the initial storage level is equal or bigger than the maximum */ + if (d_Wo>=d_Wc) { + ciclo=3; + G_debug ( 4, fprintf(stdout,"dWo=dWc: stauro\n") ); + d_IntLoss = FMIN((d_Eo*d_Ts),(d_R*d_Ts)+(d_Wo-d_Wc)); + //d_IntLoss = d_Eo*d_Ts; + d_Drainage = d_R*d_Ts - d_IntLoss + (d_Wo-d_Wc); + d_Wt = d_Wc; + G_debug ( 4, fprintf(stdout,"Troughfall=%lf",d_Drainage) ); + } + + /* if the initial storage level is less than the maximum */ + else { + G_debug ( 4, fprintf(stdout,"R=i_sat){ + G_debug ( 4, fprintf(stdout,"dt>=d_Ts\n") ); + ciclo=5; + //time to have saturation + dt = -d_tao*log(1-((d_Wc-d_Wo)/(d_R*d_tao))); + + /* some check!!! */ + if(dt>d_Ts) { + G_warning ("Saturation time cannot be larger than time step!\n"); + } + if(dt<0) { + G_warning ("Saturation time cannot be negative!\n"); + } + + /* d_IntLoss = FMIN( ((d_R*d_Ts)-(d_Wc-d_Wo)) , ((d_R*dt)-(d_Wc-d_Wo)+(d_Ts-dt)*d_Eo) ); */ + d_IntLoss = (d_R*dt)-(d_Wc-d_Wo)+(d_Ts-dt)*d_Eo; + d_Drainage = (d_R*d_Ts) - (d_Wc-d_Wo) - d_IntLoss; + d_Wt = d_Wc; + + } + + /* if the saturation is not reached into the timestep */ + else { + G_debug ( 4, fprintf(stdout,"dt0 && d_Eo>=d_R) { + ciclo=12; + d_Drainage = 0; + d_Wt = FMAX(d_Wo*exp(-d_Ts/d_tao),0); + d_IntLoss = d_Wo-d_Wt+d_R; + } + + /* if it is not raining it is a zero or decrease phase */ + else if (d_R<=0){ + /* if the storage was empty (zero phase)*/ + if (d_Wo<=0){ + G_debug ( 4, fprintf(stdout,"dWo=0\n") ); + ciclo=10; + d_IntLoss = 0; + d_Drainage = 0; + d_Wt = 0; + } + /* if the storage was not empty (decrease phase)*/ + else if (d_Wo<=d_Wc) { + G_debug ( 4, fprintf(stdout,"dWo>0\n") ); + ciclo=11; + d_Drainage = 0; + d_Wt = FMAX(d_Wo*exp(-d_Ts/d_tao),0); + d_IntLoss = d_Wo-d_Wt; + } + /* new added Marted? 03 Maggio */ + else { + d_Drainage = d_Wo-d_Wc; + d_Wt = FMIN(FMAX(d_Wo*exp(-d_Ts/d_tao),0),d_Wc); + d_IntLoss = d_Wc-d_Wt; + } + } + + else { + G_warning ("Exception case: Rain=%lf - Evapo=%lf\n",d_R,d_Eo); + d_IntLoss = 0; + d_Drainage = 0; + d_Wt = 0; + } + + if(((d_IntLoss+d_Drainage+d_Wt-d_Wo-d_R)-0)>0.00001) + G_debug ( 3, printf("BILANCIO: %e | CICLO:%d | IL=%lf - D=%lf - Wt=%lf - d_Wo=%lf - R=%lf\n",d_IntLoss+d_Drainage+d_Wt-d_Wo-d_R,ciclo,d_IntLoss,d_Drainage,d_Wt,d_Wo,d_R) ); + + if (d_Wt<0 || d_Wt>d_Wc) { + G_debug ( 3, printf("\nciclo: %d, d_IntLoss:%lf\nd_R:%lf, d_Eo:%lf, d_Wo:%lf, d_Wc:%lf, \ni_sat:%lf, dt:%lf, R+E:%lf",ciclo,d_IntLoss,d_R,d_Eo,d_Wo,d_Wc,i_sat,dt,((d_R*d_Ts)+d_Wo)) ); + } + + /* write evaluated values in the buffers */ + if(d_Drainage<0){ + printf("\nciclo %d\n",ciclo); + } + ((DCELL *) outrast)[col] = d_IntLoss*d_F; + ((DCELL *) outrast_D)[col] = (d_Drainage*d_F); + /* note: to get total rain reaching the ground-> d_Drainage*d_F)+(1-d_F)*d_R; */ + ((DCELL *) outrast_Wt)[col] = d_Wt; + G_debug ( 5, fprintf(stdout,"IntLoss=%lf\n",d_IntLoss) ); + } + + /* write buffers into the output rasters */ + if (G_put_d_raster_row (outfd, outrast) < 0) + G_fatal_error (_("Cannot write to <%s>"),IntLoss); + if (G_put_d_raster_row (outfd_D, outrast_D) < 0) + G_fatal_error (_("Cannot write to <%s>"),Drainage); + if (G_put_d_raster_row (outfd_Wt, outrast_Wt) < 0) + G_fatal_error (_("Cannot write to <%s>"),Wt); + + } + +if (err==1) + G_warning ("Canopy starting storage has exceeded maximum storage"); +if (err==2) + G_warning ("Canopy starting storage is negative"); + + + +/* free buffer */ +G_free(inrast_LAI); +G_free(inrast_Eo); +G_free(inrast_Wo); +G_free(inrast_R); +G_free(inrast_F); +G_free(outrast); +G_free(outrast_D); +G_free(outrast_Wt); + +/* close raster */ +G_close_cell (infd_LAI); +G_close_cell (infd_Eo); +G_close_cell (infd_Wo); +G_close_cell (infd_R); +G_close_cell (infd_F); +G_close_cell (outfd); +G_close_cell (outfd_D); +G_close_cell (outfd_Wt); + +return (0); +} Property changes on: trunk/grassaddons/HydroFOSS/r.interception/main.c ___________________________________________________________________ Name: svn:executable + * Modified: trunk/grassaddons/HydroFOSS/r.snow/description.html =================================================================== --- trunk/grassaddons/HydroFOSS/r.snow/description.html 2007-07-30 02:53:26 UTC (rev 985) +++ trunk/grassaddons/HydroFOSS/r.snow/description.html 2007-07-30 17:58:03 UTC (rev 986) @@ -107,10 +107,10 @@

      SEE ALSO

      @@ -118,7 +118,7 @@

      AUTHORS

      -

      Original version of program: The HydroFOSS project, 2006, IST-SUPSI. +

      Original version of program: The HydroFOSS project, 2006, IST-SUPSI. (http://istgis.ist.supsi.ch:8001/geomatica/index.php?id=1)
      Massimiliano Cannata, Istituto Scienze della Terra - Scuola Universitaria Professionale della Svizzera Italiana
      Maria A. Brovelli, Politecnico di Milano - Polo regionale di Como
      @@ -146,6 +146,6 @@ Utah Water Research Laboratory and USDA Forest Service Intermountain Research Station. -

      Last changed: $Date: 2005/11/15 08:14:53 $ +

      Last changed: $Date: 2007/07/29 19:30:00 $ Modified: trunk/grassaddons/HydroFOSS/r.snow/main.c =================================================================== --- trunk/grassaddons/HydroFOSS/r.snow/main.c 2007-07-30 02:53:26 UTC (rev 985) +++ trunk/grassaddons/HydroFOSS/r.snow/main.c 2007-07-30 17:58:03 UTC (rev 986) @@ -8,7 +8,7 @@ * the snowamelt and the snowpack energy with a modified * SHE model approach. * -* COPYRIGHT: (C) 2006 by Istituto Scienze della Terra +* COPYRIGHT: (C) 2006 by Istituto Scienze della Terra (www.ist.supsi.ch) * * This program is free software under the GNU General Public * Licence (>=2). Read the file COPYING that cames with GRASS From cannata at grass.itc.it Mon Jul 30 19:59:32 2007 From: cannata at grass.itc.it (cannata@grass.itc.it) Date: Mon Jul 30 19:59:33 2007 Subject: [grass-addons] r987 - trunk/grassaddons/HydroFOSS/r.interception Message-ID: <200707301759.l6UHxWg8011697@grass.itc.it> Author: cannata Date: 2007-07-30 19:59:30 +0200 (Mon, 30 Jul 2007) New Revision: 987 Modified: trunk/grassaddons/HydroFOSS/r.interception/main.c Log: added new command r.interception and minor changes to description files Modified: trunk/grassaddons/HydroFOSS/r.interception/main.c =================================================================== --- trunk/grassaddons/HydroFOSS/r.interception/main.c 2007-07-30 17:58:03 UTC (rev 986) +++ trunk/grassaddons/HydroFOSS/r.interception/main.c 2007-07-30 17:59:30 UTC (rev 987) @@ -302,12 +302,12 @@ /* if the initial storage level is equal or bigger than the maximum */ if (d_Wo>=d_Wc) { ciclo=3; - G_debug ( 4, fprintf(stdout,"dWo=dWc: stauro\n") ); + G_debug ( 4, _("dWo=dWc: stauro\n") ); d_IntLoss = FMIN((d_Eo*d_Ts),(d_R*d_Ts)+(d_Wo-d_Wc)); //d_IntLoss = d_Eo*d_Ts; d_Drainage = d_R*d_Ts - d_IntLoss + (d_Wo-d_Wc); d_Wt = d_Wc; - G_debug ( 4, fprintf(stdout,"Troughfall=%lf",d_Drainage) ); + G_debug ( 4, _("Troughfall=%lf"),d_Drainage); } /* if the initial storage level is less than the maximum */ @@ -319,17 +319,17 @@ /* if the saturation is reach into the timestep */ if (d_R>=i_sat){ - G_debug ( 4, fprintf(stdout,"dt>=d_Ts\n") ); + G_debug ( 4, _("dt>=d_Ts\n") ); ciclo=5; //time to have saturation dt = -d_tao*log(1-((d_Wc-d_Wo)/(d_R*d_tao))); /* some check!!! */ if(dt>d_Ts) { - G_warning ("Saturation time cannot be larger than time step!\n"); + G_warning (_("Saturation time cannot be larger than time step!\n")); } if(dt<0) { - G_warning ("Saturation time cannot be negative!\n"); + G_warning (_("Saturation time cannot be negative!\n")); } /* d_IntLoss = FMIN( ((d_R*d_Ts)-(d_Wc-d_Wo)) , ((d_R*dt)-(d_Wc-d_Wo)+(d_Ts-dt)*d_Eo) ); */ @@ -341,7 +341,7 @@ /* if the saturation is not reached into the timestep */ else { - G_debug ( 4, fprintf(stdout,"dt0\n") ); + G_debug ( 4, _("dWo>0\n") ); ciclo=11; d_Drainage = 0; d_Wt = FMAX(d_Wo*exp(-d_Ts/d_tao),0); @@ -388,17 +388,17 @@ } else { - G_warning ("Exception case: Rain=%lf - Evapo=%lf\n",d_R,d_Eo); + G_warning (_("Exception case: Rain=%lf - Evapo=%lf\n"),d_R,d_Eo); d_IntLoss = 0; d_Drainage = 0; d_Wt = 0; } if(((d_IntLoss+d_Drainage+d_Wt-d_Wo-d_R)-0)>0.00001) - G_debug ( 3, printf("BILANCIO: %e | CICLO:%d | IL=%lf - D=%lf - Wt=%lf - d_Wo=%lf - R=%lf\n",d_IntLoss+d_Drainage+d_Wt-d_Wo-d_R,ciclo,d_IntLoss,d_Drainage,d_Wt,d_Wo,d_R) ); + G_debug ( 3, _("BILANCIO: %e | CICLO:%d | IL=%lf - D=%lf - Wt=%lf - d_Wo=%lf - R=%lf\n"),d_IntLoss+d_Drainage+d_Wt-d_Wo-d_R,ciclo,d_IntLoss,d_Drainage,d_Wt,d_Wo,d_R); if (d_Wt<0 || d_Wt>d_Wc) { - G_debug ( 3, printf("\nciclo: %d, d_IntLoss:%lf\nd_R:%lf, d_Eo:%lf, d_Wo:%lf, d_Wc:%lf, \ni_sat:%lf, dt:%lf, R+E:%lf",ciclo,d_IntLoss,d_R,d_Eo,d_Wo,d_Wc,i_sat,dt,((d_R*d_Ts)+d_Wo)) ); + G_debug ( 3, _("\nciclo: %d, d_IntLoss:%lf\nd_R:%lf, d_Eo:%lf, d_Wo:%lf, d_Wc:%lf, \ni_sat:%lf, dt:%lf, R+E:%lf"),ciclo,d_IntLoss,d_R,d_Eo,d_Wo,d_Wc,i_sat,dt,((d_R*d_Ts)+d_Wo)); } /* write evaluated values in the buffers */ @@ -409,7 +409,7 @@ ((DCELL *) outrast_D)[col] = (d_Drainage*d_F); /* note: to get total rain reaching the ground-> d_Drainage*d_F)+(1-d_F)*d_R; */ ((DCELL *) outrast_Wt)[col] = d_Wt; - G_debug ( 5, fprintf(stdout,"IntLoss=%lf\n",d_IntLoss) ); + G_debug ( 5, _("IntLoss=%lf\n"),d_IntLoss); } /* write buffers into the output rasters */ @@ -423,9 +423,9 @@ } if (err==1) - G_warning ("Canopy starting storage has exceeded maximum storage"); + G_warning (_("Canopy starting storage has exceeded maximum storage")); if (err==2) - G_warning ("Canopy starting storage is negative"); + G_warning (_("Canopy starting storage is negative"));