12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022 |
- """!
- @package web_services.dialogs
- @brief Dialogs for web services.
- List of classes:
- - dialogs::WSDialogBase
- - dialogs::AddWSDialog
- - dialogs::WSPropertiesDialog
- - dialogs::SaveWMSLayerDialog
- (C) 2009-2013 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Martin Landa <landa.martin gmail.com>
- @author Stepan Turek <stepan.turek seznam.cz>
- """
- import wx
- import os
- import sys
- import shutil
- from copy import deepcopy
- import grass.script as grass
- from core import globalvar
- from core.debug import Debug
- from core.gcmd import GMessage, GWarning, GError, RunCommand
- from core.utils import GetSettingsPath, CmdToTuple, CmdTupleToList, _
- from core.gconsole import CmdThread, GStderr, EVT_CMD_DONE, EVT_CMD_OUTPUT
- from gui_core.gselect import Select
- from web_services.widgets import WSPanel, WSManageSettingsWidget
- class WSDialogBase(wx.Dialog):
- """!Base class for web service dialogs.
- """
- def __init__(self, parent, id = wx.ID_ANY,
- style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
- wx.Dialog.__init__(self, parent, id, style = style, **kwargs)
- self.parent = parent
- # contains panel for every web service on server
- self.ws_panels = {'WMS_1.1.1' : {'panel' : None,
- 'label' : 'WMS 1.1.1'},
- 'WMS_1.3.0' : {'panel' : None,
- 'label' : 'WMS 1.3.0'},
- 'WMTS' : {'panel' : None,
- 'label' : 'WMTS'},
- 'OnEarth' : {'panel' : None,
- 'label' : 'OnEarth'},
- }
- #TODO: should be in file
- self.default_servers = { 'OSM-WMS-EUROPE' : ['http://129.206.228.72/cached/osm', '', ''],
- 'irs.gis-lab.info (OSM)' : ['http://irs.gis-lab.info', '', ''],
- 'NASA OnEarth' : ['http://onearth.jpl.nasa.gov/wms.cgi', '', '']
- }
- # holds reference to web service panel which is showed
- self.active_ws_panel = None
- # buttons which are disabled when the dialog is not connected
- self.run_btns = []
- # stores error messages for GError dialog showed when all web service connections were unsuccessful
- self.error_msgs = ''
- self._createWidgets()
- self._doLayout()
- def _createWidgets(self):
- settingsFile = os.path.join(GetSettingsPath(), 'wxWS')
- self.settsManager = WSManageSettingsWidget(parent=self,
- settingsFile=settingsFile,
- default_servers=self.default_servers)
- self.settingsBox = wx.StaticBox(parent = self,
- id = wx.ID_ANY,
- label = _(" Server settings "))
-
- self.serverText = wx.StaticText(parent = self,
- id = wx.ID_ANY, label = _("Server:"))
- self.server = wx.TextCtrl(parent = self, id = wx.ID_ANY)
- self.btn_connect = wx.Button(parent = self,
- id = wx.ID_ANY, label = _("&Connect"))
- self.btn_connect.SetToolTipString(_("Connect to the server"))
- if not self.server.GetValue():
- self.btn_connect.Enable(False)
- self.infoCollapseLabelExp = _('Show advanced connection settings')
- self.infoCollapseLabelCol = _('Hide advanced connection settings')
- self.adv_conn = wx.CollapsiblePane(parent = self,
- label = self.infoCollapseLabelExp,
- style = wx.CP_DEFAULT_STYLE |
- wx.CP_NO_TLW_RESIZE | wx.EXPAND)
- self.MakeAdvConnPane(pane = self.adv_conn.GetPane())
- self.adv_conn.Collapse(True)
- self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnAdvConnPaneChanged, self.adv_conn)
- self.reqDataPanel = wx.Panel(parent = self, id = wx.ID_ANY)
- self.layerNameBox = wx.StaticBox(parent = self.reqDataPanel,
- id = wx.ID_ANY,
- label = _(" Layer Manager Settings "))
- self.layerNameText = wx.StaticText(parent = self.reqDataPanel, id = wx.ID_ANY,
- label = _("Output layer name:"))
- self.layerName = wx.TextCtrl(parent = self.reqDataPanel, id = wx.ID_ANY)
- for ws in self.ws_panels.iterkeys():
- self.ws_panels[ws]['panel'] = WSPanel(parent = self.reqDataPanel,
- web_service = ws)
- self.ws_panels[ws]['panel'].capParsed.connect(self.OnPanelCapParsed)
- self.ws_panels[ws]['panel'].layerSelected.connect(self.OnLayerSelected)
- # buttons
- self.btn_close = wx.Button(parent = self, id = wx.ID_CLOSE)
- self.btn_close.SetToolTipString(_("Close dialog"))
-
- # statusbar
- self.statusbar = wx.StatusBar(parent = self, id = wx.ID_ANY)
- # bindings
- self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
- self.Bind(wx.EVT_CLOSE, self.OnClose)
- self.btn_connect.Bind(wx.EVT_BUTTON, self.OnConnect)
- self.server.Bind(wx.EVT_TEXT, self.OnServer)
- self.layerName.Bind(wx.EVT_TEXT, self.OnOutputLayerName)
- self.settsManager.settingsChanged.connect(self.OnSettingsChanged)
- self.settsManager.settingsSaving.connect(self.OnSettingsSaving)
- def OnLayerSelected(self, title):
- if not self.layerName.GetValue().strip():
- self.layerName.SetValue(title)
- def _doLayout(self):
- dialogSizer = wx.BoxSizer(wx.VERTICAL)
- dialogSizer.Add(item = self.settsManager, proportion = 0,
- flag = wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border = 5)
-
- # connectin settings
- settingsSizer = wx.StaticBoxSizer(self.settingsBox, wx.VERTICAL)
-
- serverSizer = wx.FlexGridSizer(cols = 3, vgap = 5, hgap = 5)
- serverSizer.Add(item = self.serverText,
- flag = wx.ALIGN_CENTER_VERTICAL)
- serverSizer.AddGrowableCol(1)
- serverSizer.Add(item = self.server,
- flag = wx.EXPAND | wx.ALL)
- serverSizer.Add(item = self.btn_connect)
- settingsSizer.Add(item = serverSizer, proportion = 0,
- flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
-
- settingsSizer.Add(item = self.adv_conn,
- flag = wx.ALL | wx.EXPAND, border = 5)
- dialogSizer.Add(item = settingsSizer, proportion = 0,
- flag = wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border = 5)
- # layer name, parsed capabilites
- reqDataSizer = wx.BoxSizer(wx.VERTICAL)
- layerNameSizer = wx.StaticBoxSizer(self.layerNameBox, wx.HORIZONTAL)
- layerNameSizer.Add(item = self.layerNameText,
- flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = 5)
- layerNameSizer.Add(item = self.layerName,
- flag = wx.EXPAND, proportion = 1)
-
- reqDataSizer.Add(item = layerNameSizer,
- flag = wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND, border = 5)
- self.ch_ws_sizer = wx.BoxSizer(wx.VERTICAL)
- reqDataSizer.Add(item = self.ch_ws_sizer, proportion = 0,
- flag = wx.TOP | wx.EXPAND, border = 5)
- for ws in self.ws_panels.iterkeys():
- reqDataSizer.Add(item = self.ws_panels[ws]['panel'], proportion = 1,
- flag = wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND, border = 5)
- self.ws_panels[ws]['panel'].Hide()
- dialogSizer.Add(item = self.reqDataPanel, proportion = 1,
- flag = wx.EXPAND)
- self.reqDataPanel.SetSizer(reqDataSizer)
- self.reqDataPanel.Hide()
- # buttons
- self.btnsizer = wx.BoxSizer(orient = wx.HORIZONTAL)
- self.btnsizer.Add(item = self.btn_close, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER,
- border = 10)
-
- dialogSizer.Add(item = self.btnsizer, proportion = 0,
- flag = wx.ALIGN_CENTER)
- dialogSizer.Add(item = self.statusbar, proportion = 0)
- self.SetSizer(dialogSizer)
- self.Layout()
- self.SetMinSize((550, -1))
- self.SetMaxSize((-1, self.GetBestSize()[1]))
- self.Fit()
- def MakeAdvConnPane(self, pane):
- """!Create advanced connection settings pane
- """
- self.usernameText = wx.StaticText(parent = pane,
- id = wx.ID_ANY, label = _("Username:"))
- self.username = wx.TextCtrl(parent = pane, id = wx.ID_ANY)
- self.passwText = wx.StaticText(parent = pane,
- id = wx.ID_ANY, label = _("Password:"))
- self.password = wx.TextCtrl(parent = pane, id = wx.ID_ANY,
- style = wx.TE_PASSWORD)
- # pane layout
- adv_conn_sizer = wx.BoxSizer(wx.VERTICAL)
- usernameSizer = wx.BoxSizer(wx.HORIZONTAL)
- usernameSizer.Add(item = self.usernameText,
- flag = wx.ALIGN_CENTER_VERTICAL, border = 5)
- usernameSizer.Add(item = self.username, proportion = 1,
- flag = wx.EXPAND, border = 5)
- adv_conn_sizer.Add(item = usernameSizer,
- flag = wx.ALL | wx.EXPAND, border = 5)
- passwSizer = wx.BoxSizer(wx.HORIZONTAL)
- passwSizer.Add(item = self.passwText,
- flag = wx.ALIGN_CENTER_VERTICAL, border = 5)
- passwSizer.Add(item = self.password, proportion = 1,
- flag = wx.EXPAND, border = 5)
- adv_conn_sizer.Add(item = passwSizer,
- flag = wx.ALL | wx.EXPAND, border = 5)
-
- pane.SetSizer(adv_conn_sizer)
- adv_conn_sizer.Fit(pane)
- pane.SetSizer(adv_conn_sizer)
- adv_conn_sizer.Fit(pane)
- def OnSettingsSaving(self, name):
- """!Check if required data are filled before setting save is performed.
- """
- server = self.server.GetValue().strip()
- if not server:
- GMessage(parent = self,
- message = _("No data source defined, settings are not saved."))
- return
- self.settsManager.SetDataToSave((server,
- self.username.GetValue(),
- self.password.GetValue()))
- self.settsManager.SaveSettings(name)
- def OnSettingsChanged(self, data):
- """!Update widgets according to chosen settings"""
- # data list: [server, username, password]
- if len < 3:
- return
- self.server.SetValue(data[0])
- self.username.SetValue(data[1])
- self.password.SetValue(data[2])
- if data[1] or data[2]:
- self.adv_conn.Expand()
- else:
- self.adv_conn.Collapse(True)
- def OnClose(self, event):
- """!Close the dialog
- """
- """!Close dialog"""
- if not self.IsModal():
- self.Destroy()
- event.Skip()
- def _getCapFiles(self):
- ws_cap_files = {}
- for v in self.ws_panels.itervalues():
- ws_cap_files[v['panel'].GetWebService()] = v['panel'].GetCapFile()
- return ws_cap_files
- def OnServer(self, event):
- """!Server settings edited
- """
- value = event.GetString()
- if value:
- self.btn_connect.Enable(True)
- else:
- self.btn_connect.Enable(False)
-
- def OnOutputLayerName(self, event):
- """!Update layer name to web service panel
- """
- lname = event.GetString()
- lname = lname.encode('ascii', 'replace')
- for v in self.ws_panels.itervalues():
- v['panel'].SetOutputLayerName(lname.strip())
- def OnConnect(self, event):
- """!Connect to the server
- """
- server = self.server.GetValue().strip()
- self.ch_ws_sizer.Clear(deleteWindows = True)
- if self.active_ws_panel is not None:
- self.reqDataPanel.Hide()
- for btn in self.run_btns:
- btn.Enable(False)
- self.active_ws_panel = None
- self.Layout()
- self.Fit()
- self.statusbar.SetStatusText(_("Connecting to <%s>..." % self.server.GetValue().strip()))
- # number of panels already connected
- self.finished_panels_num = 0
- for ws in self.ws_panels.iterkeys():
- self.ws_panels[ws]['panel'].ConnectToServer(url = server,
- username = self.username.GetValue(),
- password = self.password.GetValue())
- self.ws_panels[ws]['panel'].Hide()
-
- def OnPanelCapParsed(self, error_msg):
- """!Called when panel has downloaded and parsed capabilities file.
- """
- # how many web service panels are finished
- self.finished_panels_num += 1
- if error_msg:
- self.error_msgs += '\n' + error_msg
- # if all are finished, show panels, which succeeded in connection
- if self.finished_panels_num == len(self.ws_panels):
- self.UpdateDialogAfterConnection()
- # show error dialog only if connections to all web services were unsuccessful
- if not self._getConnectedWS() and self.error_msgs:
- GError(self.error_msgs, parent = self)
- self.error_msgs = ''
- self.Layout()
- self.Fit()
- def _getConnectedWS(self):
- """
- @return list of found web services on server (identified as keys in self.ws_panels)
- """
- conn_ws = []
- for ws, data in self.ws_panels.iteritems():
- if data['panel'].IsConnected():
- conn_ws.append(ws)
- return conn_ws
- def UpdateDialogAfterConnection(self):
- """!Update dialog after all web service panels downloaded and parsed capabilities data.
- """
- avail_ws = {}
- conn_ws = self._getConnectedWS()
- for ws in conn_ws:
- avail_ws[ws] = self.ws_panels[ws]
- self.web_service_sel = []
- self.rb_choices = []
- # at least one web service found on server
- if len(avail_ws) > 0:
- self.reqDataPanel.Show()
- self.rb_order = ['WMS_1.1.1', 'WMS_1.3.0', 'WMTS', 'OnEarth']
- for ws in self.rb_order:
- if ws in avail_ws:
- self.web_service_sel.append(ws)
- self.rb_choices.append(avail_ws[ws]['label'])
- self.choose_ws_rb = wx.RadioBox(parent = self.reqDataPanel, id = wx.ID_ANY,
- label = _("Available web services"),
- pos = wx.DefaultPosition, choices = self.rb_choices,
- majorDimension = 1, style = wx.RA_SPECIFY_ROWS)
-
- self.Bind(wx.EVT_RADIOBOX, self.OnChooseWs, self.choose_ws_rb)
- self.ch_ws_sizer.Add(item = self.choose_ws_rb,
- flag = wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND, border = 5)
- self._showWsPanel(self.web_service_sel[self.choose_ws_rb.GetSelection()])
- self.statusbar.SetStatusText(_("Connected to <%s>" % self.server.GetValue().strip()))
- for btn in self.run_btns:
- btn.Enable(True)
- # no web service found on server
- else:
- self.statusbar.SetStatusText(_("Unable to connect to <%s>" % self.server.GetValue().strip()))
- for btn in self.run_btns:
- btn.Enable(False)
- self.reqDataPanel.Hide()
- self.active_ws_panel = None
- def OnChooseWs(self, event):
- """!Show panel corresponding to selected web service.
- """
- choosen_r = event.GetInt()
- self._showWsPanel(self.web_service_sel[choosen_r])
- def _showWsPanel(self, ws):
- """!Helper function
- """
- if self.active_ws_panel is not None:
- self.active_ws_panel.Hide()
- self.active_ws_panel = self.ws_panels[ws]['panel']
- self.active_ws_panel.Show()
- self.SetMaxSize((-1, -1))
- self.Layout()
- def OnAdvConnPaneChanged(self, event):
- """!Collapse search module box
- """
- if self.adv_conn.IsExpanded():
- self.adv_conn.SetLabel(self.infoCollapseLabelCol)
- else:
- self.adv_conn.SetLabel(self.infoCollapseLabelExp)
- self.Layout()
- self.SetMaxSize((-1, self.GetBestSize()[1]))
- self.SendSizeEvent()
- self.Fit()
- class AddWSDialog(WSDialogBase):
- """!Dialog for adding web service layer."""
- def __init__(self, parent, giface, id = wx.ID_ANY,
- style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
- WSDialogBase.__init__(self, parent, id = wx.ID_ANY,
- style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs)
- self.SetTitle(_("Add web service layer"))
- self.parent = parent
- self.giface = giface
- self.btn_connect.SetDefault()
- def _createWidgets(self):
- WSDialogBase._createWidgets(self)
- self.btn_add = wx.Button(parent = self, id = wx.ID_ANY, label = _("&Add layer"))
- self.btn_add.SetToolTipString(_("Add selected web service layers as map layer into layer tree"))
- self.btn_add.Enable(False)
-
- self.run_btns.append(self.btn_add)
- def _doLayout(self):
- WSDialogBase._doLayout(self)
- self.btnsizer.Add(item = self.btn_add, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER,
- border = 10)
- # bindings
- self.btn_add.Bind(wx.EVT_BUTTON, self.OnAddLayer)
- def UpdateDialogAfterConnection(self):
- """!Connect to the server
- """
- WSDialogBase.UpdateDialogAfterConnection(self)
- if self._getConnectedWS():
- self.btn_add.SetDefault()
- else:
- self.btn_connect.SetDefault()
- def OnAddLayer(self, event):
- """!Add web service layer.
- """
- # add layer
- if self.active_ws_panel is None:
- return
- lcmd = self.active_ws_panel.CreateCmd()
- if not lcmd:
- return None
- # TODO: It is not clear how to do GetOptData in giface
- # knowing what GetOptData is doing might help
- # (maybe Get... is not the right name)
- # please fix giface if you know
- # tree -> giface
- # GetLayerTree -> GetLayerList
- # AddLayer -> AddLayer (but tree ones returns some layer,
- # giface ones nothing)
- # GetLayerInfo -> Layer object can by used instead
- # GetOptData -> unknown
- ltree = self.giface.GetLayerTree()
- active_ws = self.active_ws_panel.GetWebService()
- if 'WMS' not in active_ws:
- cap_file = self.active_ws_panel.GetCapFile()
- cmd_cap_file = grass.tempfile()
- shutil.copyfile(cap_file, cmd_cap_file)
- lcmd.append('capfile=' + cmd_cap_file)
- layer = ltree.AddLayer(ltype = 'wms',
- lname = self.active_ws_panel.GetOutputLayerName(),
- lchecked = True, lcmd = lcmd)
- ws_cap_files = self._getCapFiles()
- # create properties dialog
- cmd_list = ltree.GetLayerInfo(layer,'cmd')
- cmd = CmdToTuple(cmd_list)
- prop_win = WSPropertiesDialog(parent = self.parent,
- giface = self.giface,
- id = wx.ID_ANY,
- layer = layer,
- ws_cap_files = ws_cap_files,
- cmd = cmd)
- prop_win.Hide()
- ltree.GetOptData(dcmd = None, layer = layer,
- params = None, propwin = prop_win)
- class WSPropertiesDialog(WSDialogBase):
- """!Dialog for editing web service properties."""
- def __init__(self, parent, giface, layer, ws_cap_files, cmd, id = wx.ID_ANY,
- style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
- """
- @param giface grass interface
- @param layer layer tree item
- @param ws_cap_files dict web service('WMS_1.1.1', 'WMS_1.3.0', 'WMTS', 'OnEarth') : cap file path
- cap files, which will be parsed
- @param cmd cmd to which dialog widgets will be initialized if it is possible
- (cmp parameters exists in parsed web service cap_file)
- """
- WSDialogBase.__init__(self, parent, id = wx.ID_ANY,
- style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs)
- self.SetTitle(_("Web service layer properties"))
- self.layer = layer
- self.giface = giface
- # after web service panels are connected, set dialog widgets
- # according to cmd in this variable (if it is not None)
- self.cmd_to_set = None
- # store data needed for reverting
- self.revert_ws_cap_files = {}
- self.revert_cmd = cmd
- ws_cap = self._getWSfromCmd(cmd)
- for ws in self.ws_panels.iterkeys():
- # cap file used in cmd will be deleted, thnaks to the dialogs destructor
- if ws == ws_cap and cmd[1].has_key('capfile'):
- self.revert_ws_cap_files[ws] = cmd[1]['capfile']
- del ws_cap_files[ws]
- else:
- self.revert_ws_cap_files[ws] = grass.tempfile()
- self._setRevertCapFiles(ws_cap_files)
- self.LoadCapFiles(ws_cap_files = self.revert_ws_cap_files, cmd = cmd)
- self.btn_ok.SetDefault()
- def __del__(self):
- for f in self.revert_ws_cap_files.itervalues():
- grass.try_remove(f)
- def _setRevertCapFiles(self, ws_cap_files):
- for ws, f in ws_cap_files.iteritems():
- if os.path.isfile(ws_cap_files[ws]):
- shutil.copyfile(f, self.revert_ws_cap_files[ws])
- else:
- # delete file content
- f_o = open(f, 'w')
- f_o.close()
- def _createWidgets(self):
- WSDialogBase._createWidgets(self)
- self.btn_apply = wx.Button(parent = self, id = wx.ID_ANY, label = _("&Apply"))
- self.btn_apply.SetToolTipString(_("Apply changes"))
- self.btn_apply.Enable(False)
- self.run_btns.append(self.btn_apply)
- self.btn_ok = wx.Button(parent = self, id = wx.ID_ANY, label = _("&OK"))
- self.btn_ok.SetToolTipString(_("Apply changes and close dialog"))
- self.btn_ok.Enable(False)
- self.run_btns.append(self.btn_ok)
- def _doLayout(self):
- WSDialogBase._doLayout(self)
- self.btnsizer.Add(item = self.btn_apply, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER,
- border = 10)
- self.btnsizer.Add(item = self.btn_ok, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER,
- border = 10)
- # bindings
- self.btn_apply.Bind(wx.EVT_BUTTON, self.OnApply)
- self.btn_ok.Bind(wx.EVT_BUTTON, self.OnSave)
- def LoadCapFiles(self, ws_cap_files, cmd):
- """!Parse cap files and update dialog.
- For parameters description, see the constructor.
- """
- self.ch_ws_sizer.Clear(deleteWindows = True)
- self.cmd_to_set = cmd
- self.finished_panels_num = 0
- conn = self._getServerConnFromCmd(cmd)
- self.server.SetValue(conn['url'])
- self.password.SetValue(conn['password'])
- self.username.SetValue(conn['username'])
- self.layerName.SetValue(cmd[1]['map'])
- for ws, data in self.ws_panels.iteritems():
- cap_file = None
- if ws_cap_files.has_key(ws):
- cap_file = ws_cap_files[ws]
- data['panel'].ParseCapFile(url = conn['url'],
- username = conn['password'],
- password = conn['username'],
- cap_file = cap_file)
- def _getServerConnFromCmd(self, cmd):
- """!Get url/server/passwod from cmd tuple
- """
- conn = { 'url' : '', 'username' : '', 'password' : ''}
-
- for k in conn.iterkeys():
- if cmd[1].has_key(k):
- conn[k] = cmd[1][k]
- return conn
- def _apply(self):
- """!Apply chosen values from widgets to web service layer."""
- lcmd = self.active_ws_panel.CreateCmd()
- if not lcmd:
- return
- active_ws = self.active_ws_panel.GetWebService()
- if 'WMS' not in active_ws:
- lcmd.append('capfile=' + self.revert_ws_cap_files[active_ws])
- self.giface.GetLayerTree().GetOptData(dcmd = lcmd,
- layer = self.layer,
- params = None,
- propwin = self)
- #TODO use just list or tuple
- cmd = CmdToTuple(lcmd)
- self.revert_cmd = cmd
- self._setRevertCapFiles(self._getCapFiles())
- self.giface.updateMap.emit()
- def UpdateDialogAfterConnection(self):
- """!Connect to the server
- """
- WSDialogBase.UpdateDialogAfterConnection(self)
- if self._getConnectedWS():
- self.btn_ok.SetDefault()
- else:
- self.btn_connect.SetDefault()
- def OnApply(self, event):
- self._apply()
- def OnSave(self, event):
- self._apply()
- self._close()
- def OnClose(self, event):
- """!Close dialog"""
- self._close()
- def _close(self):
- """!Hide dialog"""
- self.Hide()
- self.LoadCapFiles(cmd = self.revert_cmd,
- ws_cap_files = self.revert_ws_cap_files)
- def OnPanelCapParsed(self, error_msg):
- """!Called when panel has downloaded and parsed capabilities file.
- """
- WSDialogBase.OnPanelCapParsed(self, error_msg)
- if self.finished_panels_num == len(self.ws_panels):
- if self.cmd_to_set:
- self._updateWsPanelWidgetsByCmd(self.cmd_to_set)
- self.cmd_to_set = None
- def _updateWsPanelWidgetsByCmd(self, cmd):
- """!Set values of widgets according to parameters in cmd.
- """
- ws = self._getWSfromCmd(cmd)
- if self.ws_panels[ws]['panel'].IsConnected():
- self.ws_panels[ws]['panel'].UpdateWidgetsByCmd(cmd)
- self.choose_ws_rb.SetStringSelection(self.ws_panels[ws]['label'])
- self._showWsPanel(ws)
- def _getWSfromCmd(self, cmd):
- driver = cmd[1]['driver']
- ws = driver.split('_')[0]
-
- if ws == 'WMS':
- ws += '_' + cmd[1]['wms_version']
- return ws
- class SaveWMSLayerDialog(wx.Dialog):
- """!Dialog for saving web service layer into GRASS vector/raster layer.
- @todo Implement saving data in region of map display.
- """
- def __init__(self, parent, layer, giface):
-
- wx.Dialog.__init__(self, parent = parent, title = ("Save web service layer as raster map"), id = wx.ID_ANY)
- self.layer = layer
- self._giface = giface
- self.cmd = self.layer.GetCmd()
- self.thread = CmdThread(self)
- self.cmdStdErr = GStderr(self)
- self._createWidgets()
- def _createWidgets(self):
- self.labels = {}
- self.params = {}
- self.labels['output'] = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Name for output raster map:"))
- self.params['output'] = Select(parent = self, type = 'rast', mapsets = [grass.gisenv()['MAPSET']],
- size = globalvar.DIALOG_GSELECT_SIZE)
- self.regionStBoxLabel = wx.StaticBox(parent = self, id = wx.ID_ANY,
- label = _("Region"))
- self.region_types_order = ['comp', 'named']
- self.region_types = {}
- #self.region_types['map_display'] = wx.RadioButton(parent = self, id = wx.ID_ANY, label = 'Map display', style = wx.RB_GROUP )
- self.region_types['comp'] = wx.RadioButton(parent = self, id = wx.ID_ANY, label = 'Computational region')
- self.region_types['named'] = wx.RadioButton(parent = self, id = wx.ID_ANY, label = 'Named region')
- self.overwrite = wx.CheckBox(parent = self, id = wx.ID_ANY,
- label = _("Overwrite existing raster map"))
- self.named_reg_panel = wx.Panel(parent = self, id = wx.ID_ANY)
- self.labels['region'] = wx.StaticText(parent = self.named_reg_panel, id = wx.ID_ANY,
- label = _("Choose named region:"))
- self.params['region'] = Select(parent = self.named_reg_panel, type = 'region',
- size = globalvar.DIALOG_GSELECT_SIZE)
- # buttons
- self.btn_close = wx.Button(parent = self, id = wx.ID_CLOSE)
- self.btn_close.SetToolTipString(_("Close dialog"))
-
- self.btn_ok = wx.Button(parent = self, id = wx.ID_ANY, label = _("&Save layer"))
- self.btn_ok.SetToolTipString(_("Save web service layer as raster map"))
- # statusbar
- self.statusbar = wx.StatusBar(parent = self, id = wx.ID_ANY)
- self._layout()
- def _layout(self):
- border = wx.BoxSizer(wx.VERTICAL)
- dialogSizer = wx.BoxSizer(wx.VERTICAL)
- regionSizer = wx.BoxSizer(wx.HORIZONTAL)
- dialogSizer.Add(item = self._addSelectSizer(title = self.labels['output'],
- sel = self.params['output']))
- dialogSizer.Add(item = self.overwrite)
- regionSizer = wx.StaticBoxSizer(self.regionStBoxLabel, wx.VERTICAL)
- regionTypeSizer = wx.BoxSizer(wx.HORIZONTAL)
- for r_type in self.region_types_order:
- regionTypeSizer.Add(item = self.region_types[r_type])
- regionSizer.Add(item = regionTypeSizer)
- self.named_reg_panel.SetSizer(self._addSelectSizer(title = self.labels['region'],
- sel = self.params['region']))
- regionSizer.Add(item = self.named_reg_panel)
- self.named_reg_panel.Hide()
- dialogSizer.Add(item = regionSizer, flag = wx.EXPAND)
- # buttons
- self.btnsizer = wx.BoxSizer(orient = wx.HORIZONTAL)
- self.btnsizer.Add(item = self.btn_close, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER,
- border = 10)
-
- self.btnsizer.Add(item = self.btn_ok, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER,
- border = 10)
- dialogSizer.Add(item = self.btnsizer, proportion = 0,
- flag = wx.ALIGN_CENTER)
- border.Add(item = dialogSizer, proportion = 0,
- flag = wx.ALL, border = 5)
- border.Add(item = self.statusbar, proportion = 0)
- self.SetSizer(border)
- self.Layout()
- self.Fit()
- # bindings
- self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
- self.btn_ok.Bind(wx.EVT_BUTTON, self.OnSave)
- self.Bind(EVT_CMD_DONE, self.OnCmdDone)
- self.Bind(EVT_CMD_OUTPUT, self.OnCmdOutput)
- for r_type in self.region_types_order:
- self.Bind(wx.EVT_RADIOBUTTON, self.OnRegionType, self.region_types[r_type])
- def _addSelectSizer(self, title, sel):
- """!Helper layout function.
- """
- selSizer = wx.BoxSizer(orient = wx.VERTICAL)
- selTitleSizer = wx.BoxSizer(wx.HORIZONTAL)
- selTitleSizer.Add(item = title, proportion = 1,
- flag = wx.LEFT | wx.TOP | wx.EXPAND, border = 5)
- selSizer.Add(item = selTitleSizer, proportion = 0,
- flag = wx.EXPAND)
- selSizer.Add(item = sel, proportion = 1,
- flag = wx.EXPAND | wx.ALL| wx.ALIGN_CENTER_VERTICAL,
- border = 5)
- return selSizer
- def OnClose(self, event):
- """!Close dialog
- """
- if not self.IsModal():
- self.Destroy()
- event.Skip()
- def OnRegionType(self, event):
-
- selected = event.GetEventObject()
- if selected == self.region_types['named']:
- self.named_reg_panel.Show()
- else:
- self.named_reg_panel.Hide()
- self.Layout()
- self.Fit()
- def OnSave(self, event):
- """!Import WMS raster data into GRASS as raster layer.
- """
- self.thread.abort(abortall = True)
- currmapset = grass.gisenv()['MAPSET']
-
- self.output = self.params['output'].GetValue().strip()
- l_spl = self.output.strip().split("@")
- # check output layer
- msg = None
- if not self.output:
- msg = _('Missing output raster.')
- elif len(l_spl) > 1 and \
- l_spl[1] != currmapset:
- msg = _('Output map can be added only to current mapset.')
- elif not self.overwrite.IsChecked() and\
- grass.find_file(self.output, 'cell', '.')['fullname']:
- msg = _('Output map <%s> already exists' % self.output)
- if msg:
- GMessage(parent = self,
- message = msg)
- return
- self.output = l_spl[0]
- # check region
- region = self.params['region'].GetValue().strip()
- reg_spl = region.strip().split("@")
- reg_mapset = '.'
- if len(reg_spl) > 1:
- reg_mapset = reg_spl[1]
- if self.region_types['comp'].GetValue() == 1:
- pass
- elif grass.find_file(reg_spl[0], 'region', reg_mapset)['fullname']:
- msg = _('Region <%s> does not exists.' % self.params['region'].GetValue())
- GWarning(parent = self,
- message = msg)
- return
- # create r.in.wms command
- cmd = ('r.in.wms', deepcopy(self.cmd[1]))
- if cmd[1].has_key('map'):
- del cmd[1]['map']
- cmd[1]['output'] = self.output
- if self.overwrite.IsChecked():
- cmd[1]['overwrite'] = True
- if self.region_types['named'].GetValue() == 1:
- cmd[1]['region'] = region
- cmdList = CmdTupleToList(cmd)
- self.currentPid = self.thread.GetId()
- self.thread.RunCmd(cmdList, stderr = self.cmdStdErr)
- self.statusbar.SetStatusText(_("Downloading data..."))
- def OnCmdDone(self, event):
- """!When data are fetched.
- """
- if event.pid != self.currentPid:
- return
- self._addLayer()
- self.statusbar.SetStatusText("")
- def _addLayer(self):
- """!Add layer into layer tree.
- """
- llist = self._giface.GetLayerList()
- if len(llist.GetLayersByName(self.output)) == 0:
- cmd = ['d.rast', 'map=' + self.output]
- llist.AddLayer(ltype='raster',
- name=self.output,
- cmd=cmd,
- checked=True)
- def OnCmdOutput(self, event):
- """!Handle cmd output according to debug level.
- """
- if Debug.GetLevel() == 0:
- if event.type == 'error':
- msg = _('Unable to fetch data.\n')
- msg += event.text
- GWarning(parent = self,
- message = msg)
- else:
- Debug.msg(1, event.text)
|