|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
00001 """! 00002 @package module.ogc_services 00003 00004 @brief Dialogs for OGC services 00005 00006 Currently only implemeted WMS. 00007 00008 List of classes: 00009 - ogc_services::WMSDialog 00010 - ogc_services::LayersList 00011 00012 (C) 2009-2011 by the GRASS Development Team 00013 00014 This program is free software under the GNU General Public License 00015 (>=v2). Read the file COPYING that comes with GRASS for details. 00016 00017 @author Martin Landa <landa.martin gmail.com> 00018 """ 00019 00020 import wx 00021 from wx.gizmos import TreeListCtrl 00022 import wx.lib.mixins.listctrl as listmix 00023 00024 from core.gcmd import RunCommand 00025 from core.settings import UserSettings 00026 00027 class WMSDialog(wx.Dialog): 00028 def __init__(self, parent, service = 'wms', 00029 id=wx.ID_ANY, 00030 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): 00031 """!Dialog to import data from WMS server""" 00032 self.parent = parent # GMFrame 00033 self.service = service # currently only WMS is implemented 00034 00035 wx.Dialog.__init__(self, parent, id, style=style) 00036 if self.service == 'wms': 00037 self.SetTitle(_("Import data from WMS server")) 00038 00039 self.panel = wx.Panel(parent = self, id = wx.ID_ANY) 00040 00041 self.__createWidgets() 00042 00043 self.__doLayout() 00044 00045 self.SetMinSize((550, 400)) 00046 00047 def __createWidgets(self): 00048 """!Create dialog widgets""" 00049 # 00050 # settings 00051 # 00052 self.settingsBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY, 00053 label = _(" Server settings ")) 00054 00055 self.serverText = wx.StaticText(parent = self.panel, id = wx.ID_ANY, label = _("Server:")) 00056 self.server = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY) 00057 00058 # 00059 # list of layers 00060 # 00061 self.layersBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY, 00062 label=_(" List of layers ")) 00063 00064 self.list = LayersList(self.panel) 00065 self.list.LoadData() 00066 00067 self.add = wx.CheckBox(parent=self.panel, id=wx.ID_ANY, 00068 label=_("Add imported layers into layer tree")) 00069 self.add.SetValue(UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled')) 00070 00071 # 00072 # buttons 00073 # 00074 # cancel 00075 self.btn_cancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL) 00076 self.btn_cancel.SetToolTipString(_("Close dialog")) 00077 # connect 00078 self.btn_connect = wx.Button(parent = self.panel, id = wx.ID_ANY, label = _("&Connect")) 00079 self.btn_connect.SetToolTipString(_("Connect to the server")) 00080 self.btn_connect.SetDefault() 00081 if not self.server.GetValue(): 00082 self.btn_connect.Enable(False) 00083 # import 00084 self.btn_import = wx.Button(parent = self.panel, id = wx.ID_OK, label = _("&Import")) 00085 self.btn_import.SetToolTipString(_("Import selected layers")) 00086 self.btn_import.Enable(False) 00087 00088 # 00089 # bindings 00090 # 00091 self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) 00092 self.btn_connect.Bind(wx.EVT_BUTTON, self.OnConnect) 00093 self.server.Bind(wx.EVT_TEXT, self.OnServer) 00094 00095 def __doLayout(self): 00096 """!Do dialog layout""" 00097 dialogSizer = wx.BoxSizer(wx.VERTICAL) 00098 00099 # 00100 # settings 00101 # 00102 settingsSizer = wx.StaticBoxSizer(self.settingsBox, wx.HORIZONTAL) 00103 00104 gridSizer = wx.FlexGridSizer(cols=2, vgap=5, hgap=5) 00105 00106 gridSizer.Add(item=self.serverText, 00107 flag=wx.ALIGN_CENTER_VERTICAL) 00108 gridSizer.AddGrowableCol(1) 00109 gridSizer.Add(item=self.server, 00110 flag=wx.EXPAND | wx.ALL) 00111 00112 settingsSizer.Add(item=gridSizer, proportion=1, 00113 flag=wx.EXPAND | wx.ALL) 00114 00115 dialogSizer.Add(item=settingsSizer, proportion=0, 00116 flag=wx.ALL | wx.EXPAND, border=5) 00117 00118 # 00119 # list of layers 00120 # 00121 layersSizer = wx.StaticBoxSizer(self.layersBox, wx.HORIZONTAL) 00122 00123 layersSizer.Add(item=self.list, proportion=1, 00124 flag=wx.ALL | wx.EXPAND, border=5) 00125 00126 dialogSizer.Add(item=layersSizer, proportion=1, 00127 flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5) 00128 00129 dialogSizer.Add(item=self.add, proportion=0, 00130 flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5) 00131 00132 # 00133 # buttons 00134 # 00135 btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL) 00136 00137 btnsizer.Add(item=self.btn_cancel, proportion=0, 00138 flag=wx.ALL | wx.ALIGN_CENTER, 00139 border=10) 00140 00141 btnsizer.Add(item=self.btn_connect, proportion=0, 00142 flag=wx.ALL | wx.ALIGN_CENTER, 00143 border=10) 00144 00145 btnsizer.Add(item=self.btn_import, proportion=0, 00146 flag=wx.ALL | wx.ALIGN_CENTER, 00147 border=10) 00148 00149 dialogSizer.Add(item=btnsizer, proportion=0, 00150 flag=wx.ALIGN_CENTER) 00151 00152 self.panel.SetAutoLayout(True) 00153 self.panel.SetSizer(dialogSizer) 00154 dialogSizer.Fit(self.panel) 00155 self.Layout() 00156 00157 def OnCancel(self, event): 00158 """!Button 'Cancel' pressed -> close the dialog""" 00159 self.Close() 00160 00161 def OnConnect(self, event): 00162 """!Button 'Connect' pressed""" 00163 server = self.server.GetValue() 00164 if not server: 00165 self.btn_import.Enable(False) 00166 return # not reachable 00167 00168 layers = {} 00169 ret = RunCommand('r.in.wms', 00170 quiet = True, 00171 parent = self, 00172 read = True, 00173 flags = 'l', 00174 mapserver = server) 00175 00176 if not ret: 00177 self.list.LoadData() 00178 self.btn_import.Enable(False) 00179 return # no layers found 00180 00181 lastLayer = lastStyle = '' 00182 for line in ret.splitlines(): 00183 try: 00184 key, value = line.split(':', 1) 00185 except ValueError: 00186 continue 00187 key = key.strip().lower() 00188 value = value.strip() 00189 00190 if key == 'layer': 00191 layers[value] = {} 00192 lastLayer = value 00193 elif key == 'title': 00194 layers[lastLayer][key] = value 00195 elif key == 'style': 00196 if 'style' not in layers[lastLayer]: 00197 layers[lastLayer]['style'] = {} 00198 layers[lastLayer]['style'][value] = '' 00199 lastStyle = value 00200 elif key == 'style title': 00201 layers[lastLayer]['style'][lastStyle] = value 00202 00203 # update list of layers 00204 self.list.LoadData(layers) 00205 00206 if len(layers.keys()) > 0: 00207 self.btn_import.Enable(True) 00208 else: 00209 self.btn_import.Enable(False) 00210 00211 def OnServer(self, event): 00212 """!Server settings changed""" 00213 value = event.GetString() 00214 if value: 00215 self.btn_connect.Enable(True) 00216 else: 00217 self.btn_connect.Enable(False) 00218 00219 def GetLayers(self): 00220 """!Get list of selected layers/styles to be imported""" 00221 return self.list.GetSelectedLayers() 00222 00223 def GetSettings(self): 00224 """!Get connection settings""" 00225 return { 'server' : self.server.GetValue() } 00226 00227 class LayersList(TreeListCtrl, listmix.ListCtrlAutoWidthMixin): 00228 def __init__(self, parent, pos=wx.DefaultPosition): 00229 """!List of layers to be imported (dxf, shp...)""" 00230 self.parent = parent 00231 00232 TreeListCtrl.__init__(self, parent, wx.ID_ANY, 00233 style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | 00234 wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_MULTIPLE) 00235 00236 # setup mixins 00237 listmix.ListCtrlAutoWidthMixin.__init__(self) 00238 00239 self.AddColumn(_('Layer / Style')) 00240 self.AddColumn(_('Title')) 00241 self.SetMainColumn(0) # column with the tree 00242 self.SetColumnWidth(0, 175) 00243 00244 self.root = None 00245 00246 def LoadData(self, data = {}): 00247 """!Load data into list""" 00248 # detete first all items 00249 self.DeleteAllItems() 00250 self.root = self.AddRoot(_("Layers")) 00251 00252 layers = data.keys() 00253 if not layers: 00254 return 00255 00256 layers.sort() 00257 00258 for layer in layers: 00259 title = data[layer]['title'] 00260 lchild = self.AppendItem(self.root, layer) 00261 self.SetItemText(lchild, title, 1) 00262 if 'style' in data[layer]: 00263 styles = data[layer]['style'].keys() 00264 if not styles: 00265 continue 00266 styles.sort() 00267 for style in styles: 00268 title = data[layer]['style'][style] 00269 schild = self.AppendItem(lchild, style) 00270 self.SetItemText(schild, title, 1) 00271 00272 self.Expand(self.root) 00273 00274 def GetItemCount(self): 00275 """!Required for listmix.ListCtrlAutoWidthMixin""" 00276 return 0 00277 00278 def GetCountPerPage(self): 00279 """!Required for listmix.ListCtrlAutoWidthMixin""" 00280 return 0 00281 00282 def GetSelectedLayers(self): 00283 """!Get selected layers/styles""" 00284 layers = dict() 00285 00286 for item in self.GetSelections(): 00287 parent = self.GetItemParent(item) 00288 if parent == self.root: # -> layer 00289 layer = self.GetItemText(item, 0) 00290 layers[layer] = list() 00291 sitem, cookie = self.GetFirstChild(item) 00292 while sitem: 00293 layers[layer].append(self.GetItemText(sitem, 0)) 00294 sitem, cookie = self.GetNextChild(item, cookie) 00295 else: # -> style 00296 layer = self.GetItemText(parent, 0) 00297 layers[layer] = list() 00298 layers[layer].append(self.GetItemText(item, 0)) 00299 00300 return layers