[GRASS-SVN] r64850 - in grass-addons/grass7/gui/wxpython: . wx.mwprecip
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Mar 13 10:24:00 PDT 2015
Author: krejcmat
Date: 2015-03-13 10:24:00 -0700 (Fri, 13 Mar 2015)
New Revision: 64850
Added:
grass-addons/grass7/gui/wxpython/wx.mwprecip/
grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.html
grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.py
grass-addons/grass7/gui/wxpython/wx.mwprecip/mw3.py
grass-addons/grass7/gui/wxpython/wx.mwprecip/mw_util.py
grass-addons/grass7/gui/wxpython/wx.mwprecip/pgwrapper.py
grass-addons/grass7/gui/wxpython/wx.mwprecip/wx.mwprecip.py
Log:
add wx.mwprecip module
Added: grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.html (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.html 2015-03-13 17:24:00 UTC (rev 64850)
@@ -0,0 +1,5 @@
+<h2>DESCRIPTION</h2>
+<em>wx.mwprecip</em> allows to process data from cellular microwave links. For info please contact author
+<h2>AUTHOR</h2>
+
+Matej Krejci, matejkrejci at gmail.cz, Czech Technical University in Prague, Czech Republic
Added: grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.py (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.py 2015-03-13 17:24:00 UTC (rev 64850)
@@ -0,0 +1,1157 @@
+#!/usr/bin/env python
+
+
+from mw_util import *
+from core.gcmd import GMessage, GError
+
+from gui_core import gselect
+
+class DBconn(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.database = BaseInput(self, label='Name of database')
+ self.schema = BaseInput(self, label='Name of schema')
+ self.host = BaseInput(self, label='Host name')
+ self.user = BaseInput(self, label='User name')
+ self.port = BaseInput(self, label='Port')
+ self.passwd = BaseInput(self, label='Password')
+ # self.saveLoad = SaveLoad(self)
+ self.okBtt = wx.Button(self, wx.ID_OK, label='ok and close')
+ self.okBtt.Bind(wx.EVT_BUTTON, self.saveSettings)
+ if len(settings) > 0:
+ self.loadSettings()
+ self._layout()
+
+ def _layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+
+ panelSizer.Add(self.database, flag=wx.EXPAND)
+ panelSizer.Add(self.schema, flag=wx.EXPAND)
+ panelSizer.Add(self.host, flag=wx.EXPAND)
+ panelSizer.Add(self.user, flag=wx.EXPAND)
+ panelSizer.Add(self.port, flag=wx.EXPAND)
+ panelSizer.Add(self.passwd, flag=wx.EXPAND)
+ panelSizer.AddSpacer(10, 0, wx.EXPAND)
+ # panelSizer.Add(self.saveLoad, flag=wx.EXPAND)
+ panelSizer.Add(self.okBtt, flag=wx.EXPAND)
+
+ self.SetSizerAndFit(panelSizer)
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+
+ try:
+ self.database.SetValue(self.settings['database'])
+ except:
+ print 'err'
+ pass
+ try:
+ self.schema.SetValue(self.settings['schema'])
+ except:
+ pass
+ try:
+ self.host.SetValue(self.settings['host'])
+ except:
+ pass
+ try:
+ self.user.SetValue(self.settings['user'])
+ except:
+ pass
+ try:
+ self.port.SetValue(self.settings['port'])
+ except:
+ pass
+ try:
+ self.passwd.SetValue(self.settings['passwd'])
+ except:
+ pass
+
+ def saveSettings(self, settings=None):
+ if settings is not None:
+ self.settings = settings
+ self.settings['database'] = self.database.GetValue()
+ self.settings['schema'] = self.schema.GetValue()
+ self.settings['host'] = self.host.GetValue()
+ self.settings['user'] = self.user.GetValue()
+ self.settings['port'] = self.port.GetValue()
+ self.settings['passwd'] = self.passwd.GetValue()
+
+ return self.settings
+
+
+class PointInterpolationPanel(wx.Panel):
+ def __init__(self, parent, settings=None):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.interpolState = wx.CheckBox(self, label='interpolate points along links')
+ self.interpolState.Bind(wx.EVT_CHECKBOX, self.onCheckInterpol)
+ self.interpolState.SetValue(False)
+ self.rb1 = wx.RadioButton(self, label='Number of points', style=wx.RB_GROUP)
+ self.rb2 = wx.RadioButton(self, label='Distance')
+ self.val = BaseInput(self, label='Value')
+
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+
+ panelSizer.Add(self.interpolState, flag=wx.EXPAND)
+ panelSizer.Add(self.rb1, flag=wx.EXPAND)
+ panelSizer.Add(self.rb2, flag=wx.EXPAND)
+ panelSizer.Add(self.val, flag=wx.EXPAND)
+ self.SetSizerAndFit(panelSizer)
+ self.onCheckInterpol()
+
+ def onCheckInterpol(self, evt=None):
+ if self.interpolState.GetValue():
+ self.rb1.Enable()
+ self.rb2.Enable()
+ self.val.Enable()
+ else:
+ self.rb1.Disable()
+ self.rb2.Disable()
+ self.val.Disable()
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+ try:
+ self.rb1.SetValue(self.settings['pitypeDist'])
+ except:
+ pass
+ try:
+ self.val.SetValue(self.settings['pivalue'])
+ except:
+ pass
+
+ def saveSettings(self, settings=None):
+ if settings is not None:
+ self.settings = settings
+ self.settings['pitypeDist'] = self.rb1.GetValue()
+ self.settings['pivalue'] = self.val.GetValue()
+ return self.settings
+
+
+class BaselinePanel(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+
+ self.dryWin = wx.RadioButton(self, label='Compute from dry windows', style=wx.RB_GROUP)
+ self.fromFile = wx.RadioButton(self, label='Direct text input')
+ self.baselTypeTxt = wx.StaticText(self, label='Select statistic method')
+ self.baselType = wx.ComboBox(self, id=wx.ID_ANY, value="quantile", choices=['avg', 'mode', 'quantile'])
+ self.round = BaseInput(self, 'Round data to "n" of decimal places') # TODO MODE disable
+ self.quantile = BaseInput(self, 'Set quantile in %') # TODO quantile disable
+ self.aw = BaseInput(self, 'Antena wetting value')
+ self.dryInterval = TextInput(self, 'Set interval of dry period')
+ self.fromFileVal = TextInput(self, 'Set baseline values in csv format')
+ # self.SLpanel = SaveLoad(self)
+ self.okBtt = wx.Button(self, wx.ID_OK, label='ok and close')
+ self.onChangeMethod(None)
+ self.fromFile.Bind(wx.EVT_RADIOBUTTON, self.onChangeMethod)
+ self.dryWin.Bind(wx.EVT_RADIOBUTTON, self.onChangeMethod)
+ self.okBtt.Bind(wx.EVT_BUTTON, self.saveSettings)
+ if len(settings) > 0:
+ self.loadSettings(None)
+
+ self._layout()
+
+ def loadSettings(self, sett=None):
+ if sett is not None:
+ self.settings = sett
+ try:
+ self.fromFile.SetValue(self.settings['fromFile'])
+ except:
+ pass
+ try:
+ self.dryWin.SetValue(self.settings['dryWin'])
+ except:
+ pass
+ try:
+ self.quantile.SetValue(self.settings['quantile'])
+ except:
+ pass
+
+ try:
+ self.baselType.SetValue(self.settings['baselType'])
+ except:
+ pass
+ try:
+ self.round.SetValue(self.settings['round'])
+ except:
+ pass
+ try:
+ self.aw.SetValue(self.settings['aw'])
+ except:
+ pass
+ try:
+ self.dryInterval.SetPath(self.settings['dryInterval'])
+ except:
+ pass
+ try:
+ self.fromFileVal.SetPath(self.settings['fromFileVal'])
+ except:
+ pass
+ self.onChangeMethod()
+
+ def saveSettings(self, evt=None, sett=None):
+ if sett:
+ self.settings = sett
+ self.settings['fromFile'] = self.fromFile.GetValue()
+ self.settings['dryWin'] = self.dryWin.GetValue()
+
+ self.settings['baselType'] = self.baselType.GetValue()
+ self.settings['round'] = self.round.GetValue()
+ self.settings['quantile'] = self.quantile.GetValue()
+ self.settings['aw'] = self.aw.GetValue()
+ self.settings['dryInterval'] = self.dryInterval.GetPath()
+ self.settings['fromFileVal'] = self.fromFileVal.GetPath()
+ return self.settings
+
+ def onChangeMethod(self, evt=None):
+ if self.dryWin.GetValue() is False:
+ self.baselType.Disable()
+ self.round.Disable()
+ self.aw.Disable()
+ self.dryInterval.Disable()
+ self.quantile.Disable()
+ self.fromFileVal.Enable()
+ else:
+ self.baselType.Enable()
+ self.round.Enable()
+ self.aw.Enable()
+ self.quantile.Enable()
+ self.dryInterval.Enable()
+ self.fromFileVal.Disable()
+
+ def _layout(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(self.dryWin, flag=wx.EXPAND)
+ sizer.Add(self.fromFile, flag=wx.EXPAND)
+ sizer.Add(self.baselTypeTxt, flag=wx.EXPAND)
+ sizer.Add(self.baselType, flag=wx.EXPAND)
+ sizer.Add(self.round, flag=wx.EXPAND)
+ sizer.Add(self.quantile, flag=wx.EXPAND)
+ sizer.Add(self.aw, flag=wx.EXPAND)
+ sizer.Add(self.dryInterval, flag=wx.EXPAND)
+ sizer.AddSpacer(10, 0, wx.EXPAND)
+ sizer.Add(self.fromFileVal, flag=wx.EXPAND)
+ sizer.AddSpacer(10, 0, wx.EXPAND)
+ # sizer.Add(self.SLpanel, flag=wx.EXPAND)
+ sizer.Add(self.okBtt, flag=wx.EXPAND)
+ self.SetSizerAndFit(sizer)
+
+
+'''
+class DataMgrRG(wx.Panel):
+ def __init__(self, parent, settings=None):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.sett = settings
+'''
+
+
+class DataMgrMW(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+
+ self.stBoxTWIN = wx.StaticBox(self, wx.ID_ANY, 'Time windows MW')
+
+ # =================DATA=========================
+ self.linksAll = wx.RadioButton(self, label='All', style=wx.RB_GROUP)
+ self.linksOnly = wx.RadioButton(self, label='Use links')
+ self.linksIngnore = wx.RadioButton(self, label='Ignore links')
+ self.linksAll.Bind(wx.EVT_RADIOBUTTON, self.refreshLinkSet)
+ self.linksIngnore.Bind(wx.EVT_RADIOBUTTON, self.refreshLinkSet)
+ self.linksOnly.Bind(wx.EVT_RADIOBUTTON, self.refreshLinkSet)
+ self.vectorMap = wx.RadioButton(self,label='Vector map')
+ self.vectorMap.Bind(wx.EVT_RADIOBUTTON,self.refreshLinkSet)
+
+ # self.links = BaseInput(self,'Set links according to radio above',True)
+ self.links = BaseInput(self, 'Set links according to radio above')
+ self.mapLabel=wx.StaticText(self,label='Select vector map')
+ self.map = gselect.Select(self, type='vector',multiple=False)
+
+ self.start = BaseInput(self, label='Start time')
+ self.end = BaseInput(self, label='End time')
+ self.getStartBtt = wx.Button(self, label='Get min')
+ self.getEndBtt = wx.Button(self, label='Get max')
+ self.sumStep = wx.ComboBox(self, id=wx.ID_ANY, value="minute", choices=['minute', 'hour', 'day'])
+
+ self.stBoxGauge = wx.StaticBox(self, wx.ID_ANY, 'Rain gauge')
+ self.inpRainGauge = FileInput(self, 'Select folder with raingauges data')
+ self.inpRainGauge.pathInput.Bind(wx.EVT_TEXT,self.disableLinksInp)
+ # self.sb1 = wx.StaticBox(self, wx.ID_ANY, 'Baseline')
+ # self.type = self.rb1 = wx.RadioButton(self, label='Number of points', style=wx.RB_GROUP)
+ if len(settings) > 0:
+ self.loadSettings()
+ self._layout()
+
+ def disableLinksInp(self,evt=None):
+ if self.inpRainGauge.GetPath() is not None:
+ self.linksAll.Disable()
+ self.linksOnly.Disable()
+ self.linksIngnore.Disable()
+ self.links.Disable()
+ self.vectorMap.Disable()
+ self.mapLabel.Disable()
+ self.map.Disable()
+ else:
+ self.linksAll.Enable()
+ self.linksOnly.Enable()
+ self.linksIngnore.Enable()
+ self.vectorMap.Enable()
+ self.mapLabel.Enable()
+ self.map.Enable()
+
+ if not self.linksAll.GetValue():
+ self.links.Enable()
+
+ def refreshLinkSet(self, evt=None):
+ if self.linksAll.GetValue():
+ self.links.Disable()
+ else:
+ self.links.Enable()
+
+ if self.vectorMap.GetValue():
+ self.links.Hide()
+ self.mapLabel.Show()
+ self.map.Show()
+ else:
+ self.links.Show()
+ self.mapLabel.Hide()
+ self.map.Hide()
+ self.Fit()
+
+ def saveSettings(self, evt=None, sett=None):
+ if sett:
+ self.settings = sett
+ self.settings['linksOnly'] = self.linksOnly.GetValue()
+ self.settings['linksIngnore'] = self.linksIngnore.GetValue()
+ self.settings['linksMap'] = self.map.GetValue()
+ self.settings['links'] = self.links.GetValue()
+ self.settings['start'] = self.start.GetValue()
+ self.settings['end'] = self.end.GetValue()
+ self.settings['sumStep'] = self.sumStep.GetValue()
+ self.settings['inpRainGauge'] = self.inpRainGauge.GetPath()
+ return self.settings
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+ try:
+ self.map.SetValue(eval(self.settings['linksMap']))
+ except:
+ pass
+ try:
+ self.linksOnly.SetValue(eval(self.settings['linksOnly']))
+ except:
+ pass
+ try:
+ self.linksIngnore.SetValue(eval(self.settings['linksIngnore']))
+ except:
+ pass
+ try:
+ self.links.SetValue(self.settings['links'])
+ except:
+ pass
+ try:
+ self.start.SetValue(self.settings['start'])
+ except:
+ pass
+ try:
+ self.end.SetValue(self.settings['end'])
+ except:
+ pass
+ try:
+ self.sumStep.SetValue(self.settings['sumStep'])
+ except:
+ pass
+ try:
+ self.inpRainGauge.SetPath(self.settings['inpRainGauge'])
+ except:
+ pass
+
+ def _layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+ self.SetSizerAndFit(panelSizer)
+
+ linksSizer = wx.BoxSizer(wx.HORIZONTAL)
+ linksSizer.Add(self.linksAll, flag=wx.EXPAND, proportion=1)
+ linksSizer.Add(self.linksOnly, flag=wx.EXPAND, proportion=1)
+ linksSizer.Add(self.linksIngnore, flag=wx.EXPAND, proportion=1)
+ linksSizer.Add(self.vectorMap, flag=wx.EXPAND, proportion=1)
+
+ stBoxSizerTWIN = wx.StaticBoxSizer(self.stBoxTWIN, orient=wx.VERTICAL)
+ stBoxSizerTWIN.Add(linksSizer, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.links, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.mapLabel, flag=wx.EXPAND)
+ stBoxSizerTWIN.Add(self.map, flag=wx.EXPAND)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.Add(self.start, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.getStartBtt)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.Add(self.end, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.getEndBtt)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.Add(wx.StaticText(self, id=wx.ID_ANY, label='Time increment'))
+ stBoxSizerTWIN.Add(self.sumStep, flag=wx.EXPAND)
+
+ gaugeSizer = wx.BoxSizer(wx.HORIZONTAL)
+ gaugeSizer.Add(self.inpRainGauge, flag=wx.EXPAND, proportion=1)
+
+ stBoxSizerRGAUGE = wx.StaticBoxSizer(self.stBoxGauge, orient=wx.VERTICAL)
+ stBoxSizerRGAUGE.Add(gaugeSizer, flag=wx.EXPAND, proportion=1)
+
+ panelSizer.Add(stBoxSizerTWIN, flag=wx.EXPAND)
+ panelSizer.Add(stBoxSizerRGAUGE, flag=wx.EXPAND)
+
+ # panelSizer.Add(self.exportDataBtt, flag=wx.EXPAND)
+ # panelSizer.Add(self.computeBtt, flag=wx.EXPAND)
+ self.SetSizerAndFit(panelSizer)
+ self.refreshLinkSet()
+
+class GrassLayers(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.colorRules = TextInput(self,label='Color table')
+ self.colorsName = BaseInput(self,label='Name of color table')
+ self.layout()
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+ try:
+ self.colorRules.SetValue(self.settings['colorRules'])
+ except:
+ pass
+
+ try:
+ self.colorsName.SetValue(self.settings['colorsName'])
+ except:
+ pass
+
+ def saveSettings(self, evt=None, sett=None):
+ if sett:
+ self.settings = sett
+ self.settings['colorName'] = self.colorsName.GetValue()
+ self.settings['colorRules'] = self.colorRules.GetPath()
+ return self.settings
+
+ def layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+ panelSizer.Add(self.colorsName,flag= wx.EXPAND )
+ panelSizer.Add(self.colorRules, flag=wx.EXPAND )
+ self.SetSizerAndFit(panelSizer)
+
+class GeometryPanel(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.label=wx.StaticText(self,label='Create vector geometry map')
+ self.linksExp = wx.RadioButton(self, label='Links', style=wx.RB_GROUP)
+ self.nodesExp = wx.RadioButton(self, label='Nodes')
+ self.mapName=BaseInput(self,'Map name')
+ self.bttExport=wx.Button(self,label='Export')
+
+ self.layout()
+
+ def layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+
+ panelSizer.Add(self.label,flag=wx.EXPAND)
+ panelSizer.Add(self.linksExp,flag=wx.EXPAND)
+ panelSizer.Add(self.nodesExp,flag=wx.EXPAND)
+ panelSizer.Add(self.mapName,flag=wx.EXPAND)
+ panelSizer.Add(self.bttExport,flag=wx.EXPAND)
+ self.SetSizerAndFit(panelSizer)
+
+ def GetOptions(self):
+ if self.linksExp.GetValue():
+ type='links'
+ else:
+ type='nodes'
+ return type,self.mapName.GetValue()
+
+class ExportData(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+
+ self.chkid=wx.CheckBox(self,label='linkid')
+ self.chkid.SetValue(True)
+ self.chkid.Disable()
+ self.chktime=wx.CheckBox(self,label='time')
+ self.chktime.SetValue(True)
+ self.chktime.Disable()
+
+ self.chkprecip=wx.CheckBox(self,label='precipitation')
+ self.chkrx=wx.CheckBox(self,label='rx')
+ self.chktx=wx.CheckBox(self,label='tx')
+ self.chkfreq=wx.CheckBox(self,label='frequency')
+ self.chkpol=wx.CheckBox(self,label='polarization')
+ self.okBtt=wx.Button(self,label='export')
+ self.layout()
+ #self.chkprecip.Bind(wx.EVT_CHECKBOX,self.onChckPrec)
+
+ def layout(self):
+ mainSizer=wx.BoxSizer(wx.VERTICAL)
+
+ mainSizer.Add(self.chkid,wx.EXPAND)
+ mainSizer.Add(self.chktime,wx.EXPAND)
+ mainSizer.Add(self.chkprecip,wx.EXPAND)
+ mainSizer.Add(self.chkrx,wx.EXPAND)
+ mainSizer.Add(self.chktx,wx.EXPAND)
+ mainSizer.Add(self.chkfreq,wx.EXPAND)
+ mainSizer.Add(self.chkpol,wx.EXPAND)
+ mainSizer.Add(self.okBtt,wx.EXPAND)
+
+ self.SetSizerAndFit(mainSizer)
+
+class MyFrame(wx.Frame):
+ def __init__(self, parent, id, title):
+ wx.Frame.__init__(self, parent, id, title, size=(480, 640))
+ self.workPath = os.path.dirname(os.path.realpath(__file__))
+ self.initWorkingFoldrs()
+ self.settings = {}
+ self.settingsLst = []
+ self.mainSizer = wx.BoxSizer(wx.VERTICAL)
+
+ menubar = wx.MenuBar()
+ settMenu = wx.Menu()
+ fileMenu = wx.Menu()
+ databaseItem = settMenu.Append(wx.ID_ANY, 'Database', 'Set database')
+ baselineItem = settMenu.Append(wx.ID_ANY, 'Baseline', 'Set baseline methods')
+ geometry = settMenu.Append(wx.ID_ANY,'Geometry', 'Create vector geometry')
+ quitItem = settMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
+ menubar.Append(settMenu, '&Options')
+
+ #geoMenu = wx.Menu()
+
+ #menubar.Append(geoMenu, '&Settings')
+
+
+ self.SetMenuBar(menubar)
+ self.Bind(wx.EVT_MENU, self.onQuit, quitItem)
+ self.Bind(wx.EVT_MENU, self.onSetDatabase, databaseItem)
+ self.Bind(wx.EVT_MENU, self.onSetBaseline, baselineItem)
+ self.Bind(wx.EVT_MENU, self.onSetGeometry, geometry)
+
+ #def initNotebook(self):
+
+ self.ntb = wx.Notebook(self, id=wx.ID_ANY)
+ self.dataMgrMW = DataMgrMW(self.ntb)
+ self.dataMgrMW.getEndBtt.Bind(wx.EVT_BUTTON, self.getMaxTime)
+ self.dataMgrMW.getStartBtt.Bind(wx.EVT_BUTTON, self.getMinTime)
+
+ #self.dataMgrRG = DataMgrMW(self.ntb )
+ self.pointInter = PointInterpolationPanel(self.ntb)
+ self.ntb.AddPage(page=self.dataMgrMW, text='MW data')
+ #self.ntb.AddPage(page=self.dataMgrRG, text='RG data')
+ self.ntb.AddPage(page=self.pointInter, text='Points Interpolation')
+
+ self.grassLayers = GrassLayers(self.ntb, self.settings)
+ self.ntb.AddPage(page=self.grassLayers, text='Layers')
+
+ #def initProfileSett(self):
+ self.loadScheme = wx.StaticText(self, label='Load settings', id=wx.ID_ANY)
+ self.profilSelection = wx.ComboBox(self)
+ self.schema = BaseInput(self, 'Name of new working profile')
+ self.schema.text.Bind(wx.EVT_TEXT, self.OnSchemeTxtChange)
+ self.newScheme = wx.Button(self, label='Save new profile')
+ self.newScheme.Bind(wx.EVT_BUTTON, self.OnSaveSettings)
+ self.newScheme.Disable()
+ self.profilSelection.Bind(wx.EVT_COMBOBOX, self.OnLoadSettings)
+
+ #def initRunBtt(self):
+ self.computeBtt = wx.Button(self, label='Compute')
+ self.exportDataBtt = wx.Button(self, label='Export data')
+ self.computeBtt.Bind(wx.EVT_BUTTON, self.runCompute)
+ self.exportDataBtt.Bind(wx.EVT_BUTTON, self.exportData)
+
+ self.findProject()
+ self.layout()
+
+ def getMinTime(self, evt=None):
+ self.OnSaveSettings(toFile=False)
+ interface = Gui2Model(self, self.settings) # TODO optimalize init
+ if interface.connStatus:
+
+ self.dataMgrMW.start.SetValue(interface.dbConn.minTimestamp())
+
+ def getMaxTime(self, evt=None):
+ self.OnSaveSettings(toFile=False)
+ interface = Gui2Model(self, self.settings)
+ if interface.connStatus:
+ self.dataMgrMW.end.SetValue(interface.dbConn.maxTimestamp())
+
+ def GetConnection(self):
+ self.OnSaveSettings(toFile=False)
+ interface = Gui2Model(self, self.settings)
+ if interface.connStatus:
+ return interface.dbConn
+
+ def OnSchemeTxtChange(self, evt=None):
+ if self.schema.GetValue() is not None:
+ self.newScheme.Enable()
+ else:
+ self.newScheme.Disable()
+
+ def OnLoadSettings(self, evt=None):
+ currSelId = self.profilSelection.GetSelection()
+ self.settings = self.settingsLst[currSelId]
+ try:
+ self.dataMgrMW.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.dataMgrRG.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.databasePnl.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.baselinePnl.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.grassLayers.loadSettings(self.settings)
+ except:
+ pass
+
+ def OnSaveSettings(self, evt=None, toFile=True):
+ try:
+ self.settings = self.dataMgrMW.saveSettings(sett=self.settings)
+ except:
+ pass
+ # try:
+ # self.settings=self.dataMgrRG.saveSettings(sett=self.settings)
+ # except:
+ # pass
+ try:
+ self.settings = self.databasePnl.saveSettings(sett=self.settings)
+ except:
+ pass
+ try:
+ self.settings = self.baselinePnl.saveSettings(sett=self.settings)
+ except:
+ pass
+ try:
+ self.settings = self.grassLayers.saveSettings(sett=self.settings)
+ except:
+ pass
+
+ try:
+ self.settings['workSchema'] = self.profilSelection.GetValue()
+ except:
+ pass
+
+ if self.schema.GetValue() is not None:
+ self.settings['workSchema'] = self.schema.GetValue()
+
+ if toFile:
+ tmpPath = os.path.join(self.workPath, "save", self.settings['workSchema'])
+ saveDict(tmpPath, self.settings)
+ self.findProject()
+
+ def initWorkingFoldrs(self):
+ savePath=os.path.join(self.workPath,'save')
+ if not os.path.exists(savePath):
+ os.makedirs(savePath)
+
+ tmpPath=os.path.join(self.workPath,'temp')
+ if not os.path.exists(tmpPath):
+ os.makedirs(tmpPath)
+
+ def findProject(self):
+ try:
+ projectDir = os.path.join(self.workPath, "save")
+ except:
+ GMessage('Cannot find "save" folder')
+ return
+ filePathList = getFilesInFoldr(projectDir, True)
+ # print 'filePathList',filePathList
+ if filePathList != 0:
+ self.profilSelection.Clear()
+ for n, path in enumerate(filePathList):
+ tmpDict = readDict(path)
+ self.settingsLst.append(tmpDict)
+ self.profilSelection.Append(str(tmpDict['workSchema']))
+ else:
+ return
+
+ def onSetGeometry(self,evt):
+ self.geDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Geometry creator',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ self.geDialog.SetSize((500, 500))
+
+ if self.settings:
+ self.geometryPnl = GeometryPanel(self.geDialog, self.settings)
+ else:
+ self.geometryPnl = GeometryPanel(self.geDialog)
+
+ self.geometryPnl.bttExport.Bind(wx.EVT_BUTTON, self._onSetGeomDLG)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.geometryPnl, flag=wx.EXPAND)
+ self.geDialog.SetSizer(dbSizer)
+ self.geDialog.SetBestFittingSize()
+ self.geDialog.ShowModal()
+ self.geDialog.Destroy()
+
+ def _onSetGeomDLG(self, evt):
+ type,name=self.geometryPnl.GetOptions()
+ if name == '':
+ GMessage('Please set name of map')
+ else:
+ self.createGeometry(type,name)
+ #self.addMapToLay()#TODO giface
+
+ def addMapToLay(self,map):
+ #TODO giface
+ '''
+
+ tree = self._giface.GetLayerTree()
+ if tree:
+ tree.AddLayer(ltype='vector', lname=map,
+ lcmd=['d.vect', 'map=%s' % map],
+ lchecked=True)
+ '''
+ pass
+
+ def onSetBaseline(self, evt):
+ self.bsDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Baseline settings',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ #self.bsDialog.SetSize((500, 500))
+
+ if self.settings:
+ self.baselinePnl = BaselinePanel(self.bsDialog, self.settings)
+ else:
+ self.baselinePnl = BaselinePanel(self.bsDialog)
+
+ self.baselinePnl.okBtt.Bind(wx.EVT_BUTTON, self._onSetBaselineDLG)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.baselinePnl, flag=wx.EXPAND)
+
+ self.bsDialog.SetSizer(dbSizer)
+ self.bsDialog.SetBestFittingSize()
+ self.bsDialog.ShowModal()
+ self.bsDialog.Destroy()
+
+ def _onSetBaselineDLG(self, evt):
+ self.settings = self.baselinePnl.saveSettings()
+ print self.settings
+ self.bsDialog.Destroy()
+
+ def onSetDatabase(self, evt):
+ self.dbDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Database connection settings',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ self.dbDialog.SetSize((500, 500))
+
+ if self.settings:
+ self.databasePnl = DBconn(self.dbDialog, self.settings)
+ else:
+ self.databasePnl = DBconn(self.dbDialog)
+
+ self.databasePnl.okBtt.Bind(wx.EVT_BUTTON, self._onSetDatabaseDLG)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.databasePnl, flag=wx.EXPAND)
+ self.dbDialog.SetSizer(dbSizer)
+ self.dbDialog.SetBestFittingSize()
+ self.dbDialog.ShowModal()
+ self.dbDialog.Destroy()
+
+ def _onSetDatabaseDLG(self, evt):
+ self.settings = self.databasePnl.saveSettings()
+ print self.settings
+ self.dbDialog.Destroy()
+
+ def createGeometry(self,type, name):
+ interface = Gui2Model(self, self.settings)
+ interface.initVectorGrass(type=type,name=name)
+
+ def exportData(self, evt):
+
+ self.exportDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Database connection settings',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ self.exportDialog.SetSize((500, 500))
+ self.exportDMgr = ExportData(self.exportDialog)
+
+ self.exportDMgr.okBtt.Bind(wx.EVT_BUTTON, self._onExport)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.exportDMgr, flag=wx.EXPAND)
+ self.exportDialog.SetSizer(dbSizer)
+ self.exportDialog.SetBestFittingSize()
+ self.exportDialog.ShowModal()
+ self.exportDialog.Destroy()
+
+ def _onExport(self,evt=None):
+ path=OnSaveAs(self)
+ self.OnSaveSettings(toFile=False)
+ if not self.exportDMgr.chkprecip.GetValue():
+ attrTmp1=[]
+ attrTmp1.append('link.linkid')
+ attrTmp2=[]
+ attrTmp3=[]
+ #attrTmp2.append('public.linkid')
+ if self.exportDMgr.chkfreq.GetValue():
+ attrTmp1.append('link.frequency')
+ if self.exportDMgr.chkpol.GetValue():
+ attrTmp1.append('link.polarization')
+
+ attrTmp2.append('record.time')
+ if self.exportDMgr.chkrx.GetValue():
+ attrTmp2.append('record.rxpower')
+ if self.exportDMgr.chktx.GetValue():
+ attrTmp2.append('record.txpower')
+
+ attrTmp4='WHERE'
+ if len(attrTmp1) > 0:
+ attrTmp3.append('link')
+ if len(attrTmp2) > 0:
+ attrTmp3.append('record')
+
+ if len(attrTmp1) > 0 and len(attrTmp2) > 0:
+ attrTmp4='WHERE link.linkid=record.linkid AND'
+ attrTmp0=attrTmp1+attrTmp2
+ attrTmp0 = ",".join(attrTmp0)
+ elif len(attrTmp1) > 0:
+ attrTmp0 = ",".join(attrTmp1)
+ elif len(attrTmp2) > 0:
+ attrTmp0 = ",".join(attrTmp2)
+
+ if len(attrTmp3)>1:
+ attrTmp3 = ",".join(attrTmp3)
+ else:
+ attrTmp3=attrTmp3[0]
+
+ sql="SELECT %s FROM %s %s record.time>'%s' and record.time< '%s' "%(attrTmp0,
+ attrTmp3,
+ attrTmp4,
+ self.dataMgrMW.start.GetValue(),
+ self.dataMgrMW.end.GetValue())
+ conn=self.GetConnection()
+ res=conn.connection.executeSql(sql, True, True)
+ lines=''
+ for r in res:
+ lines+=str(r)[1:][:-1].replace('datetime.datetime','').replace("'","") +'\n'
+ print conn.pathworkSchemaDir
+ #path=os.path.join(conn.pathworkSchemaDir, "export")
+ io0 = open(path, "wr")
+ io0.writelines(lines)
+ io0.close()
+ GMessage('Data exported<%s>'%path)
+
+ else:
+ exportData = {'getData':True,'dataOnly':False}
+ if YesNo(self, 'Export data only?'):
+ exportData['dataOnly'] = True
+ self.settings['dataExport'] = exportData
+
+ #if rain gauges
+ if self.dataMgrMW.inpRainGauge.GetPath() is not None:
+ self.settings['IDtype']='gaugeid'
+ else:
+ self.settings['IDtype']='linkid'
+
+ interface = Gui2Model(self, self.settings)
+ interface.initVectorGrass()
+ interface.initTimeWinMW()
+ interface.initBaseline()
+ interface.doCompute()
+ conn=self.GetConnection()
+ sql='SELECT * FROM %s.%s'%(interface.dbConn.schema,interface.dbConn.computedPrecip)
+ res=conn.connection.executeSql(sql, True, True)
+ lines=''
+ for r in res:
+ lines+=str(r)[1:][:-1] +'\n'
+ print conn.pathworkSchemaDir
+ #path=os.path.join(conn.pathworkSchemaDir, "export")
+ io0 = open(path, "wr")
+ io0.writelines(lines)
+ io0.close()
+ GMessage('Data exported<%s>'%path)
+
+ self.exportDialog.Destroy()
+
+ def runCompute(self, evt):
+ self.OnSaveSettings(toFile=False)
+ exportData = {'getData':False,'dataOnly':False}
+ self.settings['dataExport'] = exportData
+
+ #if rain gauges
+ if self.dataMgrMW.inpRainGauge.GetPath() is not None:
+ self.settings['IDtype']='gaugeid'
+ else:
+ self.settings['IDtype']='linkid'
+
+ interface = Gui2Model(self, self.settings)
+ interface.initVectorGrass()
+
+ #if interpolate points along lines
+ if self.pointInter.interpolState.GetValue():
+ interface.initPInterpolation()
+
+ interface.initTimeWinMW()
+ interface.initBaseline()
+ interface.doCompute()
+
+ def layout(self):
+ self.mainSizer.Add(self.loadScheme, flag=wx.EXPAND)
+ self.mainSizer.Add(self.profilSelection, flag=wx.EXPAND)
+ self.mainSizer.Add(self.schema, flag=wx.EXPAND)
+ self.mainSizer.Add(self.newScheme, flag=wx.EXPAND)
+
+ self.mainSizer.AddSpacer(10, 0, wx.EXPAND)
+ self.mainSizer.Add(self.ntb, flag=wx.EXPAND)
+
+ self.mainSizer.AddSpacer(10, 0, wx.EXPAND)
+ self.mainSizer.Add(self.computeBtt, flag=wx.EXPAND)
+ self.mainSizer.Add(self.exportDataBtt, flag=wx.EXPAND)
+
+ self.SetSizer(self.mainSizer)
+ # self.Fit()
+
+ def onQuit(self, e):
+ self.Close()
+
+class Gui2Model():
+ def __init__(self, wxParent, settings):
+ parent = wxParent
+ self.settings = settings
+ self.dbConn = None
+ self.connStatus=False
+ self.initConnection()
+
+ def initConnection(self, info=False):
+ conninfo=None
+ try:
+ conninfo = {'name': self.settings['database']}
+ except:
+ GMessage('name of database is missing')
+ return
+ try:
+ conninfo['workSchema'] = self.settings['workSchema']
+ except:
+ pass
+ try:
+ conninfo['dataSchema'] = self.settings['schema']
+ except:
+ pass
+ try:
+ conninfo['host'] = self.settings['host']
+ except:
+ pass
+ try:
+ conninfo['user'] = self.settings['user']
+ except:
+ pass
+ try:
+ conninfo['port'] = self.settings['port']
+ except:
+ pass
+ try:
+ conninfo['password'] = self.settings['passwd']
+ except:
+ pass
+
+ if conninfo is None:
+ self.connStatus=False
+ GMessage('Database connection failed')
+ return
+
+
+ if not info: # prepare for computing
+ self.dbConn = Database(**conninfo)
+ self.connStatus=True
+ self.dbConn.firstPreparation()
+ self.dbConn.prepareDB()
+ self.dbConn.prepareDir()
+
+ return self.dbConn
+ else: # just get info about curr database state
+ self.dbConn = Database(**conninfo)
+ self.connStatus=True
+ return self.dbConn
+
+ def initVectorGrass(self,type=None,name=None):
+ convertor = VectorLoader(self.dbConn)
+ if name:
+ self.dbConn.nodeVecMapName=name
+ self.dbConn.linkVecMapName=name
+
+ if type=='nodes' or type is None:
+ # create native vector map(nodes)
+ pointsSQL = convertor.selectNodes()
+ # print pointsSQL
+ pointsASCII = convertor.getASCIInodes(pointsSQL)
+ convertor.grass_vinASCII(pointsASCII, self.dbConn.nodeVecMapName)
+ # create native vector map(links)
+ if type=='links'or type is None:
+ linksSQL = convertor.selectLinks()
+ linksASCII = convertor.getASCIIlinks(linksSQL)
+ convertor.grass_vinASCII(linksASCII, self.dbConn.linkVecMapName)
+
+ def initPInterpolation(self):
+ try:
+ pitypeDist = self.settings['pitypeDist']
+ except:
+ pass
+ try:
+ pivalue = self.settings['pivalue']
+ except:
+ self.errMsg('Missing value for interpolating points along lines')
+
+ PointInterpolation(self.dbConn, pivalue, pitypeDist)
+
+ def initBaseline(self):
+ baselInit = {}
+ try:
+ baselInit['statFce'] = self.settings['baselType']
+ except:
+ pass
+ try:
+ baselInit['quantile'] = self.settings['quantile']
+ except:
+ pass
+ try:
+ baselInit['roundMode'] = self.settings['round']
+ except:
+ pass
+ try:
+ baselInit['aw'] = self.settings['aw']
+ except:
+ pass
+ methodSel = False
+ try:
+ if self.settings['fromFile']:
+ baselInit['type'] = 'values'
+ try:
+ baselInit['pathToFile'] = self.settings['fromFileVal']
+ except:
+ self.errMsg('Path to file with baseline values is not defined')
+ methodSel = True
+ except:
+ pass
+ try:
+ if self.settings['dryWin']:
+ baselInit['type'] = 'fromDryWin'
+ try:
+ baselInit['pathToFile'] = self.settings['dryInterval']
+ except:
+ self.errMsg('Dry interval is not defined')
+ methodSel = True
+ except:
+ pass
+
+ if not methodSel:
+ self.errMsg('Baseline method is not selected')
+ print baselInit
+ self.baseline = Baseline(**baselInit)
+
+ def initTimeWinMW(self):
+ winInit = {}
+ try:
+ winInit['linksOnly'] = eval(self.settings['linksOnly'])
+ except:
+ pass
+ try:
+ winInit['linksOnly'] = eval(self.settings['linksMap'])
+ except:
+ pass
+ try:
+ winInit['linksIngnore'] = eval(self.settings['linksIngnore'])
+ except:
+ pass
+ try:
+ winInit['links'] = self.settings['links']
+ except:
+ pass
+ try:
+ winInit['startTime'] = self.settings['start']
+ except:
+ pass
+ try:
+ winInit['endTime'] = self.settings['end']
+ except:
+ pass
+ try:
+ winInit['sumStep'] = self.settings['sumStep']
+ except:
+ pass
+ try:
+ winInit['IDtype'] = self.settings['IDtype']
+ except:
+ pass
+ winInit['database'] = self.dbConn
+
+ self.twin = TimeWindows(**winInit)
+
+ def doCompute(self):
+
+ # GMessage('OK')
+ # sys.exit()
+ comp=Computor(self.baseline, self.twin, self.dbConn, self.settings['dataExport'])
+ bool,msg=comp.GetStatus()
+ if bool:
+ self.initGrassLayerMgr()
+ self.initTemporalMgr()
+
+ GMessage(msg)
+ #elf.initgrassManagement()
+
+ def initGrassLayerMgr(self):
+ grassLayerMgr = {}
+ try:
+ grassLayerMgr['rules'] = self.settings['colorRules']
+ except:
+ pass
+ try:
+ grassLayerMgr['color'] = self.settings['colorName']
+ except:
+ pass
+
+ grassLayerMgr['database'] = self.dbConn
+ GrassLayerMgr(**grassLayerMgr)
+
+
+ def initTemporalMgr(self):
+ GrassTemporalMgr(self.dbConn, self.twin)
+ GMessage('Finish')
+
+ def errMsg(self, label):
+ print label
+ GError(label)
+
+class MyApp(wx.App):
+ def OnInit(self):
+ frame = MyFrame(None, -1, "MW worker")
+ frame.Show(True)
+ self.SetTopWindow(frame)
+ return True
+
+
+app = MyApp(0) # Create an instance of the application class
+app.MainLoop() # Tell it to start processing events
+
+
+
+
Property changes on: grass-addons/grass7/gui/wxpython/wx.mwprecip/g.gui.mwprecip.py
___________________________________________________________________
Added: svn:executable
+ *
Added: grass-addons/grass7/gui/wxpython/wx.mwprecip/mw3.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.mwprecip/mw3.py (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.mwprecip/mw3.py 2015-03-13 17:24:00 UTC (rev 64850)
@@ -0,0 +1,1567 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+# __author__ = 'matt'
+
+from pgwrapper import pgwrapper as pg
+from math import sin, cos, atan2, degrees, radians, tan, sqrt, fabs
+import sys, os, shutil
+import psycopg2
+import time
+from datetime import datetime, timedelta
+import math
+
+from core.gcmd import RunCommand
+from grass.pygrass.modules import Module
+from subprocess import PIPE
+from core.gcmd import GMessage, GError, GWarning
+
+
+try:
+ from grass.script import core as grass
+except ImportError:
+ sys.exit("Cannot find 'grass' Python module. Python is supported by GRASS from version >= 6.4")
+
+from mw_util import *
+
+
+class PointInterpolation():
+ def __init__(self, database, step, methodDist=False):
+ grass.message("Interpolating points along lines...")
+ self.step = float(step)
+ self.database = database
+ self.method = methodDist # 'p' - points, else distance
+
+ nametable = self.database.linkPointsVecName + str(step).replace('.0',
+ '') # create name for table with interopol. points.
+ sql = "DROP TABLE IF EXISTS %s.%s" % (self.database.schema, nametable) # if table exist than drop
+ self.database.connection.executeSql(sql, False, True)
+
+ sql = "CREATE table %s.%s " \
+ "(linkid integer,long real,lat real,point_id serial PRIMARY KEY) " \
+ % (self.database.schema, nametable) # create table where will be intrpol. points.
+ self.database.connection.executeSql(sql, False, True)
+ a = 0 # index of latlong
+ x = 0 # id in table with interpol. points
+
+ points = []
+ vecLoader = VectorLoader(self.database)
+ linksPoints = vecLoader.selectLinks(True)
+ for record in linksPoints:
+ # latlong.append(tmp) # add [lon1 lat1 lon2 lat2] to list latlong
+ linkid = record[0] # linkid value
+ dist = record[1] * 1000 # distance between nodes on current link
+ lat1 = record[3]
+ lon1 = record[2]
+ lat2 = record[5]
+ lon2 = record[4]
+ az = self.bearing(lat1, lon1, lat2, lon2) # compute approx. azimut on sphere
+ a += 1
+
+ point = list()
+ if self.method: # #compute per distance interval(points)
+ while abs(dist) > step: # compute points per step while is not achieve second node on link
+ lat1, lon1, az, backBrg = self.destinationPointWGS(lat1, lon1, az,
+ step) # return interpol. point and set current point as starting point(for next loop), also return azimut for next point
+ dist -= step # reduce distance
+ x += 1
+
+ point.append(linkid)
+ point.append(lon1)
+ point.append(lat1)
+ point.append(x)
+
+ points.append(point)
+
+ else: # # compute by dividing distance to sub-distances
+ step1 = dist / (step + 1)
+ for i in range(0, int(step)): # compute points per step while is not achieve second node on link
+ lat1, lon1, az, backBrg = self.destinationPointWGS(lat1, lon1, az,
+ step1)
+ # return interpol. point and set current point as starting point(for next loop), also return azimut for next point
+ x += 1
+
+ point.append(linkid)
+ point.append(lon1)
+ point.append(lat1)
+ point.append(x)
+
+ points.append(point)
+
+ resultPointsAlongLines = vecLoader.getASCIInodes(points)
+ vecLoader.grass_vinASCII(resultPointsAlongLines, self.database.linkPointsVecName)
+
+ sql = "ALTER TABLE %s.%s DROP COLUMN lat" % (
+ self.database.schema, nametable) # remove latitde column from table
+ self.database.connection.executeSql(sql, False, True)
+ sql = "alter table %s.%s drop column long" % (
+ self.database.schema, nametable) # remove longtitude column from table
+ self.database.connection.executeSql(sql, False, True)
+
+ def destinationPointWGS(self, lat1, lon1, brng, s):
+ a = 6378137
+ b = 6356752.3142
+ f = 1 / 298.257223563
+ lat1 = math.radians(float(lat1))
+ lon1 = math.radians(float(lon1))
+ brg = math.radians(float(brng))
+
+ sb = sin(brg)
+ cb = cos(brg)
+ tu1 = (1 - f) * tan(lat1)
+ cu1 = 1 / sqrt((1 + tu1 * tu1))
+ su1 = tu1 * cu1
+ s2 = atan2(tu1, cb)
+ sa = cu1 * sb
+ csa = 1 - sa * sa
+ us = csa * (a * a - b * b) / (b * b)
+ A = 1 + us / 16384 * (4096 + us * (-768 + us * (320 - 175 * us)))
+ B = us / 1024 * (256 + us * (-128 + us * (74 - 47 * us)))
+ s1 = s / (b * A)
+ s1p = 2 * math.pi
+ # Loop through the following while condition is true.
+ while abs(s1 - s1p) > 1e-12:
+ cs1m = cos(2 * s2 + s1)
+ ss1 = sin(s1)
+ cs1 = cos(s1)
+ ds1 = B * ss1 * (
+ cs1m + B / 4 * (
+ cs1 * (-1 + 2 * cs1m * cs1m) - B / 6 * cs1m * (-3 + 4 * ss1 * ss1) * (-3 + 4 * cs1m * cs1m)))
+ s1p = s1
+ s1 = s / (b * A) + ds1
+ # Continue calculation after the loop.
+ t = su1 * ss1 - cu1 * cs1 * cb
+ lat2 = atan2(su1 * cs1 + cu1 * ss1 * cb, (1 - f) * sqrt(sa * sa + t * t))
+ l2 = atan2(ss1 * sb, cu1 * cs1 - su1 * ss1 * cb)
+ c = f / 16 * csa * (4 + f * (4 - 3 * csa))
+ l = l2 - (1 - c) * f * sa * (s1 + c * ss1 * (cs1m + c * cs1 * (-1 + 2 * cs1m * cs1m)))
+ d = atan2(sa, -t)
+ finalBrg = d + 2 * math.pi
+ backBrg = d + math.pi
+ lon2 = lon1 + l
+ # Convert lat2, lon2, finalBrg and backBrg to degrees
+ lat2 = degrees(lat2)
+ lon2 = degrees(lon2)
+ finalBrg = degrees(finalBrg)
+ backBrg = degrees(backBrg)
+ # b = a - (a/flat)
+ # flat = a / (a - b)
+ finalBrg = (finalBrg + 360) % 360
+ backBrg = (backBrg + 360) % 360
+
+ return (lat2, lon2, finalBrg, backBrg)
+
+ def bearing(self, lat1, lon1, lat2, lon2):
+ lat1 = math.radians(float(lat1))
+ lon1 = math.radians(float(lon1))
+ lat2 = math.radians(float(lat2))
+ lon2 = math.radians(float(lon2))
+ dLon = (lon2 - lon1)
+
+ y = math.sin(dLon) * math.cos(lat2)
+ x = math.cos(lat1) * math.sin(lat2) - math.sin(lat1) * math.cos(lat2) * math.cos(dLon)
+ brng = math.degrees(math.atan2(y, x))
+
+ return (brng + 360) % 360
+
+
+class VectorLoader():
+ def __init__(self, database):
+ self.db = database
+
+ def selectNodes(self):
+ sql = 'SELECT nodeid, lat, long FROM %s.node;' % self.db.dataSchema
+ return self.db.connection.executeSql(sql, True, True)
+
+ def selectRainGagues(self):
+ sql = 'SELECT gaugeid, lat, long FROM %s.%s;' % (self.db.dataSchema, self.db.rgaugeTableName)
+ return self.db.connection.executeSql(sql, True, True)
+
+ def getASCIInodes(self, selectedPoints):
+ newline = '\n'
+ pointsASCI = 'VERTI:\n'
+ for point in selectedPoints:
+ pointsASCI += 'P 1 1' + newline # primitive P(point), num of coordinates,num of categories
+ pointsASCI += str(point[2]) + ' ' + str(point[1]) + newline # coordination of point
+ pointsASCI += '1' + ' ' + str(point[0]) + newline # first layer, cat=id of point(nodeid)
+ return pointsASCI
+
+ def selectLinks(self, distance=False):
+ if not distance:
+ sql = 'SELECT l.linkid, n1.lat, n1.long ,n2.lat, n2.long \
+ FROM %s.node as n1\
+ JOIN %s.link as l \
+ ON n1.nodeid=fromnodeid\
+ JOIN %s.node as n2 \
+ ON n2.nodeid= tonodeid;' % (self.db.dataSchema,
+ self.db.dataSchema,
+ self.db.dataSchema)
+ else:
+ sql = 'SELECT l.linkid,l.lenght, n1.lat, n1.long ,n2.lat, n2.long \
+ FROM %s.node as n1\
+ JOIN %s.link as l \
+ ON n1.nodeid=fromnodeid\
+ JOIN %s.node as n2 \
+ ON n2.nodeid= tonodeid;' % (self.db.dataSchema,
+ self.db.dataSchema,
+ self.db.dataSchema)
+ return self.db.connection.executeSql(sql, True, True)
+
+ def getASCIIlinks(self, selectedLinks):
+ newline = '\n'
+ linksASCII = 'VERTI:\n'
+ for link in selectedLinks:
+ linksASCII += 'L 2 1' + newline # primitive L(line), num of coordinates,num of categories
+ linksASCII += str(link[2]) + ' ' + str(link[1]) + newline
+ linksASCII += str(link[4]) + ' ' + str(link[3]) + newline
+ linksASCII += '1' + ' ' + str(link[0]) + newline # first layer, cat=id of point(nodeid)
+ return linksASCII
+
+ def grass_vinASCII(self, asciiStr, outMapName):
+ currDir = os.path.dirname(os.path.realpath(__file__))
+ tmpFile = os.path.join(currDir, 'tmp')
+ f = open(tmpFile, 'w')
+ f.write(asciiStr)
+ f.close()
+ grass.run_command('v.in.ascii',
+ input=tmpFile,
+ format='standard',
+ output=outMapName,
+ quiet=True,
+ overwrite=True)
+ os.remove(tmpFile)
+
+class RainGauge():
+ def __init__(self, database, pathfile):
+ self.db = database
+ self.rgpath = pathfile
+ self.schemaPath = database.pathworkSchemaDir
+ self.schema = database.schema
+ self.gaugeid = None
+ self.lat = None
+ self.lon = None
+
+ file_list = getFilesInFoldr(self.rgpath)
+ for file in file_list:
+ path = os.path.join(self.rgpath, file)
+ self.readRaingauge(path)
+
+ def readRaingauge(self, path):
+ # get coordinates from header and id
+ try:
+ with open(path, 'rb') as f:
+ self.gaugeid = int(f.next())
+ self.lat = float(f.next())
+ self.lon = float(f.next())
+ f.close()
+ except IOError as (errno, strerror):
+ print "I/O error({0}): {1}".format(errno, strerror)
+
+ gaugeTMPfile = "gauge_tmp"
+ removeLines(old_file=path,
+ new_file=os.path.join(self.schemaPath, gaugeTMPfile),
+ start=0,
+ end=3)
+ # #prepare list of string for copy to database
+ try:
+ with open(os.path.join(self.schemaPath, gaugeTMPfile), 'rb') as f:
+ data = f.readlines()
+ tmp = []
+ for line in data:
+ stri = str(self.gaugeid) + ',' + line
+ tmp.append(stri)
+ f.close()
+ except IOError as (errno, strerror):
+ print "I/O error({0}): {1}".format(errno, strerror)
+
+ #write list of string to database
+ try:
+ with open(os.path.join(self.schemaPath, gaugeTMPfile), 'wr') as io:
+ io.writelines(tmp)
+ io.close()
+ except IOError as (errno, strerror):
+ print "I/O error({0}): {1}".format(errno, strerror)
+
+ if not isTableExist(self.db.connection, self.schema, self.db.rgaugeTableName):
+ # #create table for raingauge stations
+ sql = "create table %s.%s (gaugeid integer PRIMARY KEY,lat real,long real ) " % (
+ self.schema, self.db.rgaugeTableName)
+ self.db.connection.executeSql(sql, False, True)
+
+ # # create table for rain gauge records
+ sql = ' CREATE TABLE %s.%s \
+ (gaugeid integer NOT NULL,\
+ "time" timestamp without time zone NOT NULL,\
+ precip real,\
+ CONSTRAINT recordrg PRIMARY KEY (gaugeid, "time"),\
+ CONSTRAINT fk_record_rgague FOREIGN KEY (gaugeid)\
+ REFERENCES %s.%s (gaugeid) MATCH SIMPLE\
+ ON UPDATE NO ACTION ON DELETE NO ACTION)' % (
+ self.schema, self.db.rgaugRecord, self.schema, self.db.rgaugRecord)
+ self.db.connection.executeSql(sql, False, True)
+
+ # insert rain gauge station to table
+ sql = "Insert into %s.%s ( gaugeid , lat , long) values (%s , %s , %s) " % \
+ (self.schema, self.db.rgaugeTableName, self.gaugeid, self.lat, self.lon)
+ self.db.executeSql(sql, False, True)
+ # copy records in database
+ io = open(os.path.join(self.schemaPath, gaugeTMPfile), "r")
+ self.db.copyfrom(io, "%s.%s" % (self.schema, self.db.rgaugRecord), ',')
+ io.close()
+ os.remove(os.path.join(self.schemaPath, gaugeTMPfile))
+
+class Baseline():
+ def __init__(self, type, pathToFile, statFce='mode', quantile=97, roundMode=3, aw=0):
+ self.quantile = quantile
+ self.roundMode = roundMode
+ self.aw = aw
+ self.pathToFile = pathToFile
+ self.type = type
+ self.statFce = statFce
+
+ if statFce == 'mode':
+ if self.roundMode is None:
+ grass.fatal('Value "round" is missing.')
+ if statFce == 'quantile':
+ if self.quantile is None:
+ grass.fatal('Value "quentile" is missing.')
+ if self.type == 'fromDryWin':
+ if self.pathToFile is None:
+ grass.fatal('Dry interval is not defined.')
+ if self.type == 'values':
+ if self.pathToFile is None:
+ grass.fatal('Baseline values are not defined.')
+
+ print self.pathToFile
+
+class TimeWindows():
+ def __init__(self, database, IDtype, sumStep, startTime=None,
+ endTime=None, linksIgnored=False, linksOnly=False, links=None, linksMap=None):
+ self.linksMap = linksMap # name of map selected by user. in this case the links vector map is changed
+ self.startTime = startTime
+ self.endTime = endTime
+ self.sumStep = sumStep
+ self.database = database
+ self.db = database.connection
+ self.path = database.pathworkSchemaDir
+ self.schema = database.schema
+ self.typeID = IDtype
+ self.viewStatement = database.viewStatement
+ self.tbName = database.computedPrecip
+ self.links = links #
+ self.linksIgnored = linksIgnored # if true: remove self.link else:
+ self.linksOnly = linksOnly # compute only links
+
+ self.viewDB = None
+ self.intervalStr = None
+ self.timestamp_max = None
+ self.timestamp_min = None
+ self.temporalRegPath = None
+ self.numWindows = 0
+
+ if self.sumStep == "minute":
+ self.intervalStr = 60
+
+ elif self.sumStep == "hour":
+ self.intervalStr = 3600
+ else:
+ self.intervalStr = 86400
+
+ def createWin(self):
+ self.sumValues()
+ # self.setTimestamp()
+ if not self.linksMap:
+ if self.linksIgnored:
+ self.removeLinksIgnore()
+ if self.linksOnly:
+ self.removeLinksOthers()
+ else:
+ self.database.linkVecMapName = self.linksMap
+
+ self.crateTimeWin()
+
+ def sumValues(self):
+ # #summing values per (->user)timestep interval
+ self.viewDB = 'computed_precip_sum'
+ sql = "CREATE %s %s.%s as \
+ SELECT %s ,round(avg(precip)::numeric,3) as %s, date_trunc('%s',time)as time \
+ FROM %s.%s \
+ GROUP BY %s, date_trunc('%s',time)\
+ ORDER BY time" % (self.viewStatement, self.schema, self.viewDB, self.typeID, \
+ self.database.precipColName, self.sumStep, self.schema, self.tbName, self.typeID,
+ self.sumStep)
+ self.database.connection.executeSql(sql, False, True)
+
+ def setTimestamp(self):
+ self.timestamp_min = self.database.minTimestamp()
+ self.timestamp_max = self.database.maxTimestamp()
+
+ # check if set time by user is in dataset time interval
+ if self.startTime is not None:
+ self.startTime = datetime.strptime(str(self.startTime), "%Y-%m-%d %H:%M:%S")
+
+ if self.timestamp_min > self.startTime:
+ self.logMsg("'startTime' value is not in temporal dataset ")
+ return False
+ else:
+ self.timestamp_min = self.startTime
+ self.timestamp_min = roundTime(self.timestamp_min, self.intervalStr)
+
+ if self.endTime is not None:
+ self.endTime = datetime.strptime(str(self.endTime), "%Y-%m-%d %H:%M:%S")
+ if self.timestamp_max < self.endTime:
+ self.logMsg("'endTime' value is not in temporal dataset")
+ return False
+ else:
+ self.timestamp_max = self.endTime
+ self.timestamp_max = roundTime(self.timestamp_max, self.intervalStr)
+
+ return True
+
+ def removeLinksIgnore(self):
+ '''Remove ignored links'''
+ '''
+ try:
+ with open(self.ignoredIDpath, 'r') as f:
+ for link in f.read().splitlines():
+ sql = "DELETE FROM %s.%s WHERE %s=%s " % (self.schema, self.viewDB, self.typeID, link)
+ self.database.connection.executeSql(sql, False, True)
+ except IOError as (errno, strerror):
+ grass.fatal('Cannot open file with ingored files')
+ '''
+ for link in self.links.split(','):
+ sql = "DELETE FROM %s.%s WHERE %s=%s " % (self.schema, self.viewDB, self.typeID, link)
+ self.database.connection.executeSql(sql, False, True)
+
+ def removeLinksOthers(self):
+ '''Remove not selected links'''
+ sql = 'CREATE TABLE %s.linktmp(linkid int NOT NULL PRIMARY KEY) ' % self.schema
+ self.database.connection.executeSql(sql, False, True)
+
+ for link in self.links.split(','):
+ sql = 'INSERT INTO %s.linktmp values (%s);' % (self.schema, link) # TODO OPTIMALIZE
+ self.database.connection.executeSql(sql, False, False)
+
+ sql = 'DROP TABLE %s.linktmp ' % self.schema
+ self.database.connection.executeSql(sql, False, True)
+
+ sql = 'DELETE FROM %s.%s WHERE NOT EXISTS\
+ (SELECT %s FROM %s.linktmp \
+ WHERE %s.%s.%s=linksonly.%s)' % (self.schema, self.viewDB,
+ self.typeID, self.schema,
+ self.schema, self.viewDB, self.typeID, self.typeID)
+ self.database.connection.executeSql(sql, False, True)
+
+ def crateTimeWin(self):
+ grass.message('creating time windows')
+ time_const = 0
+ nameList = []
+ tgrass_vector = []
+ cur_timestamp = self.timestamp_min
+ prefix = 'l'
+ if self.typeID == 'gaugeid':
+ prefix = 'g'
+
+ grass.message("from " + str(self.timestamp_min) + " to " + str(self.timestamp_max) + " per " + self.sumStep)
+ # make timewindows from time interval
+ while cur_timestamp < self.timestamp_max:
+ self.numWindows += 1
+ # create name of
+ a = time.strftime("%Y_%m_%d_%H_%M", time.strptime(str(cur_timestamp), "%Y-%m-%d %H:%M:%S"))
+ view_name = "%s%s%s" % (prefix, self.database.viewStatement, a)
+ vw = view_name + "\n"
+ nameList.append(vw)
+
+ # text format for t.register ( temporal grass)
+ if self.typeID == 'linkid':
+ tgrass = view_name + '|' + str(cur_timestamp) + "\n"
+ tgrass_vector.append(tgrass)
+ else:
+ tgrass = view_name + '|' + str(cur_timestamp) + "\n"
+ tgrass_vector.append(tgrass)
+
+ sql = "CREATE TABLE %s.%s as\
+ SELECT * from %s.%s \
+ WHERE time=(timestamp'%s'+ %s * interval '1 second')" % \
+ ( self.schema, view_name,
+ self.schema, self.viewDB,
+ self.timestamp_min,
+ time_const)
+
+ data = self.database.connection.executeSql(sql, False, True)
+ # compute current timestamp (need for loop)
+
+ # sql = "SELECT (timestamp'%s')+ %s* interval '1 second'" % (cur_timestamp, self.intervalStr)
+ # cur_timestamp = self.database.connection.executeSql(sql)[0][0]
+ #rint cur_timestamp
+ #print timedelta(seconds=1)
+ #print self.intervalStr
+ cur_timestamp = cur_timestamp + self.intervalStr * timedelta(seconds=1)
+
+ # go to next time interval
+ time_const += self.intervalStr
+
+ if self.typeID == 'linkid':
+ TMPname = 'l_timewindow'
+ else:
+ TMPname = 'g_timewindow'
+ try:
+ io2 = open(os.path.join(self.path, TMPname), "wr")
+ io2.writelines(nameList)
+ io2.close()
+ except IOError as (errno, strerror):
+ grass.fatal('Cannot write temporal registration file %s' % os.path.join(self.path, TMPname))
+
+ # creating textfile for t.register input
+ filename = "timewin_%s" % prefix + "vec_" + str(self.timestamp_min).replace(' ', '_') + "|" + str(
+ self.timestamp_max).replace(' ', '_')
+ try:
+ self.temporalRegPath = os.path.join(self.path, filename)
+ io4 = open(self.temporalRegPath, "wr")
+ io4.writelines(tgrass_vector)
+ io4.close()
+ except IOError as (errno, strerror):
+ grass.fatal('Cannot write temporal reg file %s' % os.path.join(self.path, TMPname))
+
+ # drop temp table
+ # sql = "DROP TABLE %s.%s" % (self.schema, self.database.recordTableName)
+ grass.message('creating time windows-done')
+
+class Computor():
+ def __init__(self, baseline, timeWin, database, exportData):
+ self.awConst = baseline.aw
+ self.database = database
+ self.baseline = baseline
+ self.timeWin = timeWin
+ self.baselineDict = None
+ self.status = {}
+ self.status['bool'] = False
+ self.status['msg'] = 'Done'
+
+ self.cleanDatabase()
+
+ if self.computePrecip(exportData['getData'], exportData['dataOnly']): # if export data only
+ self.timeWin.createWin()
+ self.status['bool'] = True
+
+ def GetStatus(self):
+ return self.status.get('bool'), self.status.get('msg')
+
+ def ExportData(self):
+ pass
+
+ def cleanDatabase(self):
+ sql = "DROP schema IF EXISTS %s CASCADE" % self.database.schema
+ shutil.rmtree(self.database.pathworkSchemaDir)
+ os.makedirs(self.database.pathworkSchemaDir)
+ self.database.connection.executeSql(sql, False, True)
+ sql = "CREATE schema %s" % self.database.schema
+ self.database.connection.executeSql(sql, False, True)
+
+ def getBaselDict(self):
+ '''@note returns disct - key:linkid'''
+ baseline = self.baseline
+ database = self.database
+ tMin=self.timeWin.timestamp_min
+ tMax=self.timeWin.timestamp_max
+
+ def computeBaselinFromMode(recordTable):
+ sql = "SELECT linkid from %s group by 1" % recordTable
+ linksid = database.connection.executeSql(sql, True, True)
+
+ # round value
+ sql = "CREATE TABLE %s.tempround as SELECT round(a::numeric,%s) as a, linkid FROM %s" % (
+ database.schema, baseline.roundMode, recordTable)
+ database.connection.executeSql(sql, False, True)
+
+ # compute mode for current link
+ tmp = []
+ for linkid in linksid:
+ linkid = linkid[0]
+ sql = "SELECT mode(a) AS modal_value FROM %s.tempround where linkid=%s;" % (
+ database.schema, linkid)
+ resu = database.connection.executeSql(sql, True, True)[0][0]
+ tmp.append(str(linkid) + ',' + str(resu) + '\n')
+
+ sql = "DROP TABLE %s.tempround" % database.schema
+ database.connection.executeSql(sql, False, True)
+ io0 = open(os.path.join(database.pathworkSchemaDir, "baseline"), "wr")
+ io0.writelines(tmp)
+ io0.close()
+
+ # io1 = open(os.path.join(database.pathworkSchemaDir, "compute_precip_info"), "wr")
+ # io1.write('mode|' + str(baseline.aw))
+ # io1.close
+
+ def computeBaselineFromTime():
+ def chckTimeValidity(tIn):
+ #print tIn
+ tIn=str(tIn).replace("\n", "")
+
+ tIn=datetime.strptime(tIn, "%Y-%m-%d %H:%M:%S")
+ if tIn > tMax or tIn < tMin:
+ return False
+ return True
+
+ # ################################
+ # @function for reading file of intervals or just one moments when dont raining.#
+ # @format of input file(with key interval):
+ # interval
+ # 2013-09-10 04:00:00
+ # 2013-09-11 04:00:00
+ #
+ # @just one moment or moments
+ # 2013-09-11 04:00:00
+ # 2013-09-11 04:00:00
+ # ###############################
+ #@typestr choose statistical method for baseline computing.
+ # typestr='avg'
+ # typestr='mode'
+ # typestr='quantile'
+ ################################
+ tmp = []
+ st = ''
+ #print baseline.statFce
+ ######## AVG ##########
+ if baseline.statFce == 'avg':
+ try:
+ #print baseline.pathToFile
+ f = open(baseline.pathToFile, 'r')
+ except IOError as (errno, strerror):
+ print baseline.pathToFile
+ grass.fatal('Path to file with dry-window definiton not exist; %s' % baseline.pathTofile)
+
+ for line in f:
+ st += line.replace("\n", "")
+ if 'i' in line.split("\n")[0]: #get baseline form interval
+ fromt = f.next()
+ if not chckTimeValidity( fromt):
+ return False
+ st += fromt.replace("\n", "")
+ tot = f.next()
+ if not chckTimeValidity( tot):
+ return False
+ #validate input data
+ if not isTimeValid(fromt) or not isTimeValid(tot):
+ grass.warning("Input data are not valid. Parameter 'baselitime'")
+ return False
+
+ st += tot.replace("\n", "")
+ sql = "SELECT linkid, avg(a) FROM %s.record \
+ WHERE time >='%s' AND time<='%s' group by linkid order by 1" % (
+ database.schema, fromt, tot)
+ resu = database.connection.executeSql(sql, True, True)
+ tmp.append(resu)
+
+ else: # baseline one moment
+ time = line.split("\n")[0]
+ #validate input data
+ if not isTimeValid(time):
+ grass.warning("Input data are not valid. Parameter 'baselitime'")
+ return False
+
+ time = datetime.strptime(time, "%Y-%m-%d %H:%M:%S")
+ st += str(time).replace("\n", "")
+ fromt = time + timedelta(seconds=-60)
+ if not chckTimeValidity(fromt):
+ return False
+ tot = time + timedelta(seconds=+60)
+ if not chckTimeValidity(tot):
+ return False
+ sql = "SELECT linkid, avg(a) FROM %s.record \
+ WHERE time >='%s' AND time<='%s' group by linkid order by 1" % (
+ database.schema, fromt, tot)
+ resu = database.connection.executeSql(sql, True, True)
+ tmp.append(resu)
+ continue
+
+ mydict1 = {}
+ i = True
+ #print(tmp)
+ # sum all baseline per every linkid from get baseline dataset(next step avg)
+ for dataset in tmp:
+ mydict = {int(rows[0]): float(rows[1]) for rows in dataset}
+ if i is True:
+ mydict1 = mydict
+ i = False
+ continue
+ for link in dataset:
+ mydict1[link] += mydict[link]
+
+ length = len(tmp)
+ links = len(tmp[0])
+ i = 0
+ # print mydict1
+ #compute avg(divide sum by num of datasets)
+ for dataset in tmp:
+ for link in dataset:
+ i += 1
+ #print link
+ #print mydict1[link]#TODO chck
+ mydict1[link[0]] /= length
+ if i == links:
+ break
+ break
+
+ #write values to baseline file
+ writer = csv.writer(open(os.path.join(database.pathworkSchemaDir, 'baseline'), 'wr'))
+ for key, value in mydict1.items():
+ writer.writerow([key, value])
+
+ ######## MODE or QUANTILE ##########
+ elif baseline.statFce == 'mode' or baseline.statFce == 'quantile':
+ #print 'mode***'
+ try:
+ print baseline.pathToFile
+ f = open(baseline.pathToFile, 'r')
+ except IOError as (errno, strerror):
+ grass.warning('Path to file with dry-window definiton not exist')
+ return False
+ #parse input file
+ for line in f:
+ st += line.replace("\n", "")
+ if 'i' in line.split("\n")[0]: #get baseline intervals
+ fromt = f.next()
+ if not chckTimeValidity(fromt):
+ return False
+ st += fromt.replace("\n", "")
+ tot = f.next()
+ if not chckTimeValidity(tot):
+ return False
+ #validate input data
+ if not isTimeValid(fromt) or not isTimeValid(tot):
+ grass.warning("Input data are not valid. Parameter 'baselitime'")
+ return False
+ st += tot.replace("\n", "")
+ sql = "SELECT linkid, a from %s.record WHERE time >='%s' and time<='%s'" % (
+ database.schema, fromt, tot)
+ resu = database.connection.executeSql(sql, True, True)
+ resu += resu
+
+ else: #get baseline one moment
+ time = line.split("\n")[0]
+ if not isTimeValid(time):
+ grass.warning("Input data are not valid. Parameter 'baselitime'")
+ return False
+ time = datetime.strptime(time, "%Y-%m-%d %H:%M:%S")
+ st += str(time).replace("\n", "")
+ fromt = time + timedelta(seconds=-60)
+ if not chckTimeValidity(fromt):
+ return False
+ tot = time + timedelta(seconds=+60)
+ if not chckTimeValidity(tot):
+ return False
+
+ sql = "SELECT linkid, a from %s.record WHERE time >='%s' and time<='%s'" % (
+ database.schema, fromt, tot)
+ resu = database.connection.executeSql(sql, True, True)
+ resu += resu
+ continue
+
+ tmp.append(resu)
+ table_mode_tmp = "mode_tmp"
+ sql = "CREATE TABLE %s.%s ( linkid integer,a real);" % (database.schema, table_mode_tmp)
+ database.connection.executeSql(sql, False, True)
+
+ #write values to flat file
+ io = open(os.path.join(database.pathworkSchemaDir, "mode_tmp"), "wr")
+ c = 0
+ for it in tmp:
+ for i in it:
+ a = str(i[0]) + "|" + str(i[1]) + "\n"
+ io.write(a)
+ c += 1
+ io.close()
+
+ #update table
+ try:
+ io1 = open(os.path.join(database.pathworkSchemaDir, "mode_tmp"), "r")
+ database.connection.copyfrom(io1, "%s.%s" % (database.schema, table_mode_tmp))
+ io1.close()
+ os.remove(os.path.join(database.pathworkSchemaDir, "mode_tmp"))
+ except IOError as (errno, strerror):
+ grass.warning('Cannot open mode_tmp file')
+ return False
+
+ recname = database.schema + '.' + table_mode_tmp
+
+ if baseline.statFce == 'mode':
+ computeBaselinFromMode(recname)
+
+ if baseline.statFce == 'quantile':
+ computeBaselineFromQuentile(recname)
+
+ sql = "DROP TABLE %s.%s" % (database.schema, table_mode_tmp)
+ database.connection.executeSql(sql, False, True)
+
+ #write unique mark to file
+ io1 = open(os.path.join(database.pathworkSchemaDir, "compute_precip_info"), "wr")
+ st = st + '|' + str(baseline.aw)
+ io1.write(st)
+ io1.close
+ return True
+
+ def computeBaselineFromQuentile(recordTable):
+ sql = "SELECT linkid from %s group by linkid" % recordTable
+ linksid = database.connection.executeSql(sql, True, True)
+ tmp = []
+ # for each link compute baseline
+ for linkid in linksid:
+ linkid = linkid[0]
+ sql = "SELECT\
+ max(a) as maxAmount,\
+ avg(a) as avgAmount,\
+ quartile\
+ FROM (SELECT a, ntile(%s) OVER (order by a) as quartile\
+ FROM %s where linkid=%s ) x\
+ GROUP BY quartile\
+ ORDER BY quartile\
+ limit 1" % (baseline.quantile, recordTable, linkid)
+
+ resu = database.connection.executeSql(sql, True, True)
+ #print resu
+ resu=resu[0][0]
+ tmp.append(str(linkid) + ',' + str(resu) + '\n')
+
+ io0 = open(os.path.join(database.pathworkSchemaDir, "baseline"), "wr")
+ io0.writelines(tmp)
+ io0.close()
+
+ io1 = open(os.path.join(database.pathworkSchemaDir, "compute_precip_info"), "wr")
+ io1.write('quantile' + str(baseline.quantile) + '|' + str(baseline.aw))
+ io1.close
+
+ def readBaselineFromText(path):
+ with open(path, mode='r') as infile:
+ reader = csv.reader(infile, delimiter=',')
+ mydict = {float(rows[0]): float(rows[1]) for rows in reader}
+ return mydict
+
+ if self.baseline.type == 'values':
+ #print 'valuesDirectly'
+ self.baselineDict = readBaselineFromText(self.baseline.pathTofile)
+
+ elif self.baseline.type == 'fromDryWin':
+ grass.message('Computing baselines "time interval" "%s"...' % self.baseline.statFce)
+ # print 'fromDryWin'
+ if computeBaselineFromTime():
+ self.baselineDict = readBaselineFromText(os.path.join(database.pathworkSchemaDir, 'baseline'))
+ return True
+ else:
+ return False
+
+ def logMsg(self, msg):
+ if self.status.get('msg') == 'Done':
+ self.status['msg']=''
+ self.status['msg'] += msg + '\n'
+ grass.warning(msg)
+
+ def computePrecip(self, getData=False, dataOnly=False):
+ Aw = float(self.baseline.aw)
+ link_num = self.database.connection.count("link")
+ compPrecTab = "%s.%s" % (self.database.schema, self.database.computedPrecip)
+ # self.timeWin.sumValues()
+ if not self.timeWin.setTimestamp():
+ self.logMsg("Out of available time interval")
+ return False
+ grass.message("Quering data")
+
+ sql = "SELECT linkid,lenght,polarization,frequency \
+ FROM %s.link" % self.database.dataSchema
+ linkResu = self.database.connection.executeSql(sql, True, True)
+ linksDict = {}
+
+ # fill dict by links metadata-> much faster than tables join
+ for link, leng, pol, freq in linkResu:
+ linksInfo = []
+ linksInfo.append(leng)
+ linksInfo.append(pol)
+ linksInfo.append(freq)
+ linksDict[link] = linksInfo
+
+ '''
+ sql = "SELECT linkid,time,txpower-rxpower as a \
+ FROM %s.record \
+ WHERE time >= '%s' AND\
+ time <= '%s' \
+ ORDER by recordid;" % \
+ (self.database.dataSchema,
+ self.timeWin.timestamp_min,
+ self.timeWin.timestamp_max)
+ resu = self.database.connection.executeSql(sql, True, True)
+ '''
+ sql = "CREATE TABLE %s.record AS (SELECT linkid,time,txpower-rxpower as a \
+ FROM %s.record \
+ WHERE time >= '%s' AND\
+ time <= '%s' \
+ ORDER by recordid);" % \
+ (self.database.schema,
+ self.database.dataSchema,
+ self.timeWin.timestamp_min,
+ self.timeWin.timestamp_max)
+ self.database.connection.executeSql(sql, False, True)
+
+ sql = "SELECT * from %s.record" % self.database.schema
+ resu = self.database.connection.executeSql(sql, True, True)
+
+ grass.message("Quering data-done")
+ '''
+ sql = "SELECT n2.time, n2.txpower-n2.rxpower as a,n1.lenght,n1.polarization,n1.frequency,n1.linkid\
+ FROM %s.link AS n1 \
+ JOIN %s.record AS n2 ON n1.linkid = n2.linkid \
+ WHERE n2.linkid = n1.linkid AND\
+ time >= '%s' AND\
+ time <= '%s' \
+ ORDER by n2.recordid;" % \
+ (self.database.dataSchema,
+ self.database.dataSchema,
+ self.timeWin.timestamp_min,
+ self.timeWin.timestamp_max)
+
+ resu = self.database.connection.executeSql(sql, True, True)
+ '''
+
+ sql = "CREATE TABLE %s ( linkid integer,time timestamp, precip real);" % compPrecTab
+ self.database.connection.executeSql(sql, False, True)
+
+ # optimalization of commits
+ self.database.connection.setIsoLvl(0) #TODO dont know what is that
+
+ # choose baseline source (quantile, user values, ) get dict linkid, baseline
+ grass.message("Computing baseline")
+ if not self.getBaselDict():
+ self.logMsg('Dry interval is out of defined time interval(from,to)')
+ return False
+ if len(self.baselineDict) == 0:
+ self.logMsg('Baselines coputation faild. Check dry windows')
+ return False
+ grass.message("Computing baseline-done")
+
+ # check if baseline from text is correct
+ if len(self.baselineDict) < link_num:
+ sql = "SELECT linkid FROM link"
+ links = self.database.connection.executeSql(sql, True, True)
+ for link in links:
+ # grass.message(type(link))
+ if not link[0] in self.baselineDict:
+ grass.message("Linkid= %s is missing in txtfile" % str(link[0]))
+ grass.message(
+ 'Missing values "linkid,baseline," in text file. Data are not available in dry interval(baseline) .')
+
+ temp = []
+ grass.message("Computing precipitation")
+ skippedList=[]
+ for record in resu:
+ curLinkData = linksDict[record[0]] # record[0] is linkid
+
+ if curLinkData[1] is None:
+ if not record[0] in skippedList:
+ curLinkData[1] = 'V' # TODO REMOVE THIS!!!!!!!!!!!!!!!!
+ #self.logMsg('Polarization value is missing. Linkid<%s> wil be skipped' % record[0])
+ #skippedList.append(record[0])
+ continue
+ # if missing baseline. Link will be skip
+ if record[0] in self.baselineDict and (curLinkData[2] / 1000000) > 10: #TODO
+ # coef_a_k[alpha, k]
+ coef_a_k = self.computeAlphaK(curLinkData[2], curLinkData[1])
+
+ #read value from dictionary
+ baseline_decibel = (self.baselineDict[record[0]])
+
+ #final precipiatation is R1
+ Ar = record[2] - baseline_decibel - Aw
+ #TODO check this condition
+ '''computePrecip
+ R1 = (yr / coef_a_k[1]) ** (1 / coef_a_k[0])
+ ValueError: negative number cannot be raised to a fractional
+ power
+ '''
+ if Ar > 0:
+ yr = Ar / curLinkData[0]
+ R1 = (yr / coef_a_k[1]) ** (1 / coef_a_k[0])
+ #print R1
+ else:
+ R1 = 0
+
+ #string for output flatfile
+ out = str(record[0]) + "|" + str(record[1]) + "|" + str(R1) + "\n"
+ temp.append(out)
+
+ grass.message("Computing precipitation-done")
+ # write values to flat file
+ # print temp
+ pathExp = os.path.join(self.database.pathworkSchemaDir, "precip")
+ io = open(pathExp, "wr")
+ io.writelines(temp)
+ io.close()
+ #if getData:
+ grass.message("Computed data has been saved to <%s>" % pathExp)
+ grass.message("File structure is <linkid> <time> <precipitation>")
+ if dataOnly:
+ return False
+
+ grass.message("Writing computed precipitation to database...")
+ io1 = open(os.path.join(self.database.pathworkSchemaDir, "precip"), "r")
+ self.database.connection.copyfrom(io1, compPrecTab)
+ #grass.message("Done")
+ #
+ return True
+
+ def computeAlphaK(self, freq, polarization):
+ """@RECOMMENDATION ITU-R P.838-3
+ Specific attenuation model for rain for use in prediction methods
+ γR = kR^α
+ return kv and αv (vertical polarization)
+ return kh and αh (horizontal polarization)
+ """
+ freq /= 1000000
+
+ if polarization == "h":
+ # Coefficients for kH 1
+ aj_kh = (-5.33980, -0.35351, -0.23789, -0.94158)
+ bj_kh = (-0.10008, 1.26970, 0.86036, 0.64552)
+ cj_kh = (1.13098, 0.45400, 0.15354, 0.16817)
+ mk_kh = -0.18961
+ ck_kh = 0.71147
+
+ # Coefficients for αH 3
+ aj_ah = (-0.14318, 0.29591, 0.32177, -5.37610, 16.1721)
+ bj_ah = (1.82442, 0.77564, 0.63773, -0.96230, -3.29980)
+ cj_ah = (-0.55187, 0.19822, 0.13164, 1.47828, 3.43990)
+ ma_ah = 0.67849
+ ca_ah = -1.95537
+ kh = 0
+ ah = 0
+
+ # kh.. coefficient k of horizontal polarization
+ for j in range(0, len(aj_kh)):
+ frac_kh = -math.pow(((math.log10(freq) - bj_kh[j]) / cj_kh[j]), 2)
+ kh += aj_kh[j] * math.exp(frac_kh)
+
+ kh = 10 ** (kh + mk_kh * math.log10(freq) + ck_kh)
+
+ # ah.. coefficient α of horizontal polarization
+ for j in range(0, len(aj_ah)):
+ frac_ah = -math.pow(((math.log10(freq) - bj_ah[j]) / cj_ah[j]), 2)
+ ah += aj_ah[j] * math.exp(frac_ah)
+
+ ah = ah + ma_ah * math.log10(freq) + ca_ah
+
+ return ah, kh
+
+ else:
+ # Coefficients for kV 2
+ aj_kv = [-3.80595, -3.44965, -0.39902, 0.50167]
+ bj_kv = [0.56934, -0.22911, 0.73042, 1.07319]
+ cj_kv = [0.81061, 0.51059, 0.11899, 0.27195]
+ mk_kv = -0.16398
+ ck_kv = 0.63297
+
+ # Coefficients for αV 4
+ aj_av = [-0.07771, 0.56727, -0.20238, -48.2991, 48.5833]
+ bj_av = [2.33840, 0.95545, 1.14520, 0.791669, 0.791459]
+ cj_av = [-0.76284, 0.54039, 0.26809, 0.116226, 0.116479]
+ ma_av = -0.053739
+ ca_av = 0.83433
+ kv = 0
+ av = 0
+ # kv.. coefficient k of vertical polarization
+ for j in range(0, len(aj_kv)):
+ frac_kv = -math.pow(((math.log10(freq) - bj_kv[j]) / cj_kv[j]), 2)
+ kv += aj_kv[j] * math.exp(frac_kv)
+
+ kv = 10 ** (kv + mk_kv * math.log10(freq) + ck_kv)
+
+ # av.. coefficient α of vertical polarization
+ for j in range(0, len(aj_av)):
+ frac_av = -math.pow(((math.log10(freq) - bj_av[j]) / cj_av[j]), 2)
+ av += aj_av[j] * math.exp(frac_av)
+
+ av = (av + ma_av * math.log10(freq) + ca_av)
+
+ return av, kv
+
+class GrassLayerMgr():
+ def __init__(self, database, color=None, rules=None):
+ self.color = color
+ self.rules = rules
+ self.database = database
+ map = self.connectDBaLayers()
+ if color is not None or rules is not None:
+ self.makeRGB(map)
+
+ def makeRGB(self, map):
+ grass.message('Creating RGB column in database')
+ # print map
+ # print self.database.linkVecMapName
+ # print self.database.precipColName
+ #print self.color
+
+ if self.color is not None:
+ for lay in range(1, self.getNumLayer(self.database.linkVecMapName), 1):
+ Module('v.colors',
+ map=map,
+ use='attr',
+ column=self.database.precipColName,
+ color=self.color,
+ rgb_column='GRASSRGB',
+ layer=lay)
+ if self.rules is not None:
+ for lay in range(1, self.getNumLayer(self.database.linkVecMapName), 1):
+ Module('v.colors',
+ map=map,
+ use='attr',
+ column=self.database.precipColName,
+ rules=self.rules,
+ rgb_column='GRASSRGB',
+ layer=lay)
+ grass.message('Creating RGB column in database-done')
+
+ def getNumLayer(self, map):
+ numLay = Module('v.category',
+ input=map,
+ option='layers',
+ quiet=True,
+ stdout_=PIPE)
+
+ return len(numLay.outputs.stdout.splitlines())
+
+ def getNumLinks(self, map):
+ numLink = Module('v.db.connect',
+ map=map,
+ quiet=True,
+ flags='g',
+ stdout_=PIPE)
+ return len(numLink.outputs.stdout.splitlines())
+
+ def unlinkLayer(self, map):
+ for l in range(1, int(self.getNumLinks(map)), 1):
+ RunCommand('v.db.connect',
+ map=map,
+ flags='d',
+ layer=l,
+ quiet=True)
+
+ for l in range(1, int(self.getNumLayer(map)), 1):
+ RunCommand('v.edit',
+ map=map,
+ tool='catdel',
+ layer=l,
+ cats='1-10000', # TODO
+ quiet=True)
+
+ def connectDBaLayers(self):
+ grass.message('Connecting tables to maps')
+ inputMap = self.database.linkVecMapName
+ self.database.linkVecMapName += '_%s' % self.database.schema
+
+ try:
+ f = open(os.path.join(self.database.pathworkSchemaDir, "l_timewindow"), 'r')
+ except:
+ grass.warning('Cannot connect tables(time-windows) to vector layer')
+ return None
+
+ if grass.find_file(self.database.linkVecMapName, element='vector')['fullname']:
+ self.unlinkLayer(self.database.linkVecMapName)
+ layerNum = 0
+ layStr = ''
+ for win in f.read().splitlines():
+ layerNum += 1
+ layStr += str(layerNum) + ','
+
+ layStr = layStr[:-1]
+ f.close()
+ RunCommand('v.category',
+ input=inputMap,
+ output=self.database.linkVecMapName,
+ option="transfer",
+ overwrite=True,
+ layer=layStr,
+ flags='t',
+ quiet=True)
+
+ try:
+ f = open(os.path.join(self.database.pathworkSchemaDir, "l_timewindow"), 'r')
+ except:
+ grass.fatal('Cannot connect tables(time-windows) to vector layer')
+ layerNum = 0
+ for win in f.read().splitlines():
+ layerNum += 1
+ win = self.database.schema + '.' + win
+
+ RunCommand('v.db.connect',
+ driver='pg',
+ database=self.database.dbName,
+ map=self.database.linkVecMapName,
+ table=win,
+ key='linkid',
+ layer=layerNum,
+ overwrite=True,
+ quiet=True)
+ f.close()
+ grass.message('Connecting tables to maps-done')
+ return self.database.linkVecMapName
+
+
+class GrassTemporalMgr():
+ def __init__(self, database, timeWinConf):
+ self.database = database
+ self.timeWinConf = timeWinConf
+ self.datasetName = database.schema
+ self.datasetTitle = 'MW time dataset'
+ self.datasetTdescription = " IDtype=%s," \
+ "sumStep=%s," \
+ "startTime=%s," \
+ "endTime='%s" % (timeWinConf.typeID,
+ timeWinConf.sumStep,
+ timeWinConf.startTime,
+ timeWinConf.endTime)
+ self.createTimedataset()
+ self.registerMaps()
+
+ def createTimedataset(self, datasetName=None, datasetTitle=None,
+ datasetTdescription=None, temporalType='absolute',
+ semanticType='mean'):
+ if datasetName is None:
+ self.datasetName = self.datasetName
+ if datasetTitle is None:
+ self.datasetTitle = self.datasetTitle
+ if datasetTdescription is None:
+ self.datasetTdescription = self.datasetTdescription
+
+ # print '--'*10
+ # #print self.datasetName
+ # print self.datasetTitle
+ # print self.datasetTdescription
+ # print temporalType
+ # print semanticType
+
+ # ret, err = \
+ RunCommand('t.create',
+ type='stvds',
+ output=self.datasetName,
+ title=self.datasetTitle,
+ description=self.datasetTdescription,
+ temporaltype=temporalType,
+ semantictype=semanticType,
+ overwrite=True)
+ #getErrorMsg=True)
+ #print ret
+ #print err
+
+ def registerMaps(self):
+ grass.message('Registring maps to temporal database')
+ gisenv_grass = grass.gisenv()
+ timeOfLay = self.timeWinConf.timestamp_min
+ regTMP = ""
+ regFilePath = os.path.join(self.database.pathworkSchemaDir, "temporal_reg_file")
+ # print '---'
+ # print self.timeWinConf.numWindows + 1
+ for layer in range(1, self.timeWinConf.numWindows + 1, 1):
+ mapsName = str(self.database.linkVecMapName + ':' + str(layer) + '@' + gisenv_grass['MAPSET'])
+ timeOfLay += timedelta(seconds=self.timeWinConf.intervalStr)
+ regTMP += mapsName + '|' + str(timeOfLay) + '\n'
+
+ io1 = open(regFilePath, "wr")
+ io1.writelines(regTMP), io1.close
+ io1.close()
+ print 'datasetName', self.datasetName
+ print regFilePath
+ RunCommand('t.register',
+ input=self.datasetName,
+ type='vector',
+ file=regFilePath,
+ overwrite=True)
+
+ grass.message('Registring maps to temporal database-done')
+
+
+class Database():
+ def __init__(self, name=None, user=None, password=None,
+ host=None, port=None, nodeVecMapName='node', linkVecMapName='link',
+ linkPointsVecName='linkPoints', workSchema=None, dataSchema=None):
+
+ self.dbName = name
+ self.user = user
+ self.port = port
+ self.password = password
+ self.host = host
+ if workSchema is None:
+ workSchema = 'tmp_' + randomWord(3)
+ self.schema = workSchema
+ if dataSchema is None:
+ dataSchema = 'public'
+ self.dataSchema = dataSchema
+ self.connection = None
+ self.viewStatement = 'table'
+ self.recordTableName = 'record'
+ self.computedPrecip = 'mw_computed_precip'
+ self.computedPrecipGauge = 'rgauge_computed_precip'
+ self.rgaugRecord = 'rgauge_record'
+ self.rgaugeTableName = 'rgauge'
+ self.precipColName = 'precip_mm_h'
+
+ self.nodeVecMapName = nodeVecMapName
+ self.linkVecMapName = linkVecMapName
+ self.linkPointsVecName = linkPointsVecName
+ self.pathworkSchemaDir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "tmp_%s" % self.schema)
+
+ self.pyConnection()
+ if self.host:
+ self.grassConnectionRemote()
+ else:
+ self.grassConnection()
+ self.grassTemporalConnection('postgres')
+ self.firstPreparation()
+ self.prepareDB()
+ self.prepareDir()
+
+ def minTimestamp(self):
+ sql = "SELECT min(time) FROM %s.%s" % (self.dataSchema, self.recordTableName)
+ time = self.connection.executeSql(sql)[0][0]
+ time = roundTime(time, 30)
+ return time
+
+ def maxTimestamp(self):
+ sql = "SELECT max(time) FROM %s.%s" % (
+ self.dataSchema, self.recordTableName)
+ time = self.connection.executeSql(sql)[0][0]
+ time = roundTime(time, 30)
+ return time
+
+ def grassTemporalConnection(self, db):
+ if db == 'postgres':
+ conninfo = 'dbname= ' + self.dbName
+ if self.user:
+ conninfo += ' user= ' + self.user
+ if self.password:
+ conninfo += ' passwd= ' + self.password
+ if self.host:
+ conninfo += ' host=' + self.host
+
+ if grass.run_command('t.connect',
+ driver='pg',
+ database=conninfo) != 0:
+ grass.warning("Unable to connect to the database by temporal grass driver.")
+ return False #TODO
+ if db == 'sql':
+ grass.run_command('t.connect',
+ flags='d')
+
+ def grassConnection(self):
+ grass.message("Connecting to db-GRASS...")
+ # Unfortunately we cannot test untill user/password is set
+ if self.user or self.password:
+ if grass.run_command('db.login',
+ driver="pg",
+ database=self.dbName,
+ user=self.user,
+ password=self.password) != 0:
+ grass.warning("Cannot login")
+ return False
+
+ # Try to connect
+ if grass.run_command('db.select',
+ quiet=True,
+ flags='c',
+ driver="pg",
+ database=self.dbName,
+ sql="select version()") != 0:
+
+ if self.user or self.password:
+ grass.message("Deleting login (db.login) ...")
+ if grass.run_command('db.login',
+ quiet=True,
+ driver="pg",
+ database=self.dbName,
+ user="", password="") != 0:
+ grass.message("Cannot delete login.")
+ grass.warning("Cannot connect to database.")
+ return False
+
+ if grass.run_command('db.connect', driver="pg", database=self.dbName) != 0:
+ grass.warning("Cannot connect to database.")
+ return False
+
+
+ def grassConnectionRemote(self):
+ conninfo = 'dbname= ' + self.dbName
+ if self.host:
+ conninfo += ' host=' + self.host
+ if self.port:
+ conninfo += ' port=' + str(self.port)
+
+ # Unfortunately we cannot test untill user/password is set
+ if self.user or self.password:
+ grass.run_command('db.login',
+ driver="pg",
+ database=self.dbName,
+ user=self.user,
+ password=self.password)
+
+
+ else:
+ grass.run_command('db.login',
+ quiet=True,
+ driver="pg",
+ database=self.dbName,
+ user="", password="")
+
+ if grass.run_command('db.connect', driver="pg", database=conninfo) != 0:
+ grass.fatal("Unable to connect to the database by grass driver.")
+
+
+ def pyConnection(self):
+ try:
+ conninfo = {'dbname': self.dbName}
+ if self.user:
+ conninfo['user'] = self.user
+ if self.password:
+ conninfo['passwd'] = self.password
+ if self.host:
+ conninfo['host'] = self.host
+ if self.port:
+ conninfo['port'] = self.port
+ self.connection = pg(**conninfo)
+
+ except psycopg2.OperationalError, e:
+ grass.fatal("Unable to connect to the database <%s>. %s" % (self.dbName, e))
+
+ def firstPreparation(self):
+ if not isAttributExist(self.connection, 'public', 'link', 'lenght'):
+ grass.message("Add colum lenght")
+ sql = "ALTER TABLE link ADD COLUMN lenght real; "
+ self.connection.executeSql(sql, False, True)
+
+ # grass.message("Add colum frequency")
+ # sql = "ALTER TABLE link ADD COLUMN frequency real; "
+ # self.connection.executeSql(sql, False, True)
+
+ # grass.message("Optimalization of frequency attribute")
+ # sql = "UPDATE link\
+ # SET frequency = record.frequency\
+ # FROM record\
+ # WHERE record.linkid = link.linkid;"
+ #self.connection.executeSql(sql, False, True)
+
+ #sql = "ALTER TABLE record DROP COLUMN frequency;"
+ #self.connection.executeSql(sql, False, True)
+
+ # TODO
+
+ grass.message("Add function for computing distance ")
+ '''
+ sql=r"CREATE OR REPLACE FUNCTION get_earth_distance1
+ (lon1 Float, lat1 Float, lon2 Float, lat2 Float, Radius Float DEFAULT 6387.7)
+ RETURNS FLOAT AS '
+ -- Convert degrees to radians
+ DECLARE K FLOAT := 57.29577951; v_dist FLOAT;
+ BEGIN
+ -- calculate
+ v_dist := (Radius * ACOS((SIN(Lat1 / K) * SIN(Lat2 / K))
+ + (COS(Lat1 / K) * COS(Lat2 / K) * COS(Lon2 / K - Lon1 / K))));
+ -- Return distance in Km
+ RETURN round(CAST (v_dist AS Numeric),3);
+ END;
+ ' LANGUAGE 'plpgsql';"
+ '''
+ sql = r"CREATE OR REPLACE FUNCTION get_earth_distance1 (lon1 Float, lat1 Float, lon2 Float, lat2 Float, Radius Float DEFAULT 6387.7) RETURNS FLOAT AS ' DECLARE K FLOAT := 57.29577951; v_dist FLOAT; BEGIN v_dist := (Radius * ACOS((SIN(Lat1 / K) * SIN(Lat2 / K)) + (COS(Lat1 / K) * COS(Lat2 / K) * COS(Lon2 / K - Lon1 / K)))); RETURN round(CAST (v_dist AS Numeric),3); END; ' LANGUAGE 'plpgsql';"
+ self.connection.executeSql(sql, False, True)
+
+ grass.message("Computing column lenght")
+ sql = "UPDATE link SET lenght = get_earth_distance1(n1.long,n1.lat,n2.long,n2.lat) \
+ FROM node AS n1 JOIN \
+ link AS l ON n1.nodeid = fromnodeid \
+ JOIN node AS n2 ON n2.nodeid = tonodeid \
+ WHERE link.linkid = l.linkid; "
+ self.connection.executeSql(sql, False, True)
+
+ #grass.message("Add column precip")
+ #sql = "ALTER TABLE record ADD COLUMN precip real; "
+ #self.connection.executeSql(sql, False, True)
+
+ grass.message("Create sequence")
+ sql = "CREATE SEQUENCE serial START 1; "
+ self.connection.executeSql(sql, False, True)
+
+ grass.message("Add column recordid")
+ sql = "ALTER TABLE record add column recordid integer default nextval('serial'); "
+ self.connection.executeSql(sql, False, True)
+
+ grass.message("Create index on recordid")
+ sql = "CREATE INDEX idindex ON record USING btree(recordid); "
+ self.connection.executeSql(sql, False, True)
+
+ sql = "CREATE INDEX timeindex ON record USING btree (time); "
+ self.connection.executeSql(sql, False, True)
+
+ grass.message("Add mode function")
+ sql = "CREATE OR REPLACE FUNCTION _final_mode(anyarray)\
+ RETURNS anyelement AS $BODY$ SELECT a FROM unnest($1)\
+ a GROUP BY 1 ORDER BY COUNT(1) DESC, 1 LIMIT 1;\
+ $BODY$ LANGUAGE 'sql' IMMUTABLE;"
+ self.connection.executeSql(sql, False, True)
+
+ sql = "CREATE AGGREGATE mode(anyelement) (\
+ SFUNC=array_append, \
+ STYPE=anyarray,\
+ FINALFUNC=_final_mode, \
+ INITCOND='{}');"
+ self.connection.executeSql(sql, False, True)
+
+ def prepareDB(self):
+ sql = "DROP schema IF EXISTS %s CASCADE" % self.schema
+ try:
+ shutil.rmtree(self.pathworkSchemaDir)
+ except:
+ os.makedirs(self.pathworkSchemaDir)
+ self.connection.executeSql(sql, False, True)
+ sql = "CREATE schema %s" % self.schema
+ self.connection.executeSql(sql, False, True)
+
+ def prepareDir(self):
+ try:
+ os.makedirs(self.pathworkSchemaDir)
+ except OSError:
+ if not os.path.isdir(self.pathworkSchemaDir):
+ raise
+
+'''
+def main():
+ db = Database(name='tyden')
+ convertor = VectorLoader(db)
+ # create native vector map(nodes)
+ pointsSQL = convertor.selectNodes()
+ # print pointsSQL
+ pointsASCII = convertor.getASCIInodes(pointsSQL)
+ convertor.grass_vinASCII(pointsASCII, db.nodeVecMapName)
+
+ # create native vector map(links)
+ linksSQL = convertor.selectLinks()
+ linksASCII = convertor.getASCIIlinks(linksSQL)
+ convertor.grass_vinASCII(linksASCII, db.linkVecMapName)
+
+ PointInterpolation(2, '', db)
+ # sys.exit()
+ twin = TimeWindows(IDtype='linkid',
+ sumStep='minute',
+ startTime='2014-10-20 01:00:00',
+ endTime='2014-10-20 04:00:00', # TODO check input
+ # startTime='2013-09-09 00:00:00',
+ # endTime='2013-09-10 00:00:00',
+ database=db)
+
+ baseline = Baseline(type='fromDryWin',
+ statFce='mode',
+ pathToFile='/home/matt/Dropbox/MV/test_suite/baseltime2.ref',
+ roundMode=3)
+
+ Computor(baseline, twin, db)
+
+ GrassLayerMgr(db)
+
+ # sys.exit()
+ GrassTemporalMgr(db, twin)
+
+
+ #main()
+'''
\ No newline at end of file
Property changes on: grass-addons/grass7/gui/wxpython/wx.mwprecip/mw3.py
___________________________________________________________________
Added: svn:executable
+ *
Added: grass-addons/grass7/gui/wxpython/wx.mwprecip/mw_util.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.mwprecip/mw_util.py (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.mwprecip/mw_util.py 2015-03-13 17:24:00 UTC (rev 64850)
@@ -0,0 +1,292 @@
+#!/usr/bin/env python
+import re, os, sys
+import random
+import string
+import wx
+import csv
+from datetime import datetime, timedelta
+from gui_core import gselect
+
+
+class SaveLoad(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ saveBtt = wx.Button(parent=self, label='Save')
+ loadBtt = wx.Button(parent=self, label='Load')
+ sizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ sizer.Add(saveBtt, flag=wx.EXPAND)
+ sizer.Add(loadBtt, flag=wx.EXPAND)
+ self.SetSizer(sizer)
+
+
+class BaseInput(wx.Panel):
+ #def __init__(self, parent, label,key, cats=False):
+ def __init__(self, parent, label):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ statText = wx.StaticText(self, id=wx.ID_ANY, label=label)
+ #if cats:
+ #self.ctrl = gselect.VectorCategorySelect(parent=self, giface=self._giface) # TODO gifece
+ #else:
+ self.text = wx.TextCtrl(self, id=wx.ID_ANY)
+ #self.key=key
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(statText, flag=wx.EXPAND)
+ sizer.Add(self.text, flag=wx.EXPAND)
+ self.SetSizer(sizer)
+
+ def GetKey(self):
+ return self.key
+
+ def GetValue(self):
+ value=self.text.GetValue()
+ if value=='':
+ return None
+ else:
+ return value
+
+ def SetValue(self, value):
+ self.text.SetValue((str(value)))
+
+class TextInput(wx.Panel):
+ def __init__(self, parent, label, tmpPath=None):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.tmpPath = tmpPath
+ statText = wx.StaticText(self, id=wx.ID_ANY, label=label)
+ statText2 = wx.StaticText(self, id=wx.ID_ANY, label='or enter values interactively')
+
+ self.pathInput = wx.TextCtrl(self, id=wx.ID_ANY)
+ self.browseBtt = wx.Button(self, id=wx.ID_ANY, label='Browse')
+ self.directInp = wx.TextCtrl(self, id=wx.ID_ANY, size=(0, 70), style=wx.TE_MULTILINE | wx.HSCROLL)
+ self.saveBtt=wx.Button(self,label='Save to new file')
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer2 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer2.Add(self.pathInput, flag=wx.EXPAND, proportion=1)
+ sizer2.Add(self.browseBtt, flag=wx.EXPAND)
+
+
+ sizer.Add(statText, flag=wx.EXPAND)
+ sizer.Add(sizer2, flag=wx.EXPAND)
+ sizer.Add(statText2, flag=wx.EXPAND)
+ sizer.Add(self.directInp, flag=wx.EXPAND)
+ sizer.Add(self.saveBtt)
+
+ self.SetSizer(sizer)
+ self.browseBtt.Bind(wx.EVT_BUTTON, self.onBrowse)
+ self.saveBtt.Bind(wx.EVT_BUTTON,self.setTmpPath)
+ self.firstDirInp = False
+
+ def setTmpPath(self, event):
+ if self.firstDirInp is False:
+ self.firstDirInp = True
+ if self.tmpPath is None:
+ self.tmpPath=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'tmp%s' % randomWord(3))
+ print self.tmpPath
+ self.pathInput.SetValue(str(self.tmpPath))
+
+ io=open(self.tmpPath,'w')
+ io.writelines(self.directInp.GetValue())
+ io.close()
+ print self.directInp.GetValue()
+
+ def onBrowse(self, event):
+ openFileDialog = wx.FileDialog(self, "Open text file", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
+ if openFileDialog.ShowModal() == wx.ID_CANCEL:
+ return # the user changed idea...
+ path = openFileDialog.GetPath()
+ self.firstDirInpActive = False
+ self.pathInput.SetValue(path)
+ if self.SetValue() == -1:
+ # TODO msgbox
+ self.pathInput.SetValue('')
+
+ def GetValue(self):
+ return self.directInp.GetValue()
+
+ def SetValue(self):
+ io = open(self.pathInput.GetValue(), 'r')
+ str = io.read()
+ try:
+ self.directInp.SetValue(str)
+ return 1
+ except IOError as e:
+ print "I/O error({0}): {1}".format(e.errno, e.strerror)
+ return -1
+ except ValueError:
+ print "Could not decode text"
+ return -1
+ except:
+ print "Unexpected error:", sys.exc_info()[0]
+ raise
+ io.close()
+
+ def GetPath(self):
+ path=self.pathInput.GetValue()
+ if path=='':
+ return None
+ else:
+ return path
+
+ def SetPath(self, value):
+ self.firstDirInpActive = True
+ self.pathInput.SetValue(value)
+ if self.SetValue() == -1:
+ # TODO msgbox
+ self.pathInput.SetValue('')
+
+class FileInput(wx.Panel):
+ def __init__(self, parent, label, dir=False, tmpPath=None):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.dir = dir
+ self.tmpPath = tmpPath
+ statText = wx.StaticText(self, id=wx.ID_ANY, label=label)
+
+ self.pathInput = wx.TextCtrl(self, id=wx.ID_ANY)
+ self.browseBtt = wx.Button(self, id=wx.ID_ANY, label='Browse')
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer2 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer2.Add(self.pathInput, flag=wx.EXPAND, proportion=1)
+ sizer2.Add(self.browseBtt, flag=wx.EXPAND)
+
+ sizer.Add(statText, flag=wx.EXPAND)
+ sizer.Add(sizer2, flag=wx.EXPAND)
+
+ self.SetSizer(sizer)
+ self.browseBtt.Bind(wx.EVT_BUTTON, self.onBrowse)
+
+ def onBrowse(self, event):
+ if self.dir:
+ openFileDialog = wx.DirDialog(self, "Choose a directory:",
+ style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST | wx.DD_CHANGE_DIR)
+ if openFileDialog.ShowModal() == wx.ID_CANCEL:
+ return # the user changed idea...
+ path = openFileDialog.GetPath()
+ self.pathInput.SetValue(path)
+
+
+ else:
+ openFileDialog = wx.FileDialog(self, "Choose a file:", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
+ if openFileDialog.ShowModal() == wx.ID_CANCEL:
+ return # the user changed idea...
+ path = openFileDialog.GetPath()
+ self.pathInput.SetValue(path)
+
+
+ def GetPath(self):
+ path=self.pathInput.GetValue()
+ if len(path)!=0:
+ return path
+ else:
+ return None
+
+ def SetPath(self, value):
+ self.pathInput.SetValue(value)
+
+
+def YesNo(parent, question, caption='Yes or no?'):
+ dlg = wx.MessageDialog(parent, question, caption, wx.YES_NO | wx.ICON_QUESTION)
+ result = dlg.ShowModal() == wx.ID_YES
+ dlg.Destroy()
+ return result
+
+
+def getFilesInFoldr(fpath, full=False):
+ try:
+ lis = os.listdir(fpath)
+ except:
+ #GError('canot find folder%s'%fpath)
+ return 0
+ tmp = []
+ for path in lis:
+ if path.find('~') == -1:
+ if full:
+ tmp.append(os.path.join(fpath, path))
+ else:
+ tmp.append(path)
+ if len(tmp) > 0:
+ return tmp
+ else:
+ return 0
+
+
+def isAttributExist(connection, schema, table, columns):
+ sql = "SELECT EXISTS( SELECT * FROM information_schema.columns WHERE \
+ table_schema = '%s' AND \
+ table_name = '%s' AND\
+ column_name='%s');" % (schema, table, columns)
+ return connection.executeSql(sql, True, True)[0][0]
+
+
+def isTableExist(connection, schema, table):
+ sql = "SELECT EXISTS( SELECT * \
+ FROM information_schema.tables \
+ WHERE table_schema = '%s' AND \
+ table_name = '%s');" % (schema, table)
+ return connection.executeSql(sql, True, True)[0][0]
+
+
+def removeLines(old_file, new_file, start, end):
+ '''remove lines between two lines by line number and create new file '''
+ data_list = open(old_file, 'r').readlines()
+ temp_list = data_list[0:start]
+ temp_list[len(temp_list):] = data_list[end:len(data_list)]
+ open(new_file, 'wr').writelines(temp_list)
+
+def OnSaveAs(parent):
+ saveFileDialog = wx.FileDialog(parent, "Save file","", "",
+ "files (*.*)|*.*", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
+
+ if saveFileDialog.ShowModal() == wx.ID_CANCEL:
+ return # the user changed idea...
+
+ # save the current contents in the file
+ # this can be done with e.g. wxPython output streams:
+ output_stream = (saveFileDialog.GetPath())
+ return output_stream
+
+def saveDict(fn, dict_rap):
+ f = open(fn, "wb")
+ w = csv.writer(f)
+ for key, val in dict_rap.items():
+ if val is None or val == '':
+ continue
+ w.writerow([key, val])
+ f.close()
+
+
+def readDict(fn):
+ f = open(fn, 'rb')
+ dict_rap = {}
+ for key, val in csv.reader(f):
+ try:
+ dict_rap[key] = eval(val)
+ except:
+ val = '"' + val + '"'
+ dict_rap[key] = eval(val)
+ f.close()
+ return (dict_rap)
+
+
+def randomWord(length):
+ return ''.join(random.choice(string.lowercase) for i in range(length))
+
+
+def isTimeValid(time):
+ RE = re.compile(r'^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}$')
+ return bool(RE.search(time))
+
+
+def roundTime(dt, roundTo=60):
+ """Round a datetime object to any time laps in seconds
+ dt : datetime.datetime object, default now.
+ roundTo : Closest number of seconds to round to, default 1 minute.
+ Author: Thierry Husson 2012 - Use it as you want but don't blame me.
+ """
+ # if dt == None : dt = datetime.datetime.now()
+ seconds = (dt - dt.min).seconds
+ # // is a floor division, not a comment on following line:
+ rounding = (seconds + roundTo / 2) // roundTo * roundTo # rounding floor
+ return dt + timedelta(0, rounding - seconds, -dt.microsecond)
+
Added: grass-addons/grass7/gui/wxpython/wx.mwprecip/pgwrapper.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.mwprecip/pgwrapper.py (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.mwprecip/pgwrapper.py 2015-03-13 17:24:00 UTC (rev 64850)
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+
+import sys
+import psycopg2 as ppg
+# import psycopg2.extensions
+
+class pgwrapper:
+ def __init__(self, dbname, host='', user='', passwd='',port=''):
+ self.dbname = dbname # Database name which connect to.
+ self.host = host # Host name (default is "localhost")
+ self.user = user # User name for login to the database.
+ self.port=port
+ self.password = passwd # Password for login to the database.
+ self.connection = self.setConnect() # Set a connection to the database
+ self.cursor = self.setCursor() # Generate cursor.
+
+ def setConnect(self):
+ conn_string = "dbname='%s'" % self.dbname
+ if self.user:
+ conn_string += " user='%s'" % self.user
+ if self.host:
+ conn_string += " host='%s'" % self.host
+ if self.password:
+ conn_string += " password='%s'" % self.password
+ if self.port:
+ conn_string += " port='%s'" % self.port
+ try:
+ conn = ppg.connect(conn_string)
+ except:
+ print 'Cannot connect to database'
+
+ return conn
+
+ def setCursor(self):
+ try:
+ return self.connection.cursor()
+ except:
+ print 'cannot set cursor'
+
+ def setIsoLvl(self, lvl='0'):
+ if lvl == 0:
+ self.connection.set_session('read committed')
+ elif lvl == 1:
+ self.connection.set_session(readonly=True, autocommit=False)
+
+
+ def copyfrom(self, afile, table, sep='|'):
+ try:
+ self.cursor.copy_from(afile, table, sep=sep)
+ self.connection.commit()
+
+ except Exception, err:
+ self.connection.rollback()
+ self.print_message(" Catched error (as expected):\n")
+ self.print_message(err)
+
+ pass
+
+ def copyto(self, afile, table, sep='|'):
+ try:
+ self.cursor.copy_to(afile, table, sep=sep)
+ self.connection.commit()
+
+ except Exception, err:
+ self.connection.rollback()
+ self.print_message(" Catched error (as expected):\n")
+ self.print_message(err)
+ pass
+
+
+ def copyexpert(self, sql, data):
+ try:
+ self.cursor.copy_expert(sql, data)
+ except Exception:
+ self.connection.rollback()
+ pass
+
+
+ def executeSql(self, sql, results=True, commit=False):
+ # Excute the SQL statement.
+ # self.print_message (sql)
+
+ print '*'*50
+ print sql
+ print '*'*50
+
+ try:
+ self.cursor.execute(sql)
+ except Exception, e:
+ self.connection.rollback()
+ self.print_message( e.pgerror)
+
+
+ if commit:
+ self.connection.commit()
+
+ if results:
+ # Get the results.
+ results = self.cursor.fetchall()
+ # Return the results.1
+ return results
+
+
+ def count(self, table):
+ """!Count the number of rows.
+ @param table : Name of the table to count row"""
+ sql_count = 'SELECT COUNT(*) FROM ' + table
+ self.cursor.execute(sql_count)
+ n = self.cursor.fetchall()[0][0]
+ return n
+
+ def updatecol(self, table, columns, where=''):
+ """!Update the values of columns.
+ @param table : Name of the table to parse.
+ @param columns : Keys values pair of column names and values to update.
+ @param where : Advanced search option for 'where' statement.
+ """
+ # Make a SQL statement.
+ parse = ''
+ for i in range(len(columns)):
+ parse = parse + '"' + str(dict.keys(columns)[i]) + '"=' + str(dict.values(columns)[i]) + ','
+ parse = parse.rstrip(',')
+
+ if where == '':
+ sql_update_col = 'UPDATE "' + table + '" SET ' + parse
+ else:
+ sql_update_col = 'UPDATE "' + table + '" SET ' + parse + ' WHERE ' + where
+ print "upcol %s" % sql_update_col
+ # Excute the SQL statement.
+ self.cursor.execute(sql_update_col)
+
+ def print_message(self, msg):
+ print '-' * 80
+ print msg
+ print '-' * 80
+ print
+ sys.stdout.flush()
Property changes on: grass-addons/grass7/gui/wxpython/wx.mwprecip/pgwrapper.py
___________________________________________________________________
Added: svn:executable
+ *
Added: grass-addons/grass7/gui/wxpython/wx.mwprecip/wx.mwprecip.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.mwprecip/wx.mwprecip.py (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.mwprecip/wx.mwprecip.py 2015-03-13 17:24:00 UTC (rev 64850)
@@ -0,0 +1,1157 @@
+#!/usr/bin/env python
+
+
+from mw_util import *
+from core.gcmd import GMessage, GError
+
+from gui_core import gselect
+
+class DBconn(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.database = BaseInput(self, label='Name of database')
+ self.schema = BaseInput(self, label='Name of schema')
+ self.host = BaseInput(self, label='Host name')
+ self.user = BaseInput(self, label='User name')
+ self.port = BaseInput(self, label='Port')
+ self.passwd = BaseInput(self, label='Password')
+ # self.saveLoad = SaveLoad(self)
+ self.okBtt = wx.Button(self, wx.ID_OK, label='ok and close')
+ self.okBtt.Bind(wx.EVT_BUTTON, self.saveSettings)
+ if len(settings) > 0:
+ self.loadSettings()
+ self._layout()
+
+ def _layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+
+ panelSizer.Add(self.database, flag=wx.EXPAND)
+ panelSizer.Add(self.schema, flag=wx.EXPAND)
+ panelSizer.Add(self.host, flag=wx.EXPAND)
+ panelSizer.Add(self.user, flag=wx.EXPAND)
+ panelSizer.Add(self.port, flag=wx.EXPAND)
+ panelSizer.Add(self.passwd, flag=wx.EXPAND)
+ panelSizer.AddSpacer(10, 0, wx.EXPAND)
+ # panelSizer.Add(self.saveLoad, flag=wx.EXPAND)
+ panelSizer.Add(self.okBtt, flag=wx.EXPAND)
+
+ self.SetSizerAndFit(panelSizer)
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+
+ try:
+ self.database.SetValue(self.settings['database'])
+ except:
+ print 'err'
+ pass
+ try:
+ self.schema.SetValue(self.settings['schema'])
+ except:
+ pass
+ try:
+ self.host.SetValue(self.settings['host'])
+ except:
+ pass
+ try:
+ self.user.SetValue(self.settings['user'])
+ except:
+ pass
+ try:
+ self.port.SetValue(self.settings['port'])
+ except:
+ pass
+ try:
+ self.passwd.SetValue(self.settings['passwd'])
+ except:
+ pass
+
+ def saveSettings(self, settings=None):
+ if settings is not None:
+ self.settings = settings
+ self.settings['database'] = self.database.GetValue()
+ self.settings['schema'] = self.schema.GetValue()
+ self.settings['host'] = self.host.GetValue()
+ self.settings['user'] = self.user.GetValue()
+ self.settings['port'] = self.port.GetValue()
+ self.settings['passwd'] = self.passwd.GetValue()
+
+ return self.settings
+
+
+class PointInterpolationPanel(wx.Panel):
+ def __init__(self, parent, settings=None):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.interpolState = wx.CheckBox(self, label='interpolate points along links')
+ self.interpolState.Bind(wx.EVT_CHECKBOX, self.onCheckInterpol)
+ self.interpolState.SetValue(False)
+ self.rb1 = wx.RadioButton(self, label='Number of points', style=wx.RB_GROUP)
+ self.rb2 = wx.RadioButton(self, label='Distance')
+ self.val = BaseInput(self, label='Value')
+
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+
+ panelSizer.Add(self.interpolState, flag=wx.EXPAND)
+ panelSizer.Add(self.rb1, flag=wx.EXPAND)
+ panelSizer.Add(self.rb2, flag=wx.EXPAND)
+ panelSizer.Add(self.val, flag=wx.EXPAND)
+ self.SetSizerAndFit(panelSizer)
+ self.onCheckInterpol()
+
+ def onCheckInterpol(self, evt=None):
+ if self.interpolState.GetValue():
+ self.rb1.Enable()
+ self.rb2.Enable()
+ self.val.Enable()
+ else:
+ self.rb1.Disable()
+ self.rb2.Disable()
+ self.val.Disable()
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+ try:
+ self.rb1.SetValue(self.settings['pitypeDist'])
+ except:
+ pass
+ try:
+ self.val.SetValue(self.settings['pivalue'])
+ except:
+ pass
+
+ def saveSettings(self, settings=None):
+ if settings is not None:
+ self.settings = settings
+ self.settings['pitypeDist'] = self.rb1.GetValue()
+ self.settings['pivalue'] = self.val.GetValue()
+ return self.settings
+
+
+class BaselinePanel(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+
+ self.dryWin = wx.RadioButton(self, label='Compute from dry windows', style=wx.RB_GROUP)
+ self.fromFile = wx.RadioButton(self, label='Direct text input')
+ self.baselTypeTxt = wx.StaticText(self, label='Select statistic method')
+ self.baselType = wx.ComboBox(self, id=wx.ID_ANY, value="quantile", choices=['avg', 'mode', 'quantile'])
+ self.round = BaseInput(self, 'Round data to "n" of decimal places') # TODO MODE disable
+ self.quantile = BaseInput(self, 'Set quantile in %') # TODO quantile disable
+ self.aw = BaseInput(self, 'Antena wetting value')
+ self.dryInterval = TextInput(self, 'Set interval of dry period')
+ self.fromFileVal = TextInput(self, 'Set baseline values in csv format')
+ # self.SLpanel = SaveLoad(self)
+ self.okBtt = wx.Button(self, wx.ID_OK, label='ok and close')
+ self.onChangeMethod(None)
+ self.fromFile.Bind(wx.EVT_RADIOBUTTON, self.onChangeMethod)
+ self.dryWin.Bind(wx.EVT_RADIOBUTTON, self.onChangeMethod)
+ self.okBtt.Bind(wx.EVT_BUTTON, self.saveSettings)
+ if len(settings) > 0:
+ self.loadSettings(None)
+
+ self._layout()
+
+ def loadSettings(self, sett=None):
+ if sett is not None:
+ self.settings = sett
+ try:
+ self.fromFile.SetValue(self.settings['fromFile'])
+ except:
+ pass
+ try:
+ self.dryWin.SetValue(self.settings['dryWin'])
+ except:
+ pass
+ try:
+ self.quantile.SetValue(self.settings['quantile'])
+ except:
+ pass
+
+ try:
+ self.baselType.SetValue(self.settings['baselType'])
+ except:
+ pass
+ try:
+ self.round.SetValue(self.settings['round'])
+ except:
+ pass
+ try:
+ self.aw.SetValue(self.settings['aw'])
+ except:
+ pass
+ try:
+ self.dryInterval.SetPath(self.settings['dryInterval'])
+ except:
+ pass
+ try:
+ self.fromFileVal.SetPath(self.settings['fromFileVal'])
+ except:
+ pass
+ self.onChangeMethod()
+
+ def saveSettings(self, evt=None, sett=None):
+ if sett:
+ self.settings = sett
+ self.settings['fromFile'] = self.fromFile.GetValue()
+ self.settings['dryWin'] = self.dryWin.GetValue()
+
+ self.settings['baselType'] = self.baselType.GetValue()
+ self.settings['round'] = self.round.GetValue()
+ self.settings['quantile'] = self.quantile.GetValue()
+ self.settings['aw'] = self.aw.GetValue()
+ self.settings['dryInterval'] = self.dryInterval.GetPath()
+ self.settings['fromFileVal'] = self.fromFileVal.GetPath()
+ return self.settings
+
+ def onChangeMethod(self, evt=None):
+ if self.dryWin.GetValue() is False:
+ self.baselType.Disable()
+ self.round.Disable()
+ self.aw.Disable()
+ self.dryInterval.Disable()
+ self.quantile.Disable()
+ self.fromFileVal.Enable()
+ else:
+ self.baselType.Enable()
+ self.round.Enable()
+ self.aw.Enable()
+ self.quantile.Enable()
+ self.dryInterval.Enable()
+ self.fromFileVal.Disable()
+
+ def _layout(self):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(self.dryWin, flag=wx.EXPAND)
+ sizer.Add(self.fromFile, flag=wx.EXPAND)
+ sizer.Add(self.baselTypeTxt, flag=wx.EXPAND)
+ sizer.Add(self.baselType, flag=wx.EXPAND)
+ sizer.Add(self.round, flag=wx.EXPAND)
+ sizer.Add(self.quantile, flag=wx.EXPAND)
+ sizer.Add(self.aw, flag=wx.EXPAND)
+ sizer.Add(self.dryInterval, flag=wx.EXPAND)
+ sizer.AddSpacer(10, 0, wx.EXPAND)
+ sizer.Add(self.fromFileVal, flag=wx.EXPAND)
+ sizer.AddSpacer(10, 0, wx.EXPAND)
+ # sizer.Add(self.SLpanel, flag=wx.EXPAND)
+ sizer.Add(self.okBtt, flag=wx.EXPAND)
+ self.SetSizerAndFit(sizer)
+
+
+'''
+class DataMgrRG(wx.Panel):
+ def __init__(self, parent, settings=None):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.sett = settings
+'''
+
+
+class DataMgrMW(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+
+ self.stBoxTWIN = wx.StaticBox(self, wx.ID_ANY, 'Time windows MW')
+
+ # =================DATA=========================
+ self.linksAll = wx.RadioButton(self, label='All', style=wx.RB_GROUP)
+ self.linksOnly = wx.RadioButton(self, label='Use links')
+ self.linksIngnore = wx.RadioButton(self, label='Ignore links')
+ self.linksAll.Bind(wx.EVT_RADIOBUTTON, self.refreshLinkSet)
+ self.linksIngnore.Bind(wx.EVT_RADIOBUTTON, self.refreshLinkSet)
+ self.linksOnly.Bind(wx.EVT_RADIOBUTTON, self.refreshLinkSet)
+ self.vectorMap = wx.RadioButton(self,label='Vector map')
+ self.vectorMap.Bind(wx.EVT_RADIOBUTTON,self.refreshLinkSet)
+
+ # self.links = BaseInput(self,'Set links according to radio above',True)
+ self.links = BaseInput(self, 'Set links according to radio above')
+ self.mapLabel=wx.StaticText(self,label='Select vector map')
+ self.map = gselect.Select(self, type='vector',multiple=False)
+
+ self.start = BaseInput(self, label='Start time')
+ self.end = BaseInput(self, label='End time')
+ self.getStartBtt = wx.Button(self, label='Get min')
+ self.getEndBtt = wx.Button(self, label='Get max')
+ self.sumStep = wx.ComboBox(self, id=wx.ID_ANY, value="minute", choices=['minute', 'hour', 'day'])
+
+ self.stBoxGauge = wx.StaticBox(self, wx.ID_ANY, 'Rain gauge')
+ self.inpRainGauge = FileInput(self, 'Select folder with raingauges data')
+ self.inpRainGauge.pathInput.Bind(wx.EVT_TEXT,self.disableLinksInp)
+ # self.sb1 = wx.StaticBox(self, wx.ID_ANY, 'Baseline')
+ # self.type = self.rb1 = wx.RadioButton(self, label='Number of points', style=wx.RB_GROUP)
+ if len(settings) > 0:
+ self.loadSettings()
+ self._layout()
+
+ def disableLinksInp(self,evt=None):
+ if self.inpRainGauge.GetPath() is not None:
+ self.linksAll.Disable()
+ self.linksOnly.Disable()
+ self.linksIngnore.Disable()
+ self.links.Disable()
+ self.vectorMap.Disable()
+ self.mapLabel.Disable()
+ self.map.Disable()
+ else:
+ self.linksAll.Enable()
+ self.linksOnly.Enable()
+ self.linksIngnore.Enable()
+ self.vectorMap.Enable()
+ self.mapLabel.Enable()
+ self.map.Enable()
+
+ if not self.linksAll.GetValue():
+ self.links.Enable()
+
+ def refreshLinkSet(self, evt=None):
+ if self.linksAll.GetValue():
+ self.links.Disable()
+ else:
+ self.links.Enable()
+
+ if self.vectorMap.GetValue():
+ self.links.Hide()
+ self.mapLabel.Show()
+ self.map.Show()
+ else:
+ self.links.Show()
+ self.mapLabel.Hide()
+ self.map.Hide()
+ self.Fit()
+
+ def saveSettings(self, evt=None, sett=None):
+ if sett:
+ self.settings = sett
+ self.settings['linksOnly'] = self.linksOnly.GetValue()
+ self.settings['linksIngnore'] = self.linksIngnore.GetValue()
+ self.settings['linksMap'] = self.map.GetValue()
+ self.settings['links'] = self.links.GetValue()
+ self.settings['start'] = self.start.GetValue()
+ self.settings['end'] = self.end.GetValue()
+ self.settings['sumStep'] = self.sumStep.GetValue()
+ self.settings['inpRainGauge'] = self.inpRainGauge.GetPath()
+ return self.settings
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+ try:
+ self.map.SetValue(eval(self.settings['linksMap']))
+ except:
+ pass
+ try:
+ self.linksOnly.SetValue(eval(self.settings['linksOnly']))
+ except:
+ pass
+ try:
+ self.linksIngnore.SetValue(eval(self.settings['linksIngnore']))
+ except:
+ pass
+ try:
+ self.links.SetValue(self.settings['links'])
+ except:
+ pass
+ try:
+ self.start.SetValue(self.settings['start'])
+ except:
+ pass
+ try:
+ self.end.SetValue(self.settings['end'])
+ except:
+ pass
+ try:
+ self.sumStep.SetValue(self.settings['sumStep'])
+ except:
+ pass
+ try:
+ self.inpRainGauge.SetPath(self.settings['inpRainGauge'])
+ except:
+ pass
+
+ def _layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+ self.SetSizerAndFit(panelSizer)
+
+ linksSizer = wx.BoxSizer(wx.HORIZONTAL)
+ linksSizer.Add(self.linksAll, flag=wx.EXPAND, proportion=1)
+ linksSizer.Add(self.linksOnly, flag=wx.EXPAND, proportion=1)
+ linksSizer.Add(self.linksIngnore, flag=wx.EXPAND, proportion=1)
+ linksSizer.Add(self.vectorMap, flag=wx.EXPAND, proportion=1)
+
+ stBoxSizerTWIN = wx.StaticBoxSizer(self.stBoxTWIN, orient=wx.VERTICAL)
+ stBoxSizerTWIN.Add(linksSizer, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.links, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.mapLabel, flag=wx.EXPAND)
+ stBoxSizerTWIN.Add(self.map, flag=wx.EXPAND)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.Add(self.start, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.getStartBtt)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.Add(self.end, flag=wx.EXPAND, proportion=1)
+ stBoxSizerTWIN.Add(self.getEndBtt)
+ stBoxSizerTWIN.AddSpacer(5, 5, 1, wx.EXPAND)
+ stBoxSizerTWIN.Add(wx.StaticText(self, id=wx.ID_ANY, label='Time increment'))
+ stBoxSizerTWIN.Add(self.sumStep, flag=wx.EXPAND)
+
+ gaugeSizer = wx.BoxSizer(wx.HORIZONTAL)
+ gaugeSizer.Add(self.inpRainGauge, flag=wx.EXPAND, proportion=1)
+
+ stBoxSizerRGAUGE = wx.StaticBoxSizer(self.stBoxGauge, orient=wx.VERTICAL)
+ stBoxSizerRGAUGE.Add(gaugeSizer, flag=wx.EXPAND, proportion=1)
+
+ panelSizer.Add(stBoxSizerTWIN, flag=wx.EXPAND)
+ panelSizer.Add(stBoxSizerRGAUGE, flag=wx.EXPAND)
+
+ # panelSizer.Add(self.exportDataBtt, flag=wx.EXPAND)
+ # panelSizer.Add(self.computeBtt, flag=wx.EXPAND)
+ self.SetSizerAndFit(panelSizer)
+ self.refreshLinkSet()
+
+class GrassLayers(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.colorRules = TextInput(self,label='Color table')
+ self.colorsName = BaseInput(self,label='Name of color table')
+ self.layout()
+
+ def loadSettings(self, sett=None):
+ if sett:
+ self.settings = sett
+ try:
+ self.colorRules.SetValue(self.settings['colorRules'])
+ except:
+ pass
+
+ try:
+ self.colorsName.SetValue(self.settings['colorsName'])
+ except:
+ pass
+
+ def saveSettings(self, evt=None, sett=None):
+ if sett:
+ self.settings = sett
+ self.settings['colorName'] = self.colorsName.GetValue()
+ self.settings['colorRules'] = self.colorRules.GetPath()
+ return self.settings
+
+ def layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+ panelSizer.Add(self.colorsName,flag= wx.EXPAND )
+ panelSizer.Add(self.colorRules, flag=wx.EXPAND )
+ self.SetSizerAndFit(panelSizer)
+
+class GeometryPanel(wx.Panel):
+ def __init__(self, parent, settings={}):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+ self.settings = settings
+ self.label=wx.StaticText(self,label='Create vector geometry map')
+ self.linksExp = wx.RadioButton(self, label='Links', style=wx.RB_GROUP)
+ self.nodesExp = wx.RadioButton(self, label='Nodes')
+ self.mapName=BaseInput(self,'Map name')
+ self.bttExport=wx.Button(self,label='Export')
+
+ self.layout()
+
+ def layout(self):
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
+
+ panelSizer.Add(self.label,flag=wx.EXPAND)
+ panelSizer.Add(self.linksExp,flag=wx.EXPAND)
+ panelSizer.Add(self.nodesExp,flag=wx.EXPAND)
+ panelSizer.Add(self.mapName,flag=wx.EXPAND)
+ panelSizer.Add(self.bttExport,flag=wx.EXPAND)
+ self.SetSizerAndFit(panelSizer)
+
+ def GetOptions(self):
+ if self.linksExp.GetValue():
+ type='links'
+ else:
+ type='nodes'
+ return type,self.mapName.GetValue()
+
+class ExportData(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+
+ self.chkid=wx.CheckBox(self,label='linkid')
+ self.chkid.SetValue(True)
+ self.chkid.Disable()
+ self.chktime=wx.CheckBox(self,label='time')
+ self.chktime.SetValue(True)
+ self.chktime.Disable()
+
+ self.chkprecip=wx.CheckBox(self,label='precipitation')
+ self.chkrx=wx.CheckBox(self,label='rx')
+ self.chktx=wx.CheckBox(self,label='tx')
+ self.chkfreq=wx.CheckBox(self,label='frequency')
+ self.chkpol=wx.CheckBox(self,label='polarization')
+ self.okBtt=wx.Button(self,label='export')
+ self.layout()
+ #self.chkprecip.Bind(wx.EVT_CHECKBOX,self.onChckPrec)
+
+ def layout(self):
+ mainSizer=wx.BoxSizer(wx.VERTICAL)
+
+ mainSizer.Add(self.chkid,wx.EXPAND)
+ mainSizer.Add(self.chktime,wx.EXPAND)
+ mainSizer.Add(self.chkprecip,wx.EXPAND)
+ mainSizer.Add(self.chkrx,wx.EXPAND)
+ mainSizer.Add(self.chktx,wx.EXPAND)
+ mainSizer.Add(self.chkfreq,wx.EXPAND)
+ mainSizer.Add(self.chkpol,wx.EXPAND)
+ mainSizer.Add(self.okBtt,wx.EXPAND)
+
+ self.SetSizerAndFit(mainSizer)
+
+class MyFrame(wx.Frame):
+ def __init__(self, parent, id, title):
+ wx.Frame.__init__(self, parent, id, title, size=(480, 640))
+ self.workPath = os.path.dirname(os.path.realpath(__file__))
+ self.initWorkingFoldrs()
+ self.settings = {}
+ self.settingsLst = []
+ self.mainSizer = wx.BoxSizer(wx.VERTICAL)
+
+ menubar = wx.MenuBar()
+ settMenu = wx.Menu()
+ fileMenu = wx.Menu()
+ databaseItem = settMenu.Append(wx.ID_ANY, 'Database', 'Set database')
+ baselineItem = settMenu.Append(wx.ID_ANY, 'Baseline', 'Set baseline methods')
+ geometry = settMenu.Append(wx.ID_ANY,'Geometry', 'Create vector geometry')
+ quitItem = settMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
+ menubar.Append(settMenu, '&Options')
+
+ #geoMenu = wx.Menu()
+
+ #menubar.Append(geoMenu, '&Settings')
+
+
+ self.SetMenuBar(menubar)
+ self.Bind(wx.EVT_MENU, self.onQuit, quitItem)
+ self.Bind(wx.EVT_MENU, self.onSetDatabase, databaseItem)
+ self.Bind(wx.EVT_MENU, self.onSetBaseline, baselineItem)
+ self.Bind(wx.EVT_MENU, self.onSetGeometry, geometry)
+
+ #def initNotebook(self):
+
+ self.ntb = wx.Notebook(self, id=wx.ID_ANY)
+ self.dataMgrMW = DataMgrMW(self.ntb)
+ self.dataMgrMW.getEndBtt.Bind(wx.EVT_BUTTON, self.getMaxTime)
+ self.dataMgrMW.getStartBtt.Bind(wx.EVT_BUTTON, self.getMinTime)
+
+ #self.dataMgrRG = DataMgrMW(self.ntb )
+ self.pointInter = PointInterpolationPanel(self.ntb)
+ self.ntb.AddPage(page=self.dataMgrMW, text='MW data')
+ #self.ntb.AddPage(page=self.dataMgrRG, text='RG data')
+ self.ntb.AddPage(page=self.pointInter, text='Points Interpolation')
+
+ self.grassLayers = GrassLayers(self.ntb, self.settings)
+ self.ntb.AddPage(page=self.grassLayers, text='Layers')
+
+ #def initProfileSett(self):
+ self.loadScheme = wx.StaticText(self, label='Load settings', id=wx.ID_ANY)
+ self.profilSelection = wx.ComboBox(self)
+ self.schema = BaseInput(self, 'Name of new working profile')
+ self.schema.text.Bind(wx.EVT_TEXT, self.OnSchemeTxtChange)
+ self.newScheme = wx.Button(self, label='Save new profile')
+ self.newScheme.Bind(wx.EVT_BUTTON, self.OnSaveSettings)
+ self.newScheme.Disable()
+ self.profilSelection.Bind(wx.EVT_COMBOBOX, self.OnLoadSettings)
+
+ #def initRunBtt(self):
+ self.computeBtt = wx.Button(self, label='Compute')
+ self.exportDataBtt = wx.Button(self, label='Export data')
+ self.computeBtt.Bind(wx.EVT_BUTTON, self.runCompute)
+ self.exportDataBtt.Bind(wx.EVT_BUTTON, self.exportData)
+
+ self.findProject()
+ self.layout()
+
+ def getMinTime(self, evt=None):
+ self.OnSaveSettings(toFile=False)
+ interface = Gui2Model(self, self.settings) # TODO optimalize init
+ if interface.connStatus:
+
+ self.dataMgrMW.start.SetValue(interface.dbConn.minTimestamp())
+
+ def getMaxTime(self, evt=None):
+ self.OnSaveSettings(toFile=False)
+ interface = Gui2Model(self, self.settings)
+ if interface.connStatus:
+ self.dataMgrMW.end.SetValue(interface.dbConn.maxTimestamp())
+
+ def GetConnection(self):
+ self.OnSaveSettings(toFile=False)
+ interface = Gui2Model(self, self.settings)
+ if interface.connStatus:
+ return interface.dbConn
+
+ def OnSchemeTxtChange(self, evt=None):
+ if self.schema.GetValue() is not None:
+ self.newScheme.Enable()
+ else:
+ self.newScheme.Disable()
+
+ def OnLoadSettings(self, evt=None):
+ currSelId = self.profilSelection.GetSelection()
+ self.settings = self.settingsLst[currSelId]
+ try:
+ self.dataMgrMW.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.dataMgrRG.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.databasePnl.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.baselinePnl.loadSettings(self.settings)
+ except:
+ pass
+ try:
+ self.grassLayers.loadSettings(self.settings)
+ except:
+ pass
+
+ def OnSaveSettings(self, evt=None, toFile=True):
+ try:
+ self.settings = self.dataMgrMW.saveSettings(sett=self.settings)
+ except:
+ pass
+ # try:
+ # self.settings=self.dataMgrRG.saveSettings(sett=self.settings)
+ # except:
+ # pass
+ try:
+ self.settings = self.databasePnl.saveSettings(sett=self.settings)
+ except:
+ pass
+ try:
+ self.settings = self.baselinePnl.saveSettings(sett=self.settings)
+ except:
+ pass
+ try:
+ self.settings = self.grassLayers.saveSettings(sett=self.settings)
+ except:
+ pass
+
+ try:
+ self.settings['workSchema'] = self.profilSelection.GetValue()
+ except:
+ pass
+
+ if self.schema.GetValue() is not None:
+ self.settings['workSchema'] = self.schema.GetValue()
+
+ if toFile:
+ tmpPath = os.path.join(self.workPath, "save", self.settings['workSchema'])
+ saveDict(tmpPath, self.settings)
+ self.findProject()
+
+ def initWorkingFoldrs(self):
+ savePath=os.path.join(self.workPath,'save')
+ if not os.path.exists(savePath):
+ os.makedirs(savePath)
+
+ tmpPath=os.path.join(self.workPath,'temp')
+ if not os.path.exists(tmpPath):
+ os.makedirs(tmpPath)
+
+ def findProject(self):
+ try:
+ projectDir = os.path.join(self.workPath, "save")
+ except:
+ GMessage('Cannot find "save" folder')
+ return
+ filePathList = getFilesInFoldr(projectDir, True)
+ # print 'filePathList',filePathList
+ if filePathList != 0:
+ self.profilSelection.Clear()
+ for n, path in enumerate(filePathList):
+ tmpDict = readDict(path)
+ self.settingsLst.append(tmpDict)
+ self.profilSelection.Append(str(tmpDict['workSchema']))
+ else:
+ return
+
+ def onSetGeometry(self,evt):
+ self.geDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Geometry creator',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ self.geDialog.SetSize((500, 500))
+
+ if self.settings:
+ self.geometryPnl = GeometryPanel(self.geDialog, self.settings)
+ else:
+ self.geometryPnl = GeometryPanel(self.geDialog)
+
+ self.geometryPnl.bttExport.Bind(wx.EVT_BUTTON, self._onSetGeomDLG)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.geometryPnl, flag=wx.EXPAND)
+ self.geDialog.SetSizer(dbSizer)
+ self.geDialog.SetBestFittingSize()
+ self.geDialog.ShowModal()
+ self.geDialog.Destroy()
+
+ def _onSetGeomDLG(self, evt):
+ type,name=self.geometryPnl.GetOptions()
+ if name == '':
+ GMessage('Please set name of map')
+ else:
+ self.createGeometry(type,name)
+ #self.addMapToLay()#TODO giface
+
+ def addMapToLay(self,map):
+ #TODO giface
+ '''
+
+ tree = self._giface.GetLayerTree()
+ if tree:
+ tree.AddLayer(ltype='vector', lname=map,
+ lcmd=['d.vect', 'map=%s' % map],
+ lchecked=True)
+ '''
+ pass
+
+ def onSetBaseline(self, evt):
+ self.bsDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Baseline settings',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ #self.bsDialog.SetSize((500, 500))
+
+ if self.settings:
+ self.baselinePnl = BaselinePanel(self.bsDialog, self.settings)
+ else:
+ self.baselinePnl = BaselinePanel(self.bsDialog)
+
+ self.baselinePnl.okBtt.Bind(wx.EVT_BUTTON, self._onSetBaselineDLG)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.baselinePnl, flag=wx.EXPAND)
+
+ self.bsDialog.SetSizer(dbSizer)
+ self.bsDialog.SetBestFittingSize()
+ self.bsDialog.ShowModal()
+ self.bsDialog.Destroy()
+
+ def _onSetBaselineDLG(self, evt):
+ self.settings = self.baselinePnl.saveSettings()
+ print self.settings
+ self.bsDialog.Destroy()
+
+ def onSetDatabase(self, evt):
+ self.dbDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Database connection settings',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ self.dbDialog.SetSize((500, 500))
+
+ if self.settings:
+ self.databasePnl = DBconn(self.dbDialog, self.settings)
+ else:
+ self.databasePnl = DBconn(self.dbDialog)
+
+ self.databasePnl.okBtt.Bind(wx.EVT_BUTTON, self._onSetDatabaseDLG)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.databasePnl, flag=wx.EXPAND)
+ self.dbDialog.SetSizer(dbSizer)
+ self.dbDialog.SetBestFittingSize()
+ self.dbDialog.ShowModal()
+ self.dbDialog.Destroy()
+
+ def _onSetDatabaseDLG(self, evt):
+ self.settings = self.databasePnl.saveSettings()
+ print self.settings
+ self.dbDialog.Destroy()
+
+ def createGeometry(self,type, name):
+ interface = Gui2Model(self, self.settings)
+ interface.initVectorGrass(type=type,name=name)
+
+ def exportData(self, evt):
+
+ self.exportDialog = wx.Dialog(self, id=wx.ID_ANY,
+ title='Database connection settings',
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ size=wx.DefaultSize,
+ pos=wx.DefaultPosition)
+
+ self.exportDialog.SetSize((500, 500))
+ self.exportDMgr = ExportData(self.exportDialog)
+
+ self.exportDMgr.okBtt.Bind(wx.EVT_BUTTON, self._onExport)
+ dbSizer = wx.BoxSizer(wx.VERTICAL)
+ dbSizer.Add(self.exportDMgr, flag=wx.EXPAND)
+ self.exportDialog.SetSizer(dbSizer)
+ self.exportDialog.SetBestFittingSize()
+ self.exportDialog.ShowModal()
+ self.exportDialog.Destroy()
+
+ def _onExport(self,evt=None):
+ path=OnSaveAs(self)
+ self.OnSaveSettings(toFile=False)
+ if not self.exportDMgr.chkprecip.GetValue():
+ attrTmp1=[]
+ attrTmp1.append('link.linkid')
+ attrTmp2=[]
+ attrTmp3=[]
+ #attrTmp2.append('public.linkid')
+ if self.exportDMgr.chkfreq.GetValue():
+ attrTmp1.append('link.frequency')
+ if self.exportDMgr.chkpol.GetValue():
+ attrTmp1.append('link.polarization')
+
+ attrTmp2.append('record.time')
+ if self.exportDMgr.chkrx.GetValue():
+ attrTmp2.append('record.rxpower')
+ if self.exportDMgr.chktx.GetValue():
+ attrTmp2.append('record.txpower')
+
+ attrTmp4='WHERE'
+ if len(attrTmp1) > 0:
+ attrTmp3.append('link')
+ if len(attrTmp2) > 0:
+ attrTmp3.append('record')
+
+ if len(attrTmp1) > 0 and len(attrTmp2) > 0:
+ attrTmp4='WHERE link.linkid=record.linkid AND'
+ attrTmp0=attrTmp1+attrTmp2
+ attrTmp0 = ",".join(attrTmp0)
+ elif len(attrTmp1) > 0:
+ attrTmp0 = ",".join(attrTmp1)
+ elif len(attrTmp2) > 0:
+ attrTmp0 = ",".join(attrTmp2)
+
+ if len(attrTmp3)>1:
+ attrTmp3 = ",".join(attrTmp3)
+ else:
+ attrTmp3=attrTmp3[0]
+
+ sql="SELECT %s FROM %s %s record.time>'%s' and record.time< '%s' "%(attrTmp0,
+ attrTmp3,
+ attrTmp4,
+ self.dataMgrMW.start.GetValue(),
+ self.dataMgrMW.end.GetValue())
+ conn=self.GetConnection()
+ res=conn.connection.executeSql(sql, True, True)
+ lines=''
+ for r in res:
+ lines+=str(r)[1:][:-1].replace('datetime.datetime','').replace("'","") +'\n'
+ print conn.pathworkSchemaDir
+ #path=os.path.join(conn.pathworkSchemaDir, "export")
+ io0 = open(path, "wr")
+ io0.writelines(lines)
+ io0.close()
+ GMessage('Data exported<%s>'%path)
+
+ else:
+ exportData = {'getData':True,'dataOnly':False}
+ if YesNo(self, 'Export data only?'):
+ exportData['dataOnly'] = True
+ self.settings['dataExport'] = exportData
+
+ #if rain gauges
+ if self.dataMgrMW.inpRainGauge.GetPath() is not None:
+ self.settings['IDtype']='gaugeid'
+ else:
+ self.settings['IDtype']='linkid'
+
+ interface = Gui2Model(self, self.settings)
+ interface.initVectorGrass()
+ interface.initTimeWinMW()
+ interface.initBaseline()
+ interface.doCompute()
+ conn=self.GetConnection()
+ sql='SELECT * FROM %s.%s'%(interface.dbConn.schema,interface.dbConn.computedPrecip)
+ res=conn.connection.executeSql(sql, True, True)
+ lines=''
+ for r in res:
+ lines+=str(r)[1:][:-1] +'\n'
+ print conn.pathworkSchemaDir
+ #path=os.path.join(conn.pathworkSchemaDir, "export")
+ io0 = open(path, "wr")
+ io0.writelines(lines)
+ io0.close()
+ GMessage('Data exported<%s>'%path)
+
+ self.exportDialog.Destroy()
+
+ def runCompute(self, evt):
+ self.OnSaveSettings(toFile=False)
+ exportData = {'getData':False,'dataOnly':False}
+ self.settings['dataExport'] = exportData
+
+ #if rain gauges
+ if self.dataMgrMW.inpRainGauge.GetPath() is not None:
+ self.settings['IDtype']='gaugeid'
+ else:
+ self.settings['IDtype']='linkid'
+
+ interface = Gui2Model(self, self.settings)
+ interface.initVectorGrass()
+
+ #if interpolate points along lines
+ if self.pointInter.interpolState.GetValue():
+ interface.initPInterpolation()
+
+ interface.initTimeWinMW()
+ interface.initBaseline()
+ interface.doCompute()
+
+ def layout(self):
+ self.mainSizer.Add(self.loadScheme, flag=wx.EXPAND)
+ self.mainSizer.Add(self.profilSelection, flag=wx.EXPAND)
+ self.mainSizer.Add(self.schema, flag=wx.EXPAND)
+ self.mainSizer.Add(self.newScheme, flag=wx.EXPAND)
+
+ self.mainSizer.AddSpacer(10, 0, wx.EXPAND)
+ self.mainSizer.Add(self.ntb, flag=wx.EXPAND)
+
+ self.mainSizer.AddSpacer(10, 0, wx.EXPAND)
+ self.mainSizer.Add(self.computeBtt, flag=wx.EXPAND)
+ self.mainSizer.Add(self.exportDataBtt, flag=wx.EXPAND)
+
+ self.SetSizer(self.mainSizer)
+ # self.Fit()
+
+ def onQuit(self, e):
+ self.Close()
+
+class Gui2Model():
+ def __init__(self, wxParent, settings):
+ parent = wxParent
+ self.settings = settings
+ self.dbConn = None
+ self.connStatus=False
+ self.initConnection()
+
+ def initConnection(self, info=False):
+ conninfo=None
+ try:
+ conninfo = {'name': self.settings['database']}
+ except:
+ GMessage('name of database is missing')
+ return
+ try:
+ conninfo['workSchema'] = self.settings['workSchema']
+ except:
+ pass
+ try:
+ conninfo['dataSchema'] = self.settings['schema']
+ except:
+ pass
+ try:
+ conninfo['host'] = self.settings['host']
+ except:
+ pass
+ try:
+ conninfo['user'] = self.settings['user']
+ except:
+ pass
+ try:
+ conninfo['port'] = self.settings['port']
+ except:
+ pass
+ try:
+ conninfo['password'] = self.settings['passwd']
+ except:
+ pass
+
+ if conninfo is None:
+ self.connStatus=False
+ GMessage('Database connection failed')
+ return
+
+
+ if not info: # prepare for computing
+ self.dbConn = Database(**conninfo)
+ self.connStatus=True
+ self.dbConn.firstPreparation()
+ self.dbConn.prepareDB()
+ self.dbConn.prepareDir()
+
+ return self.dbConn
+ else: # just get info about curr database state
+ self.dbConn = Database(**conninfo)
+ self.connStatus=True
+ return self.dbConn
+
+ def initVectorGrass(self,type=None,name=None):
+ convertor = VectorLoader(self.dbConn)
+ if name:
+ self.dbConn.nodeVecMapName=name
+ self.dbConn.linkVecMapName=name
+
+ if type=='nodes' or type is None:
+ # create native vector map(nodes)
+ pointsSQL = convertor.selectNodes()
+ # print pointsSQL
+ pointsASCII = convertor.getASCIInodes(pointsSQL)
+ convertor.grass_vinASCII(pointsASCII, self.dbConn.nodeVecMapName)
+ # create native vector map(links)
+ if type=='links'or type is None:
+ linksSQL = convertor.selectLinks()
+ linksASCII = convertor.getASCIIlinks(linksSQL)
+ convertor.grass_vinASCII(linksASCII, self.dbConn.linkVecMapName)
+
+ def initPInterpolation(self):
+ try:
+ pitypeDist = self.settings['pitypeDist']
+ except:
+ pass
+ try:
+ pivalue = self.settings['pivalue']
+ except:
+ self.errMsg('Missing value for interpolating points along lines')
+
+ PointInterpolation(self.dbConn, pivalue, pitypeDist)
+
+ def initBaseline(self):
+ baselInit = {}
+ try:
+ baselInit['statFce'] = self.settings['baselType']
+ except:
+ pass
+ try:
+ baselInit['quantile'] = self.settings['quantile']
+ except:
+ pass
+ try:
+ baselInit['roundMode'] = self.settings['round']
+ except:
+ pass
+ try:
+ baselInit['aw'] = self.settings['aw']
+ except:
+ pass
+ methodSel = False
+ try:
+ if self.settings['fromFile']:
+ baselInit['type'] = 'values'
+ try:
+ baselInit['pathToFile'] = self.settings['fromFileVal']
+ except:
+ self.errMsg('Path to file with baseline values is not defined')
+ methodSel = True
+ except:
+ pass
+ try:
+ if self.settings['dryWin']:
+ baselInit['type'] = 'fromDryWin'
+ try:
+ baselInit['pathToFile'] = self.settings['dryInterval']
+ except:
+ self.errMsg('Dry interval is not defined')
+ methodSel = True
+ except:
+ pass
+
+ if not methodSel:
+ self.errMsg('Baseline method is not selected')
+ print baselInit
+ self.baseline = Baseline(**baselInit)
+
+ def initTimeWinMW(self):
+ winInit = {}
+ try:
+ winInit['linksOnly'] = eval(self.settings['linksOnly'])
+ except:
+ pass
+ try:
+ winInit['linksOnly'] = eval(self.settings['linksMap'])
+ except:
+ pass
+ try:
+ winInit['linksIngnore'] = eval(self.settings['linksIngnore'])
+ except:
+ pass
+ try:
+ winInit['links'] = self.settings['links']
+ except:
+ pass
+ try:
+ winInit['startTime'] = self.settings['start']
+ except:
+ pass
+ try:
+ winInit['endTime'] = self.settings['end']
+ except:
+ pass
+ try:
+ winInit['sumStep'] = self.settings['sumStep']
+ except:
+ pass
+ try:
+ winInit['IDtype'] = self.settings['IDtype']
+ except:
+ pass
+ winInit['database'] = self.dbConn
+
+ self.twin = TimeWindows(**winInit)
+
+ def doCompute(self):
+
+ # GMessage('OK')
+ # sys.exit()
+ comp=Computor(self.baseline, self.twin, self.dbConn, self.settings['dataExport'])
+ bool,msg=comp.GetStatus()
+ if bool:
+ self.initGrassLayerMgr()
+ self.initTemporalMgr()
+
+ GMessage(msg)
+ #elf.initgrassManagement()
+
+ def initGrassLayerMgr(self):
+ grassLayerMgr = {}
+ try:
+ grassLayerMgr['rules'] = self.settings['colorRules']
+ except:
+ pass
+ try:
+ grassLayerMgr['color'] = self.settings['colorName']
+ except:
+ pass
+
+ grassLayerMgr['database'] = self.dbConn
+ GrassLayerMgr(**grassLayerMgr)
+
+
+ def initTemporalMgr(self):
+ GrassTemporalMgr(self.dbConn, self.twin)
+ GMessage('Finish')
+
+ def errMsg(self, label):
+ print label
+ GError(label)
+
+class MyApp(wx.App):
+ def OnInit(self):
+ frame = MyFrame(None, -1, "MW worker")
+ frame.Show(True)
+ self.SetTopWindow(frame)
+ return True
+
+
+app = MyApp(0) # Create an instance of the application class
+app.MainLoop() # Tell it to start processing events
+
+
+
+
Property changes on: grass-addons/grass7/gui/wxpython/wx.mwprecip/wx.mwprecip.py
___________________________________________________________________
Added: svn:executable
+ *
More information about the grass-commit
mailing list