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