Пример #1
0
    def __init__(self,
                 parent,
                 id=wx.ID_ANY,
                 title=None,
                 vectorName=None,
                 item=None,
                 log=None,
                 selection=None,
                 **kwargs):
        """GRASS Attribute Table Manager window

        :param parent: parent window
        :param id: window id
        :param title: window title or None for default title
        :param vectorName: name of vector map
        :param item: item from Layer Tree
        :param log: log window
        :param selection: name of page to be selected
        :param kwagrs: other wx.Frame's arguments
        """
        self.parent = parent
        try:
            mapdisplay = self.parent.GetMapDisplay()
        except:
            mapdisplay = None

        DbMgrBase.__init__(self,
                           id=id,
                           mapdisplay=mapdisplay,
                           vectorName=vectorName,
                           item=item,
                           log=log,
                           statusbar=self,
                           **kwargs)

        wx.Frame.__init__(self, parent, id, *kwargs)

        # title
        if not title:
            title = "%s" % _("GRASS GIS Attribute Table Manager - ")
            if not self.dbMgrData['editable']:
                title += _("READONLY - ")
            title += "<%s>" % (self.dbMgrData['vectName'])

        self.SetTitle(title)

        # icon
        self.SetIcon(
            wx.Icon(os.path.join(globalvar.ICONDIR, 'grass_sql.ico'),
                    wx.BITMAP_TYPE_ICO))

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        if len(self.dbMgrData['mapDBInfo'].layers.keys()) == 0:
            GMessage(parent=self.parent,
                     message=_("Database connection for vector map <%s> "
                               "is not defined in DB file. "
                               "You can define new connection in "
                               "'Manage layers' tab.") %
                     self.dbMgrData['vectName'])

        busy = wx.BusyInfo(_("Please wait, loading attribute data..."),
                           parent=self.parent)
        wx.SafeYield()
        self.CreateStatusBar(number=1)

        self.notebook = GNotebook(self.panel, style=globalvar.FNPageDStyle)

        self.CreateDbMgrPage(parent=self, pageName='browse')

        self.notebook.AddPage(page=self.pages['browse'],
                              text=_("Browse data"),
                              name='browse')
        self.pages['browse'].SetTabAreaColour(globalvar.FNPageColor)

        self.CreateDbMgrPage(parent=self, pageName='manageTable')

        self.notebook.AddPage(page=self.pages['manageTable'],
                              text=_("Manage tables"),
                              name='table')
        self.pages['manageTable'].SetTabAreaColour(globalvar.FNPageColor)

        self.CreateDbMgrPage(parent=self, pageName='manageLayer')
        self.notebook.AddPage(page=self.pages['manageLayer'],
                              text=_("Manage layers"),
                              name='layers')
        del busy

        if selection:
            wx.CallAfter(self.notebook.SetSelectionByName, selection)
        else:
            wx.CallAfter(self.notebook.SetSelection, 0)  # select browse tab

        # buttons
        self.btnClose = CloseButton(parent=self.panel)
        self.btnClose.SetToolTip(_("Close Attribute Table Manager"))
        self.btnReload = Button(parent=self.panel, id=wx.ID_REFRESH)
        self.btnReload.SetToolTip(
            _("Reload currently selected attribute data"))
        self.btnReset = ClearButton(parent=self.panel)
        self.btnReset.SetToolTip(
            _("Reload all attribute data (drop current selection)"))

        # bind closing to ESC
        self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_CANCEL)
        accelTableList = [(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, wx.ID_CANCEL)]
        accelTable = wx.AcceleratorTable(accelTableList)
        self.SetAcceleratorTable(accelTable)

        # events
        self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
        self.btnReload.Bind(wx.EVT_BUTTON, self.OnReloadData)
        self.btnReset.Bind(wx.EVT_BUTTON, self.OnReloadDataAll)
        self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED,
                           self.OnPageChanged)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        # do layout
        self._layout()

        # self.SetMinSize(self.GetBestSize())
        self.SetSize((700, 550))  # FIXME hard-coded size
        self.SetMinSize(self.GetSize())
Пример #2
0
    def __init__(self, parent, web_service, **kwargs):
        """Show data from capabilities file.

        Signal: capParsed - this signal is emitted when capabilities file is downloaded
                            (after ConnectToServer method was called)

        :param parent:  parent widget
        :param web_service:  web service to be panel generated for
        """
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

        self.parent = parent
        self.ws = web_service

        self.capParsed = Signal('WSPanel.capParsed')

        # stores widgets, which represents parameters/flags of d.wms
        self.params = {}
        self.flags = {}

        self.o_layer_name = ''

        # stores err output from r.in.wms during getting capabilities
        self.cmd_err_str = ''

        # stores selected layer from layer list
        self.sel_layers = []

        # downloaded and parsed data from server successfully?
        self.is_connected = False

        # common part of command for r.in.wms -c and d.wms
        self.ws_cmdl = None

        # provides information about driver parameters
        self.drv_info = WMSDriversInfo()
        self.drv_props = self.drv_info.GetDrvProperties(self.ws)

        self.ws_drvs = {
            'WMS_1.1.1': {
                'cmd': [
                    'wms_version=1.1.1',
                    'driver=WMS_GRASS'],
                'cap_parser': lambda temp_file: WMSCapabilities(
                    temp_file,
                    '1.1.1'),
            },
            'WMS_1.3.0': {
                'cmd': [
                    'wms_version=1.3.0',
                    'driver=WMS_GRASS'],
                'cap_parser': lambda temp_file: WMSCapabilities(
                    temp_file,
                    '1.3.0'),
            },
            'WMTS': {
                'cmd': ['driver=WMTS_GRASS'],
                'cap_parser': WMTSCapabilities,
            },
            'OnEarth': {
                'cmd': ['driver=OnEarth_GRASS'],
                'cap_parser': OnEarthCapabilities,
            }}

        self.cmdStdErr = GStderr(self)
        self.cmd_thread = CmdThread(self)
        self.cap_file = grass.tempfile()

        reqDataBox = StaticBox(
            parent=self, label=_(" Requested data settings "))
        self._nb_sizer = wx.StaticBoxSizer(reqDataBox, wx.VERTICAL)
        self.notebook = GNotebook(
            parent=self,
            style=FN.FNB_FANCY_TABS | FN.FNB_NO_X_BUTTON | FN.FNB_NODRAG)

        self._requestPage()
        self._advancedSettsPage()

        self._layout()

        self.layerSelected = self.list.layerSelected

        self.Bind(EVT_CMD_DONE, self.OnCapDownloadDone)
        self.Bind(EVT_CMD_OUTPUT, self.OnCmdOutput)

        self.SetMinSize((-1, 300))
Пример #3
0
class AttributeManager(wx.Frame, DbMgrBase):
    def __init__(self,
                 parent,
                 id=wx.ID_ANY,
                 title=None,
                 vectorName=None,
                 item=None,
                 log=None,
                 selection=None,
                 **kwargs):
        """GRASS Attribute Table Manager window

        :param parent: parent window
        :param id: window id
        :param title: window title or None for default title
        :param vectorName: name of vector map
        :param item: item from Layer Tree
        :param log: log window
        :param selection: name of page to be selected
        :param kwagrs: other wx.Frame's arguments
        """
        self.parent = parent
        try:
            mapdisplay = self.parent.GetMapDisplay()
        except:
            mapdisplay = None

        DbMgrBase.__init__(self,
                           id=id,
                           mapdisplay=mapdisplay,
                           vectorName=vectorName,
                           item=item,
                           log=log,
                           statusbar=self,
                           **kwargs)

        wx.Frame.__init__(self, parent, id, *kwargs)

        # title
        if not title:
            title = "%s" % _("GRASS GIS Attribute Table Manager - ")
            if not self.dbMgrData['editable']:
                title += _("READONLY - ")
            title += "<%s>" % (self.dbMgrData['vectName'])

        self.SetTitle(title)

        # icon
        self.SetIcon(
            wx.Icon(os.path.join(globalvar.ICONDIR, 'grass_sql.ico'),
                    wx.BITMAP_TYPE_ICO))

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        if len(self.dbMgrData['mapDBInfo'].layers.keys()) == 0:
            GMessage(parent=self.parent,
                     message=_("Database connection for vector map <%s> "
                               "is not defined in DB file. "
                               "You can define new connection in "
                               "'Manage layers' tab.") %
                     self.dbMgrData['vectName'])

        busy = wx.BusyInfo(_("Please wait, loading attribute data..."),
                           parent=self.parent)
        wx.SafeYield()
        self.CreateStatusBar(number=1)

        self.notebook = GNotebook(self.panel, style=globalvar.FNPageDStyle)

        self.CreateDbMgrPage(parent=self, pageName='browse')

        self.notebook.AddPage(page=self.pages['browse'],
                              text=_("Browse data"),
                              name='browse')
        self.pages['browse'].SetTabAreaColour(globalvar.FNPageColor)

        self.CreateDbMgrPage(parent=self, pageName='manageTable')

        self.notebook.AddPage(page=self.pages['manageTable'],
                              text=_("Manage tables"),
                              name='table')
        self.pages['manageTable'].SetTabAreaColour(globalvar.FNPageColor)

        self.CreateDbMgrPage(parent=self, pageName='manageLayer')
        self.notebook.AddPage(page=self.pages['manageLayer'],
                              text=_("Manage layers"),
                              name='layers')
        del busy

        if selection:
            wx.CallAfter(self.notebook.SetSelectionByName, selection)
        else:
            wx.CallAfter(self.notebook.SetSelection, 0)  # select browse tab

        # buttons
        self.btnClose = CloseButton(parent=self.panel)
        self.btnClose.SetToolTip(_("Close Attribute Table Manager"))
        self.btnReload = Button(parent=self.panel, id=wx.ID_REFRESH)
        self.btnReload.SetToolTip(
            _("Reload currently selected attribute data"))
        self.btnReset = ClearButton(parent=self.panel)
        self.btnReset.SetToolTip(
            _("Reload all attribute data (drop current selection)"))

        # bind closing to ESC
        self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_CANCEL)
        accelTableList = [(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, wx.ID_CANCEL)]
        accelTable = wx.AcceleratorTable(accelTableList)
        self.SetAcceleratorTable(accelTable)

        # events
        self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
        self.btnReload.Bind(wx.EVT_BUTTON, self.OnReloadData)
        self.btnReset.Bind(wx.EVT_BUTTON, self.OnReloadDataAll)
        self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED,
                           self.OnPageChanged)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        # do layout
        self._layout()

        # self.SetMinSize(self.GetBestSize())
        self.SetSize((700, 550))  # FIXME hard-coded size
        self.SetMinSize(self.GetSize())

    def _layout(self):
        """Do layout"""
        # frame body
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        # buttons
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(self.btnReset, proportion=1, flag=wx.ALL, border=5)
        btnSizer.Add(self.btnReload, proportion=1, flag=wx.ALL, border=5)
        btnSizer.Add(self.btnClose, proportion=1, flag=wx.ALL, border=5)

        mainSizer.Add(self.notebook, proportion=1, flag=wx.EXPAND)
        mainSizer.Add(btnSizer, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)

        self.panel.SetAutoLayout(True)
        self.panel.SetSizer(mainSizer)
        mainSizer.Fit(self.panel)
        self.Layout()

    def OnCloseWindow(self, event):
        """Cancel button pressed"""
        if self.parent and self.parent.GetName() == 'LayerManager':
            # deregister ATM
            self.parent.dialogs['atm'].remove(self)

        if not isinstance(event, wx.CloseEvent):
            self.Destroy()

        event.Skip()

    def OnReloadData(self, event):
        """Reload data"""
        if self.pages['browse']:
            self.pages['browse'].OnDataReload(event)  # TODO replace by signal

    def OnReloadDataAll(self, event):
        """Reload all data"""
        if self.pages['browse']:
            self.pages['browse'].ResetPage()

    def OnPageChanged(self, event):
        """On page in ATM is changed"""
        try:
            if self.pages["browse"]:
                selPage = self.pages["browse"].selLayer
                id = self.pages["browse"].layerPage[selPage]['data']
            else:
                id = None
        except KeyError:
            id = None

        if event.GetSelection() == self.notebook.GetPageIndexByName(
                'browse') and id:
            win = self.FindWindowById(id)
            if win:
                self.log.write(
                    _("Number of loaded records: %d") % win.GetItemCount())
            else:
                self.log.write("")
            self.btnReload.Enable()
            self.btnReset.Enable()
        else:
            self.log.write("")
            self.btnReload.Enable(False)
            self.btnReset.Enable(False)

        event.Skip()

    def OnTextEnter(self, event):
        pass

    def UpdateDialog(self, layer):
        """Updates dialog layout for given layer"""
        DbMgrBase.UpdateDialog(self, layer=layer)
        # set current page selection
        self.notebook.SetSelectionByName('layers')
Пример #4
0
class TplotFrame(wx.Frame):
    """The main frame of the application"""
    def __init__(self, parent, giface):
        wx.Frame.__init__(self,
                          parent,
                          id=wx.ID_ANY,
                          title=_("GRASS GIS Temporal Plot Tool"))

        tgis.init(True)
        self._giface = giface
        self.datasetsV = None
        self.datasetsR = None
        # self.vectorDraw=False
        # self.rasterDraw=False
        self.init()
        self._layout()

        # We create a database interface here to speedup the GUI
        self.dbif = tgis.SQLDatabaseInterfaceConnection()
        self.dbif.connect()
        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.region = Region()

    def init(self):
        self.timeDataR = OrderedDict()
        self.timeDataV = OrderedDict()
        self.temporalType = None
        self.unit = None
        self.listWhereConditions = []
        self.plotNameListR = []
        self.plotNameListV = []
        self.poi = None

    def __del__(self):
        """Close the database interface and stop the messenger and C-interface
           subprocesses.
        """
        if self.dbif.connected is True:
            self.dbif.close()
        tgis.stop_subprocesses()

    def onClose(self, evt):
        if self._giface.GetMapDisplay():
            self.coorval.OnClose()
            self.cats.OnClose()
        self.__del__()
        self.Destroy()

    def _layout(self):
        """Creates the main panel with all the controls on it:
             * mpl canvas
             * mpl navigation toolbar
             * Control panel for interaction
        """
        self.mainPanel = wx.Panel(self)
        # Create the mpl Figure and FigCanvas objects.
        # 5x4 inches, 100 dots-per-inch
        #
        # color =  wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
        # ------------CANVAS AND TOOLBAR------------
        self.fig = Figure((5.0, 4.0), facecolor=(1, 1, 1))
        self.canvas = FigCanvas(self.mainPanel, wx.ID_ANY, self.fig)
        # axes are initialized later
        self.axes2d = None
        self.axes3d = None

        # Create the navigation toolbar, tied to the canvas
        #
        self.toolbar = NavigationToolbar(self.canvas)

        #
        # Layout
        #
        # ------------MAIN VERTICAL SIZER------------
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.EXPAND)
        self.vbox.Add(self.toolbar, 0, wx.EXPAND)
        # self.vbox.AddSpacer(10)

        # ------------ADD NOTEBOOK------------
        self.ntb = GNotebook(parent=self.mainPanel, style=FN.FNB_FANCY_TABS)

        # ------------ITEMS IN NOTEBOOK PAGE (RASTER)------------------------

        self.controlPanelRaster = wx.Panel(parent=self.ntb, id=wx.ID_ANY)
        self.datasetSelectLabelR = wx.StaticText(
            parent=self.controlPanelRaster,
            id=wx.ID_ANY,
            label=_('Raster temporal '
                    'dataset (strds)'))

        self.datasetSelectR = gselect.Select(
            parent=self.controlPanelRaster,
            id=wx.ID_ANY,
            size=globalvar.DIALOG_GSELECT_SIZE,
            type='strds',
            multiple=True)
        self.coor = wx.StaticText(parent=self.controlPanelRaster,
                                  id=wx.ID_ANY,
                                  label=_('X and Y coordinates separated by '
                                          'comma:'))
        try:
            self._giface.GetMapWindow()
            self.coorval = gselect.CoordinatesSelect(
                parent=self.controlPanelRaster, giface=self._giface)
        except:
            self.coorval = wx.TextCtrl(parent=self.controlPanelRaster,
                                       id=wx.ID_ANY,
                                       size=globalvar.DIALOG_TEXTCTRL_SIZE,
                                       validator=CoordinatesValidator())

        self.coorval.SetToolTipString(
            _("Coordinates can be obtained for example"
              " by right-clicking on Map Display."))
        self.controlPanelSizerRaster = wx.BoxSizer(wx.VERTICAL)
        # self.controlPanelSizer.Add(wx.StaticText(self.panel, id=wx.ID_ANY,
        # label=_("Select space time raster dataset(s):")),
        # pos=(0, 0), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        self.controlPanelSizerRaster.Add(self.datasetSelectLabelR,
                                         flag=wx.EXPAND)
        self.controlPanelSizerRaster.Add(self.datasetSelectR, flag=wx.EXPAND)

        self.controlPanelSizerRaster.Add(self.coor, flag=wx.EXPAND)
        self.controlPanelSizerRaster.Add(self.coorval, flag=wx.EXPAND)

        self.controlPanelRaster.SetSizer(self.controlPanelSizerRaster)
        self.controlPanelSizerRaster.Fit(self)
        self.ntb.AddPage(page=self.controlPanelRaster,
                         text=_('STRDS'),
                         name='STRDS')

        # ------------ITEMS IN NOTEBOOK PAGE (VECTOR)------------------------
        self.controlPanelVector = wx.Panel(parent=self.ntb, id=wx.ID_ANY)
        self.datasetSelectLabelV = wx.StaticText(
            parent=self.controlPanelVector,
            id=wx.ID_ANY,
            label=_('Vector temporal '
                    'dataset (stvds)\n'
                    'Press ENTER if you'
                    ' type the name of the'
                    ' stvds instead of'
                    ' selecting with the'
                    ' combobox'))
        self.datasetSelectV = gselect.Select(
            parent=self.controlPanelVector,
            id=wx.ID_ANY,
            size=globalvar.DIALOG_GSELECT_SIZE,
            type='stvds',
            multiple=True)
        self.datasetSelectV.Bind(wx.EVT_TEXT, self.OnVectorSelected)

        self.attribute = gselect.ColumnSelect(parent=self.controlPanelVector)
        self.attributeLabel = wx.StaticText(parent=self.controlPanelVector,
                                            id=wx.ID_ANY,
                                            label=_('Select attribute column'))
        # TODO fix the category selection as done for coordinates
        try:
            self._giface.GetMapWindow()
            self.cats = gselect.VectorCategorySelect(
                parent=self.controlPanelVector, giface=self._giface)
        except:
            self.cats = wx.TextCtrl(parent=self.controlPanelVector,
                                    id=wx.ID_ANY,
                                    size=globalvar.DIALOG_TEXTCTRL_SIZE)
        self.catsLabel = wx.StaticText(parent=self.controlPanelVector,
                                       id=wx.ID_ANY,
                                       label=_('Select category of vector(s)'))

        self.controlPanelSizerVector = wx.BoxSizer(wx.VERTICAL)
        # self.controlPanelSizer.Add(wx.StaticText(self.panel, id=wx.ID_ANY,
        # label=_("Select space time raster dataset(s):")),
        # pos=(0, 0), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        self.controlPanelSizerVector.Add(self.datasetSelectLabelV,
                                         flag=wx.EXPAND)
        self.controlPanelSizerVector.Add(self.datasetSelectV, flag=wx.EXPAND)

        self.controlPanelSizerVector.Add(self.attributeLabel, flag=wx.EXPAND)
        self.controlPanelSizerVector.Add(self.attribute, flag=wx.EXPAND)

        self.controlPanelSizerVector.Add(self.catsLabel, flag=wx.EXPAND)
        self.controlPanelSizerVector.Add(self.cats, flag=wx.EXPAND)

        self.controlPanelVector.SetSizer(self.controlPanelSizerVector)
        self.controlPanelSizerVector.Fit(self)
        self.ntb.AddPage(page=self.controlPanelVector,
                         text=_('STVDS'),
                         name='STVDS')

        # ------------Buttons on the bottom(draw,help)------------
        self.vButtPanel = wx.Panel(self.mainPanel, id=wx.ID_ANY)
        self.vButtSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.drawButton = wx.Button(self.vButtPanel,
                                    id=wx.ID_ANY,
                                    label=_("Draw"))
        self.drawButton.Bind(wx.EVT_BUTTON, self.OnRedraw)
        self.helpButton = wx.Button(self.vButtPanel,
                                    id=wx.ID_ANY,
                                    label=_("Help"))
        self.helpButton.Bind(wx.EVT_BUTTON, self.OnHelp)
        self.vButtSizer.Add(self.drawButton)
        self.vButtSizer.Add(self.helpButton)
        self.vButtPanel.SetSizer(self.vButtSizer)

        self.mainPanel.SetSizer(self.vbox)
        self.vbox.Add(self.ntb, flag=wx.EXPAND)
        self.vbox.Add(self.vButtPanel, flag=wx.EXPAND)
        self.vbox.Fit(self)
        self.mainPanel.Fit()

    def _getSTRDdata(self, timeseries):
        """Load data and read properties
        :param list timeseries: a list of timeseries
        """
        if not self.poi:
            GError(parent=self,
                   message=_("Invalid input coordinates"),
                   showTraceback=False)
            return
        mode = None
        unit = None
        columns = ','.join(['name', 'start_time', 'end_time'])
        for series in timeseries:
            name = series[0]
            fullname = name + '@' + series[1]
            etype = series[2]
            sp = tgis.dataset_factory(etype, fullname)
            if not sp.is_in_db(dbif=self.dbif):
                GError(message=_("Dataset <%s> not found in temporal "
                                 "database") % (fullname),
                       parent=self)
                return
            sp.select(dbif=self.dbif)

            minmin = sp.metadata.get_min_min()
            self.plotNameListR.append(name)
            self.timeDataR[name] = OrderedDict()

            self.timeDataR[name]['temporalDataType'] = etype
            self.timeDataR[name]['temporalType'] = sp.get_temporal_type()
            self.timeDataR[name]['granularity'] = sp.get_granularity()

            if mode is None:
                mode = self.timeDataR[name]['temporalType']
            elif self.timeDataR[name]['temporalType'] != mode:
                GError(parent=self,
                       message=_("Datasets have different temporal"
                                 " type (absolute x relative), "
                                 "which is not allowed."))
                return

            # check topology
            maps = sp.get_registered_maps_as_objects(dbif=self.dbif)
            self.timeDataR[name]['validTopology'] = sp.check_temporal_topology(
                maps=maps, dbif=self.dbif)

            self.timeDataR[name]['unit'] = None  # only with relative
            if self.timeDataR[name]['temporalType'] == 'relative':
                start, end, self.timeDataR[name][
                    'unit'] = sp.get_relative_time()
                if unit is None:
                    unit = self.timeDataR[name]['unit']
                elif self.timeDataR[name]['unit'] != unit:
                    GError(parent=self,
                           message=_("Datasets have different "
                                     "time unit which is not "
                                     "allowed."))
                    return

            rows = sp.get_registered_maps(columns=columns,
                                          where=None,
                                          order='start_time',
                                          dbif=self.dbif)
            for row in rows:
                self.timeDataR[name][row[0]] = {}
                self.timeDataR[name][row[0]]['start_datetime'] = row[1]
                self.timeDataR[name][row[0]]['end_datetime'] = row[2]
                r = RasterRow(row[0])
                r.open()
                val = r.get_value(self.poi)
                r.close()
                if val == -2147483648 and val < minmin:
                    self.timeDataR[name][row[0]]['value'] = None
                else:
                    self.timeDataR[name][row[0]]['value'] = val

        self.unit = unit
        self.temporalType = mode
        return

    def _parseVDbConn(self, mapp, layerInp):
        '''find attribute key according to layer of input map'''
        vdb = Module('v.db.connect', map=mapp, flags='g', stdout_=PIPE)

        vdb = vdb.outputs.stdout
        for line in vdb.splitlines():
            lsplit = line.split('|')
            layer = lsplit[0].split('/')[0]
            if str(layer) == str(layerInp):
                return lsplit[2]
        return None

    def _getExistingCategories(self, mapp, cats):
        """Get a list of categories for a vector map"""
        vdb = grass.read_command('v.category', input=mapp, option='print')
        categories = vdb.splitlines()
        for cat in cats:
            if str(cat) not in categories:
                GMessage(message=_("Category {ca} is not on vector map"
                                   " {ma} and it will be not used").format(
                                       ma=mapp, ca=cat),
                         parent=self)
                cats.remove(cat)
        return cats

    def _getSTVDData(self, timeseries):
        """Load data and read properties
        :param list timeseries: a list of timeseries
        """

        mode = None
        unit = None
        cats = None
        attribute = self.attribute.GetValue()
        if self.cats.GetValue() != '':
            cats = self.cats.GetValue().split(',')
        if cats and self.poi:
            GMessage(message=_("Both coordinates and categories are set, "
                               "coordinates will be used. The use categories "
                               "remove text from coordinate form"))
        if not attribute or attribute == '':
            GError(parent=self,
                   showTraceback=False,
                   message=_("With Vector temporal dataset you have to select"
                             " an attribute column"))
            return
        columns = ','.join(['name', 'start_time', 'end_time', 'id', 'layer'])
        for series in timeseries:
            name = series[0]
            fullname = name + '@' + series[1]
            etype = series[2]
            sp = tgis.dataset_factory(etype, fullname)
            if not sp.is_in_db(dbif=self.dbif):
                GError(message=_("Dataset <%s> not found in temporal "
                                 "database") % (fullname),
                       parent=self,
                       showTraceback=False)
                return
            sp.select(dbif=self.dbif)

            rows = sp.get_registered_maps(dbif=self.dbif,
                                          order="start_time",
                                          columns=columns,
                                          where=None)

            self.timeDataV[name] = OrderedDict()
            self.timeDataV[name]['temporalDataType'] = etype
            self.timeDataV[name]['temporalType'] = sp.get_temporal_type()
            self.timeDataV[name]['granularity'] = sp.get_granularity()

            if mode is None:
                mode = self.timeDataV[name]['temporalType']
            elif self.timeDataV[name]['temporalType'] != mode:
                GError(parent=self,
                       showTraceback=False,
                       message=_(
                           "Datasets have different temporal type ("
                           "absolute x relative), which is not allowed."))
                return
            self.timeDataV[name]['unit'] = None  # only with relative
            if self.timeDataV[name]['temporalType'] == 'relative':
                start, end, self.timeDataV[name][
                    'unit'] = sp.get_relative_time()
                if unit is None:
                    unit = self.timeDataV[name]['unit']
                elif self.timeDataV[name]['unit'] != unit:
                    GError(message=_("Datasets have different time unit which"
                                     " is not allowed."),
                           parent=self,
                           showTraceback=False)
                    return
            if self.poi:
                self.plotNameListV.append(name)
                # TODO set an appropriate distance, right now a big one is set
                # to return the closer point to the selected one
                out = grass.vector_what(map='pois_srvds',
                                        coord=self.poi.coords(),
                                        distance=10000000000000000)
                if len(out) != len(rows):
                    GError(parent=self,
                           showTraceback=False,
                           message=_("Difference number of vector layers and "
                                     "maps in the vector temporal dataset"))
                    return
                for i in range(len(rows)):
                    row = rows[i]
                    values = out[i]
                    if str(row['layer']) == str(values['Layer']):
                        lay = "{map}_{layer}".format(map=row['name'],
                                                     layer=values['Layer'])
                        self.timeDataV[name][lay] = {}
                        self.timeDataV[name][lay]['start_datetime'] = row[
                            'start_time']
                        self.timeDataV[name][lay]['end_datetime'] = row[
                            'start_time']
                        self.timeDataV[name][lay]['value'] = values[
                            'Attributes'][attribute]
            else:
                wherequery = ''
                cats = self._getExistingCategories(rows[0]['name'], cats)
                totcat = len(cats)
                ncat = 1
                for cat in cats:
                    if ncat == 1 and totcat != 1:
                        wherequery += '{k}={c} or'.format(c=cat, k="{key}")
                    elif ncat == 1 and totcat == 1:
                        wherequery += '{k}={c}'.format(c=cat, k="{key}")
                    elif ncat == totcat:
                        wherequery += ' {k}={c}'.format(c=cat, k="{key}")
                    else:
                        wherequery += ' {k}={c} or'.format(c=cat, k="{key}")

                    catn = "cat{num}".format(num=cat)
                    self.plotNameListV.append("{na}+{cat}".format(na=name,
                                                                  cat=catn))
                    self.timeDataV[name][catn] = OrderedDict()
                    ncat += 1
                for row in rows:
                    lay = int(row['layer'])
                    catkey = self._parseVDbConn(row['name'], lay)
                    if not catkey:
                        GError(parent=self,
                               showTraceback=False,
                               message=_(
                                   "No connection between vector map {vmap} "
                                   "and layer {la}".format(vmap=row['name'],
                                                           la=lay)))
                        return
                    vals = grass.vector_db_select(
                        map=row['name'],
                        layer=lay,
                        where=wherequery.format(key=catkey),
                        columns=attribute)
                    layn = "lay{num}".format(num=lay)
                    for cat in cats:
                        catn = "cat{num}".format(num=cat)
                        if layn not in self.timeDataV[name][catn].keys():
                            self.timeDataV[name][catn][layn] = {}
                        self.timeDataV[name][catn][layn][
                            'start_datetime'] = row['start_time']
                        self.timeDataV[name][catn][layn]['end_datetime'] = row[
                            'end_time']
                        self.timeDataV[name][catn][layn]['value'] = vals[
                            'values'][int(cat)][0]
        self.unit = unit
        self.temporalType = mode
        return

    def _drawFigure(self):
        """Draws or print 2D plot (temporal extents)"""
        self.axes2d.clear()
        self.axes2d.grid(False)
        if self.temporalType == 'absolute':
            self.axes2d.xaxis_date()
            self.fig.autofmt_xdate()
            self.convert = mdates.date2num
            self.invconvert = mdates.num2date
        else:
            self.convert = lambda x: x
            self.invconvert = self.convert

        self.colors = cycle(COLORS)

        self.yticksNames = []
        self.yticksPos = []
        self.plots = []

        if self.datasetsR:
            self.lookUp = LookUp(self.timeDataR, self.invconvert)
        else:
            self.lookUp = LookUp(self.timeDataV, self.invconvert)

        if self.datasetsR:
            self.drawR()
        if self.datasetsV:
            if self.poi:
                self.drawV()
            elif self.cats:
                self.drawVCats()

        self.canvas.draw()
        DataCursor(self.plots, self.lookUp, InfoFormat, self.convert)

    def drawR(self):
        for i, name in enumerate(self.datasetsR):
            name = name[0]
            # just name; with mapset it would be long
            self.yticksNames.append(name)
            self.yticksPos.append(1)  # TODO
            xdata = []
            ydata = []
            for keys, values in self.timeDataR[name].iteritems():
                if keys in [
                        'temporalType', 'granularity', 'validTopology', 'unit',
                        'temporalDataType'
                ]:
                    continue
                xdata.append(self.convert(values['start_datetime']))
                ydata.append(values['value'])

            if len(ydata) == ydata.count(None):
                GError(parent=self,
                       showTraceback=False,
                       message=_("Problem getting data from raster temporal"
                                 " dataset. Empty list of values."))
                return
            self.lookUp.AddDataset(yranges=ydata,
                                   xranges=xdata,
                                   datasetName=name)
            color = self.colors.next()
            self.plots.append(
                self.axes2d.plot(xdata,
                                 ydata,
                                 marker='o',
                                 color=color,
                                 label=self.plotNameListR[i])[0])

        if self.temporalType == 'absolute':
            self.axes2d.set_xlabel(
                _("Temporal resolution: %s" %
                  self.timeDataR[name]['granularity']))
        else:
            self.axes2d.set_xlabel(_("Time [%s]") % self.unit)
        self.axes2d.set_ylabel(', '.join(self.yticksNames))

        # legend
        handles, labels = self.axes2d.get_legend_handles_labels()
        self.axes2d.legend(loc=0)

    def drawVCats(self):
        for i, name in enumerate(self.plotNameListV):
            # just name; with mapset it would be long
            labelname = name.replace('+', ' ')
            self.yticksNames.append(labelname)
            name_cat = name.split('+')
            name = name_cat[0]
            self.yticksPos.append(1)  # TODO
            xdata = []
            ydata = []
            for keys, values in self.timeDataV[name_cat[0]][
                    name_cat[1]].iteritems():
                if keys in [
                        'temporalType', 'granularity', 'validTopology', 'unit',
                        'temporalDataType'
                ]:
                    continue
                xdata.append(self.convert(values['start_datetime']))
                ydata.append(values['value'])

            if len(ydata) == ydata.count(None):
                GError(parent=self,
                       showTraceback=False,
                       message=_("Problem getting data from raster temporal"
                                 " dataset. Empty list of values."))
                return
            self.lookUp.AddDataset(yranges=ydata,
                                   xranges=xdata,
                                   datasetName=name)
            color = self.colors.next()

            self.plots.append(
                self.axes2d.plot(xdata,
                                 ydata,
                                 marker='o',
                                 color=color,
                                 label=labelname)[0])
        # ============================
        if self.temporalType == 'absolute':
            self.axes2d.set_xlabel(
                _("Temporal resolution: %s" %
                  self.timeDataV[name]['granularity']))
        else:
            self.axes2d.set_xlabel(_("Time [%s]") % self.unit)
        self.axes2d.set_ylabel(', '.join(self.yticksNames))

        # legend
        handles, labels = self.axes2d.get_legend_handles_labels()
        self.axes2d.legend(loc=0)
        self.listWhereConditions = []

    def drawV(self):
        for i, name in enumerate(self.plotNameListV):
            # just name; with mapset it would be long
            self.yticksNames.append(self.attribute.GetValue())
            self.yticksPos.append(0)  # TODO
            xdata = []
            ydata = []
            for keys, values in self.timeDataV[name].iteritems():
                if keys in [
                        'temporalType', 'granularity', 'validTopology', 'unit',
                        'temporalDataType'
                ]:
                    continue
                xdata.append(self.convert(values['start_datetime']))
                ydata.append(values['value'])

            if len(ydata) == ydata.count(None):
                GError(parent=self,
                       showTraceback=False,
                       message=_("Problem getting data from raster temporal"
                                 " dataset. Empty list of values."))
                return
            self.lookUp.AddDataset(yranges=ydata,
                                   xranges=xdata,
                                   datasetName=name)
            color = self.colors.next()

            self.plots.append(
                self.axes2d.plot(xdata,
                                 ydata,
                                 marker='o',
                                 color=color,
                                 label=name)[0])
        # ============================
        if self.temporalType == 'absolute':
            self.axes2d.set_xlabel(
                _("Temporal resolution: %s" %
                  self.timeDataV[name]['granularity']))
        else:
            self.axes2d.set_xlabel(_("Time [%s]") % self.unit)
        self.axes2d.set_ylabel(', '.join(self.yticksNames))

        # legend
        handles, labels = self.axes2d.get_legend_handles_labels()
        self.axes2d.legend(loc=0)
        self.listWhereConditions = []

    def OnRedraw(self, event=None):
        """Required redrawing."""
        self.init()
        datasetsR = self.datasetSelectR.GetValue().strip()
        datasetsV = self.datasetSelectV.GetValue().strip()

        if not datasetsR and not datasetsV:
            return

        try:
            getcoors = self.coorval.coordsField.GetValue()
        except:
            try:
                getcoors = self.coorval.GetValue()
            except:
                getcoors = None
        if getcoors and getcoors != '':
            try:
                coordx, coordy = getcoors.split(',')
                coordx, coordy = float(coordx), float(coordy)
            except (ValueError, AttributeError):
                try:
                    coordx, coordy = self.coorval.GetValue().split(',')
                    coordx, coordy = float(coordx), float(coordy)
                except (ValueError, AttributeError):
                    GMessage(message=_("Incorrect coordinates format, should "
                                       "be: x,y"),
                             parent=self)
            coors = [coordx, coordy]
            if coors:
                try:
                    self.poi = Point(float(coors[0]), float(coors[1]))
                except GException:
                    GError(parent=self,
                           message=_("Invalid input coordinates"),
                           showTraceback=False)
                    return
                if not self.poi:
                    GError(parent=self,
                           message=_("Invalid input coordinates"),
                           showTraceback=False)
                    return
                bbox = self.region.get_bbox()
                if not bbox.contains(self.poi):
                    GError(parent=self,
                           message=_("Seed point outside the "
                                     "current region"),
                           showTraceback=False)
                    return
        # check raster dataset
        if datasetsR:
            datasetsR = datasetsR.split(',')
            try:
                datasetsR = self._checkDatasets(datasetsR, 'strds')
                if not datasetsR:
                    return
            except GException:
                GError(parent=self,
                       message=_("Invalid input raster dataset"),
                       showTraceback=False)
                return
            if not self.poi:
                GError(parent=self,
                       message=_("Invalid input coordinates"),
                       showTraceback=False)
                return
            self.datasetsR = datasetsR

        # check vector dataset
        if datasetsV:
            datasetsV = datasetsV.split(',')
            try:
                datasetsV = self._checkDatasets(datasetsV, 'stvds')
                if not datasetsV:
                    return
            except GException:
                GError(parent=self,
                       message=_("Invalid input vector dataset"),
                       showTraceback=False)
                return
            self.datasetsV = datasetsV
        self._redraw()

    def _redraw(self):
        """Readraw data.

        Decides if to draw also 3D and adjusts layout if needed.
        """
        if self.datasetsR:
            self._getSTRDdata(self.datasetsR)

        if self.datasetsV:
            self._getSTVDData(self.datasetsV)

        # axes3d are physically removed
        if not self.axes2d:
            self.axes2d = self.fig.add_subplot(1, 1, 1)
        self._drawFigure()

    def _checkDatasets(self, datasets, typ):
        """Checks and validates datasets.

        Reports also type of dataset (e.g. 'strds').

        :param list datasets: list of temporal dataset's name
        :return: (mapName, mapset, type)
        """
        validated = []
        tDict = tgis.tlist_grouped(type=typ, group_type=True, dbif=self.dbif)
        # nested list with '(map, mapset, etype)' items
        allDatasets = [[[(map, mapset, etype) for map in maps]
                        for etype, maps in etypesDict.iteritems()]
                       for mapset, etypesDict in tDict.iteritems()]
        # flatten this list
        if allDatasets:
            allDatasets = reduce(lambda x, y: x + y,
                                 reduce(lambda x, y: x + y, allDatasets))
            mapsets = tgis.get_tgis_c_library_interface().available_mapsets()
            allDatasets = [
                i
                for i in sorted(allDatasets, key=lambda l: mapsets.index(l[1]))
            ]

        for dataset in datasets:
            errorMsg = _("Space time dataset <%s> not found.") % dataset
            if dataset.find("@") >= 0:
                nameShort, mapset = dataset.split('@', 1)
                indices = [
                    n for n, (mapName, mapsetName,
                              etype) in enumerate(allDatasets)
                    if nameShort == mapName and mapsetName == mapset
                ]
            else:
                indices = [
                    n for n, (mapName, mapset, etype) in enumerate(allDatasets)
                    if dataset == mapName
                ]

            if len(indices) == 0:
                raise GException(errorMsg)
            elif len(indices) >= 2:
                dlg = wx.SingleChoiceDialog(
                    self,
                    message=_("Please specify the "
                              "space time dataset "
                              "<%s>." % dataset),
                    caption=_("Ambiguous dataset name"),
                    choices=[("%(map)s@%(mapset)s:"
                              " %(etype)s" % {
                                  'map': allDatasets[i][0],
                                  'mapset': allDatasets[i][1],
                                  'etype': allDatasets[i][2]
                              }) for i in indices],
                    style=wx.CHOICEDLG_STYLE | wx.OK)
                if dlg.ShowModal() == wx.ID_OK:
                    index = dlg.GetSelection()
                    validated.append(allDatasets[indices[index]])
                else:
                    continue
            else:
                validated.append(allDatasets[indices[0]])

        return validated

    def OnHelp(self, event):
        """Function to show help"""
        RunCommand(prog='g.manual', quiet=True, entry='g.gui.tplot')

    def SetDatasets(self, rasters, vectors, coors, cats, attr):
        """Set the data
        #TODO
        :param list rasters: a list of temporal raster dataset's name
        :param list vectors: a list of temporal vector dataset's name
        :param list coors: a list with x/y coordinates
        :param list cats: a list with incld. categories of vector
        :param str attr:  name of atribute of vectror data
        """
        if not (rasters or vectors) or not (coors or cats):
            return
        try:
            if rasters:
                self.datasetsR = self._checkDatasets(rasters, 'strds')
            if vectors:
                self.datasetsV = self._checkDatasets(vectors, 'stvds')
            if not (self.datasetsR or self.datasetsV):
                return
        except GException:
            GError(parent=self,
                   message=_("Invalid input temporal dataset"),
                   showTraceback=False)
            return
        if coors:
            try:
                self.poi = Point(float(coors[0]), float(coors[1]))
            except GException:
                GError(parent=self,
                       message=_("Invalid input coordinates"),
                       showTraceback=False)
                return
            try:
                self.coorval.coordsField.SetValue(','.join(coors))
            except:
                self.coorval.SetValue(','.join(coors))
        if self.datasetsV:
            vdatas = ','.join(map(lambda x: x[0] + '@' + x[1], self.datasetsV))
            self.datasetSelectV.SetValue(vdatas)
            if attr:
                self.attribute.SetValue(attr)
            if cats:
                self.cats.SetValue(cats)
        if self.datasetsR:
            self.datasetSelectR.SetValue(','.join(
                map(lambda x: x[0] + '@' + x[1], self.datasetsR)))
        self._redraw()

    def OnVectorSelected(self, event):
        """Update the controlbox related to stvds"""
        dataset = self.datasetSelectV.GetValue().strip()
        name = dataset.split('@')[0]
        mapset = dataset.split('@')[1] if len(dataset.split('@')) > 1 else ''
        found = False
        for each in tgis.tlist(type='stvds', dbif=self.dbif):
            each_name, each_mapset = each.split('@')
            if name == each_name:
                if mapset and mapset != each_mapset:
                    continue
                dataset = name + '@' + each_mapset
                found = True
                break
        if found:
            try:
                vect_list = grass.read_command('t.vect.list',
                                               flags='u',
                                               input=dataset,
                                               column='name')
            except Exception:
                self.attribute.Clear()
                GError(parent=self,
                       message=_("Invalid input temporal dataset"),
                       showTraceback=False)
                return
            vect_list = list(set(sorted(vect_list.split())))
            for vec in vect_list:
                self.attribute.InsertColumns(vec, 1)
        else:
            self.attribute.Clear()
Пример #5
0
class WSPanel(wx.Panel):

    def __init__(self, parent, web_service, **kwargs):
        """Show data from capabilities file.

        Signal: capParsed - this signal is emitted when capabilities file is downloaded
                            (after ConnectToServer method was called)

        :param parent:  parent widget
        :param web_service:  web service to be panel generated for
        """
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

        self.parent = parent
        self.ws = web_service

        self.capParsed = Signal('WSPanel.capParsed')

        # stores widgets, which represents parameters/flags of d.wms
        self.params = {}
        self.flags = {}

        self.o_layer_name = ''

        # stores err output from r.in.wms during getting capabilities
        self.cmd_err_str = ''

        # stores selected layer from layer list
        self.sel_layers = []

        # downloaded and parsed data from server successfully?
        self.is_connected = False

        # common part of command for r.in.wms -c and d.wms
        self.ws_cmdl = None

        # provides information about driver parameters
        self.drv_info = WMSDriversInfo()
        self.drv_props = self.drv_info.GetDrvProperties(self.ws)

        self.ws_drvs = {
            'WMS_1.1.1': {
                'cmd': [
                    'wms_version=1.1.1',
                    'driver=WMS_GRASS'],
                'cap_parser': lambda temp_file: WMSCapabilities(
                    temp_file,
                    '1.1.1'),
            },
            'WMS_1.3.0': {
                'cmd': [
                    'wms_version=1.3.0',
                    'driver=WMS_GRASS'],
                'cap_parser': lambda temp_file: WMSCapabilities(
                    temp_file,
                    '1.3.0'),
            },
            'WMTS': {
                'cmd': ['driver=WMTS_GRASS'],
                'cap_parser': WMTSCapabilities,
            },
            'OnEarth': {
                'cmd': ['driver=OnEarth_GRASS'],
                'cap_parser': OnEarthCapabilities,
            }}

        self.cmdStdErr = GStderr(self)
        self.cmd_thread = CmdThread(self)
        self.cap_file = grass.tempfile()

        reqDataBox = StaticBox(
            parent=self, label=_(" Requested data settings "))
        self._nb_sizer = wx.StaticBoxSizer(reqDataBox, wx.VERTICAL)
        self.notebook = GNotebook(
            parent=self,
            style=FN.FNB_FANCY_TABS | FN.FNB_NO_X_BUTTON | FN.FNB_NODRAG)

        self._requestPage()
        self._advancedSettsPage()

        self._layout()

        self.layerSelected = self.list.layerSelected

        self.Bind(EVT_CMD_DONE, self.OnCapDownloadDone)
        self.Bind(EVT_CMD_OUTPUT, self.OnCmdOutput)

        self.SetMinSize((-1, 300))

    def __del__(self):
        self.cmd_thread.abort(abortall=True)
        grass.try_remove(self.cap_file)

    def _layout(self):
        self._nb_sizer.Add(self.notebook, proportion=1, flag=wx.EXPAND)
        self.SetSizer(self._nb_sizer)

    def _requestPage(self):
        """Create request page"""
        self.req_page_panel = wx.Panel(parent=self, id=wx.ID_ANY)
        self.notebook.AddPage(page=self.req_page_panel,
                              text=_('Request'),
                              name='request')

        # list of layers
        self.layersBox = StaticBox(parent=self.req_page_panel, id=wx.ID_ANY,
                                   label=_("List of layers "))

        style = wx.TR_DEFAULT_STYLE | wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT
        if self.drv_props['req_multiple_layers']:
            style = style | wx.TR_MULTIPLE
        if 'WMS' not in self.ws:
            style = style | wx.TR_HIDE_ROOT

        self.list = LayersList(parent=self.req_page_panel,
                               web_service=self.ws,
                               style=style)

        self.params['format'] = None

        self.params['srs'] = None
        if 'srs' not in self.drv_props['ignored_params']:
            projText = StaticText(
                parent=self.req_page_panel, id=wx.ID_ANY,
                label=_("Source projection:"))
            self.params['srs'] = wx.Choice(
                parent=self.req_page_panel, id=wx.ID_ANY)

        self.list.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnListSelChanged)

        # layout
        self.req_page_sizer = wx.BoxSizer(wx.VERTICAL)

        layersSizer = wx.StaticBoxSizer(self.layersBox, wx.HORIZONTAL)

        layersSizer.Add(
            self.list,
            proportion=1,
            flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
            border=5)

        self.req_page_sizer.Add(
            layersSizer,
            proportion=1,
            flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
            border=5)

        self.source_sizer = wx.BoxSizer(wx.HORIZONTAL)

        if self.params['format'] is not None:
            self.source_sizer.Add(
                self.params['format'],
                flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                border=5)

        if self.params['srs'] is not None:
            self.source_sizer.Add(
                projText,
                flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                border=5)
            self.source_sizer.Add(
                self.params['srs'],
                flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP | wx.BOTTOM,
                border=5)

        self.req_page_sizer.Add(
            self.source_sizer,
            flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
            border=5)

        self.req_page_panel.SetSizer(self.req_page_sizer)

    def enableButtons(self, enable=True):
        """Enable/disable up, down, buttons
        """
        self.btnUp.Enable(enable)
        self.btnDown.Enable(enable)

    def _advancedSettsPage(self):
        """Create advanced settings page
        """
        # TODO parse maxcol, maxrow, settings from d.wms module?
        # TODO OnEarth driver - add selection of time
        adv_setts_panel = ScrolledPanel(parent=self, id=wx.ID_ANY,
                                        style=wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER)
        self.notebook.AddPage(page=adv_setts_panel,
                              text=_('Advanced request settings'),
                              name='adv_req_setts')

        labels = {}
        self.l_odrder_list = None
        if 'WMS' in self.ws:
            labels['l_order'] = StaticBox(
                parent=adv_setts_panel, id=wx.ID_ANY,
                label=_("Order of layers in raster"))
            self.l_odrder_list = wx.ListBox(
                adv_setts_panel, id=wx.ID_ANY, choices=[],
                style=wx.LB_SINGLE | wx.LB_NEEDED_SB)
            self.btnUp = Button(
                adv_setts_panel, id=wx.ID_ANY, label=_("Up"))
            self.btnDown = Button(
                adv_setts_panel, id=wx.ID_ANY, label=_("Down"))

            self.btnUp.Bind(wx.EVT_BUTTON, self.OnUp)
            self.btnDown.Bind(wx.EVT_BUTTON, self.OnDown)

        labels['method'] = StaticText(parent=adv_setts_panel, id=wx.ID_ANY,
                                      label=_("Reprojection method:"))

        self.reproj_methods = ['nearest', 'linear', 'cubic', 'cubicspline']
        self.params['method'] = wx.Choice(
            parent=adv_setts_panel,
            id=wx.ID_ANY,
            choices=[
                _('Nearest neighbor'),
                _('Linear interpolation'),
                _('Cubic interpolation'),
                _('Cubic spline interpolation')])

        labels['maxcols'] = StaticText(
            parent=adv_setts_panel, id=wx.ID_ANY,
            label=_("Maximum columns to request from server at time:"))
        self.params['maxcols'] = SpinCtrl(
            parent=adv_setts_panel, id=wx.ID_ANY, size=(100, -1))

        labels['maxrows'] = StaticText(
            parent=adv_setts_panel, id=wx.ID_ANY,
            label=_("Maximum rows to request from server at time:"))
        self.params['maxrows'] = SpinCtrl(
            parent=adv_setts_panel, id=wx.ID_ANY, size=(100, -1))

        min = 100
        max = 10000
        self.params['maxcols'].SetRange(min, max)
        self.params['maxrows'].SetRange(min, max)

        val = 500
        self.params['maxcols'].SetValue(val)
        self.params['maxrows'].SetValue(val)

        self.flags['o'] = self.params['bgcolor'] = None
        if 'o' not in self.drv_props['ignored_flags']:
            self.flags['o'] = wx.CheckBox(
                parent=adv_setts_panel, id=wx.ID_ANY,
                label=_("Do not request transparent data"))

            self.flags['o'].Bind(wx.EVT_CHECKBOX, self.OnTransparent)
            labels['bgcolor'] = StaticText(
                parent=adv_setts_panel, id=wx.ID_ANY,
                label=_("Background color:"))
            self.params['bgcolor'] = csel.ColourSelect(
                parent=adv_setts_panel, id=wx.ID_ANY, colour=(
                    255, 255, 255), size=globalvar.DIALOG_COLOR_SIZE)
            self.params['bgcolor'].Enable(False)

        self.params['urlparams'] = None
        if self.params['urlparams'] not in self.drv_props['ignored_params']:
            labels['urlparams'] = StaticText(
                parent=adv_setts_panel, id=wx.ID_ANY,
                label=_("Additional query parameters for server:"))
            self.params['urlparams'] = TextCtrl(
                parent=adv_setts_panel, id=wx.ID_ANY)

        # layout

        border = wx.BoxSizer(wx.VERTICAL)

        if 'WMS' in self.ws:

            boxSizer = wx.StaticBoxSizer(labels['l_order'], wx.VERTICAL)
            gridSizer = wx.GridBagSizer(hgap=3, vgap=3)

            gridSizer.Add(self.l_odrder_list,
                          pos=(0, 0),
                          span=(4, 1),
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
                          border=0)

            gridSizer.Add(self.btnUp,
                          pos=(0, 1),
                          flag=wx.ALIGN_CENTER_VERTICAL,
                          border=0)

            gridSizer.Add(self.btnDown,
                          pos=(1, 1),
                          flag=wx.ALIGN_CENTER_VERTICAL,
                          border=0)

            gridSizer.AddGrowableCol(0)
            boxSizer.Add(gridSizer,
                         flag=wx.EXPAND | wx.ALL,
                         border=5)

            border.Add(boxSizer,
                       flag=wx.LEFT | wx.RIGHT | wx.UP | wx.EXPAND,
                       border=5)

        gridSizer = wx.GridBagSizer(hgap=3, vgap=3)

        row = 0
        for k in ['method', 'maxcols', 'maxrows', 'o', 'bgcolor']:

            if k in self.params:
                param = self.params[k]
            elif k in self.flags:
                param = self.flags[k]

            if param is None:
                continue

            if k in labels or k == 'o':
                if k != 'o':
                    label = labels[k]
                else:
                    label = param

                gridSizer.Add(label,
                              flag=wx.ALIGN_LEFT |
                              wx.ALIGN_CENTER_VERTICAL,
                              pos=(row, 0))

            if k != 'o':
                gridSizer.Add(param,
                              flag=wx.ALIGN_RIGHT |
                              wx.ALIGN_CENTER_VERTICAL,
                              pos=(row, 1))
            row += 1

        gridSizer.AddGrowableCol(0)
        border.Add(gridSizer,
                   flag=wx.LEFT | wx.RIGHT | wx.TOP | wx.EXPAND,
                   border=5)

        if self.params['urlparams']:
            gridSizer = wx.GridBagSizer(hgap=3, vgap=3)

            row = 0
            gridSizer.Add(labels['urlparams'],
                          flag=wx.ALIGN_LEFT |
                          wx.ALIGN_CENTER_VERTICAL,
                          pos=(row, 0))

            gridSizer.Add(self.params['urlparams'],
                          flag=wx.ALIGN_RIGHT |
                          wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
                          pos=(row, 1))

            gridSizer.AddGrowableCol(1)

            border.Add(gridSizer,
                       flag=wx.LEFT | wx.RIGHT | wx.TOP | wx.EXPAND,
                       border=5)

        adv_setts_panel.SetSizer(border)
        adv_setts_panel.SetAutoLayout(True)
        adv_setts_panel.SetupScrolling()

    def OnUp(self, event):
        """Move selected layer up
        """
        if self.l_odrder_list.GetSelections():
            pos = self.l_odrder_list.GetSelection()
            if pos:
                self.sel_layers.insert(pos - 1, self.sel_layers.pop(pos))
            if pos > 0:
                self._updateLayerOrderList(selected=(pos - 1))
            else:
                self._updateLayerOrderList(selected=0)

    def OnDown(self, event):
        """Move selected to down
        """
        if self.l_odrder_list.GetSelections():
            pos = self.l_odrder_list.GetSelection()
            if pos != len(self.sel_layers) - 1:
                self.sel_layers.insert(pos + 1, self.sel_layers.pop(pos))
            if pos < len(self.sel_layers) - 1:
                self._updateLayerOrderList(selected=(pos + 1))
            else:
                self._updateLayerOrderList(selected=len(self.sel_layers) - 1)

    def _updateLayerOrderList(self, selected=None):
        """Update order in list.
        """
        def getlayercaption(l):
            if l['title']:
                cap = (l['title'])
            else:
                cap = (l['name'])

            if l['style']:
                if l['style']['title']:
                    cap += ' / ' + l['style']['title']
                else:
                    cap += ' / ' + l['style']['name']
            return cap

        layer_capts = [getlayercaption(l) for l in self.sel_layers]
        self.l_odrder_list.Set(layer_capts)
        if self.l_odrder_list.IsEmpty():
            self.enableButtons(False)
        else:
            self.enableButtons(True)
            if selected is not None:
                self.l_odrder_list.SetSelection(selected)
                self.l_odrder_list.EnsureVisible(selected)

    def OnTransparent(self, event):
        checked = event.IsChecked()
        if checked:
            self.params['bgcolor'].Enable(True)
        else:
            self.params['bgcolor'].Enable(False)

    def ConnectToServer(self, url, username, password):
        """Download and parse data from capabilities file.

        :param url: server url
        :type url: str
        :param username: username for connection
        :type username: str
        :param password: password for connection
        :type password: str
        """
        self._prepareForNewConn(url, username, password)
        cap_cmd = [
            'r.in.wms',
            '-c',
            ('capfile_output=%s' % self.cap_file),
            '--overwrite'] + self.ws_cmdl

        self.currentPid = self.cmd_thread.GetId()
        self.cmd_thread.RunCmd(cap_cmd, stderr=self.cmdStdErr)

    def OnCmdOutput(self, event):
        """Manage cmd output.
        """
        if Debug.GetLevel() != 0:
            Debug.msg(1, event.text)
        elif event.type != 'message' and event.type != 'warning':
            self.cmd_err_str += event.text + os.linesep

    def _prepareForNewConn(self, url, username, password):
        """Prepare panel for new connection
        """
        self.is_connected = False

        self.sel_layers = []
        self.formats_list = []
        self.projs_list = []

        self.conn = {
            'url': url,
            'password': password,
            'username': username
        }

        conn_cmd = []
        for k, v in six.iteritems(self.conn):
            if v:
                conn_cmd.append("%s=%s" % (k, v))

        self.ws_cmdl = self.ws_drvs[self.ws]['cmd'] + conn_cmd

    def OnCapDownloadDone(self, event):
        """Process donwloaded capabilities file and emits capParsed
        signal (see class constructor).
        """
        if event.pid != self.currentPid:
            return

        if event.returncode != 0:
            if self.cmd_err_str:
                self.cmd_err_str = _(
                    "Unable to download %s capabilities file\nfrom <%s>:\n" %
                    (self.ws.replace('_', ' '),
                     self.conn['url'])) + self.cmd_err_str
            self._postCapParsedEvt(error_msg=self.cmd_err_str)
            self.cmd_err_str = ''
            return

        self._parseCapFile(self.cap_file)

    def _parseCapFile(self, cap_file):
        """Parse capabilities data and emits capParsed signal
        (see class constructor).
        """
        try:
            self.cap = self.ws_drvs[self.ws]['cap_parser'](cap_file)
        except (IOError, ParseError) as error:
            error_msg = _(
                "%s web service was not found in fetched capabilities file from <%s>:\n%s\n" %
                (self.ws, self.conn['url'], str(error)))
            if Debug.GetLevel() != 0:
                Debug.msg(1, error_msg)
                self._postCapParsedEvt(None)
            else:
                self._postCapParsedEvt(error_msg=error_msg)
            return

        self.is_connected = True

        # WMS standard has formats defined for all layers
        if 'WMS' in self.ws:
            self.formats_list = sorted(self._getFormats())
            self._updateFormatRadioBox(self.formats_list)
            self._setDefaultFormatVal()

        self.list.LoadData(self.cap)
        self.OnListSelChanged(event=None)

        self._postCapParsedEvt(None)

    def ParseCapFile(self, url, username, password, cap_file=None,):
        """Parse capabilities data and emits capParsed signal
        (see class constructor).
        """
        self._prepareForNewConn(url, username, password)

        if cap_file is None or not url:
            self._postCapParsedEvt(None)
            return

        shutil.copyfile(cap_file, self.cap_file)

        self._parseCapFile(self.cap_file)

    def UpdateWidgetsByCmd(self, cmd):
        """Update panel widgets accordnig to passed cmd tuple

        :param cmd: cmd in tuple
        """

        dcmd = cmd[1]

        layers = []

        if 'layers' in dcmd:
            layers = dcmd['layers']

        styles = []
        if 'styles' in dcmd:
            styles = dcmd['styles']

        if 'WMS' in self.ws:
            layers = layers.split(',')
            styles = styles.split(',')
        else:
            layers = [layers]
            styles = [styles]

        if len(layers) != len(styles):
            styles = [''] * len(layers)

        l_st_list = []
        for i in range(len(layers)):
            l_st_list.append({'style': styles[i],
                              'layer': layers[i]})

        # WMS standard - first layer in params is most bottom...
        # therefore layers order need to be reversed
        l_st_list = [l for l in reversed(l_st_list)]
        self.list.SelectLayers(l_st_list)

        params = {}
        if 'format' in dcmd:
            params['format'] = dcmd['format']
        if 'srs' in dcmd:
            params['srs'] = 'EPSG:' + dcmd['srs']
        if 'method' in dcmd:
            params['method'] = dcmd['method']

        for p, v in six.iteritems(params):
            if self.params[p]:
                self.params[p].SetStringSelection(v)

        for p, conv_f in [
                ('urlparams', None),
                ('maxcols', int),
                ('maxrows', int)]:
            if p in dcmd:
                v = dcmd[p]
                if conv_f:
                    v = conv_f(v)
                self.params[p].SetValue(v)

        if 'flags' in dcmd and \
           'o' in dcmd['flags']:
            self.flags['o'].SetValue(1)
            self.params['bgcolor'].Enable(True)

        if 'bgcolor' in dcmd and \
           self.params['bgcolor']:
            bgcolor = dcmd['bgcolor'].strip().lower()
            if len(bgcolor) == 8 and \
               '0x' == bgcolor[:2]:

                colour = '#' + bgcolor[2:]
                self.params['bgcolor'].SetColour(colour)

    def IsConnected(self):
        """Was successful in downloading and parsing capabilities data?
        """
        return self.is_connected

    def _postCapParsedEvt(self, error_msg):
        """Helper function
        """
        self.capParsed.emit(error_msg=error_msg)

    def CreateCmd(self):
        """Create d.wms cmd from values of panels widgets

        :return: cmd list
        :return: None if required widgets do not have selected/filled values.
        """

        # check required widgets
        if not self._checkImportValues():
            return None

        # create d.wms command
        lcmd = self.ws_cmdl
        lcmd = ['d.wms'] + lcmd

        layers = "layers="
        styles = 'styles='
        first = True

        # WMS standard - first layer in params is most bottom...
        # therefore layers order need to be reversed
        for layer in reversed(self.sel_layers):
            if not first:
                layers += ','
                styles += ','
            first = False
            layers += layer['name']
            if layer['style'] is not None:
                styles += layer['style']['name']

        lcmd.append(layers)
        lcmd.append(styles)

        if 'format' not in self.drv_props['ignored_params']:
            i_format = self.params['format'].GetSelection()
            lcmd.append("format=%s" % self.formats_list[i_format])

        if 'srs' not in self.drv_props['ignored_params']:
            i_srs = self.params['srs'].GetSelection()
            srs = self.projs_list[i_srs].split(':')[-1]
            epsg_num = int(''.join(re.findall(r'\d+', srs)))

            lcmd.append("srs=%s" % epsg_num)

        for k in ['maxcols', 'maxrows', 'urlparams']:
            lcmd.append(k + '=' + str(self.params[k].GetValue()))

        i_method = self.params['method'].GetSelection()
        lcmd.append('method=' + self.reproj_methods[i_method])

        if 'o' not in self.drv_props['ignored_flags'] and \
                self.flags['o'].IsChecked():
            lcmd.append('-o')

            c = self.params['bgcolor'].GetColour()
            hex_color = wx.Colour(
                c[0],
                c[1],
                c[2]).GetAsString(
                wx.C2S_HTML_SYNTAX)
            lcmd.append("bgcolor=" + '0x' + hex_color[1:])

        lcmd.append("map=" + self.o_layer_name)

        return lcmd

    def OnListSelChanged(self, event):
        """Update widgets according to selected layer in list.
        """
        curr_sel_ls = self.list.GetSelectedLayers()
        # update self.sel_layers (selected layer list)
        if 'WMS' in self.ws:
            for sel_l in self.sel_layers[:]:
                if sel_l not in curr_sel_ls:
                    self.sel_layers.remove(sel_l)

            for l in curr_sel_ls:
                if l not in self.sel_layers:
                    self.sel_layers.append(l)

            self._updateLayerOrderList()
        else:
            self.sel_layers = curr_sel_ls

        # update projection

        self.projs_list = []
        projs_list = []

        intersect_proj = []
        first = True
        for l in curr_sel_ls:
            layer_projs = l['cap_intf_l'].GetLayerData('srs')
            if first:
                projs_list = layer_projs
                first = False
                continue

            projs_list = set(projs_list).intersection(layer_projs)

        if 'srs' not in self.drv_props['ignored_params']:

            for proj in projs_list:
                proj_code = Srs(proj.strip()).getcode()
                proj_spl = proj_code.split(':')
                if proj_spl[0].strip().lower() in self.drv_info.GetSrs():
                    # accept ogc:crs code
                    self.projs_list.append(proj_code)

            cur_sel = self.params['srs'].GetStringSelection()

            self.projs_list = sorted(self.projs_list)
            self.params['srs'].SetItems(self.projs_list)

            if cur_sel:
                self.params['srs'].SetStringSelection(cur_sel)
            else:
                try:
                    i = self.projs_list.index('EPSG:4326')
                    self.params['srs'].SetSelection(i)
                except ValueError:
                    if len(self.projs_list) > 0:
                        self.params['srs'].SetSelection(0)

        # update format

        if 'WMS' not in self.ws and \
           'format' not in self.drv_props['ignored_params']:
            self.formats_list = []
            cur_sel = None

            if self.params['format']:
                cur_sel = self.params['format'].GetStringSelection()

            if len(curr_sel_ls) > 0:
                self.formats_list = sorted(
                    self._getFormats(
                        curr_sel_ls[0]['cap_intf_l']))
                self._updateFormatRadioBox(self.formats_list)

                if cur_sel:
                    if self.params['format']:
                        self.params['format'].SetStringSelection(cur_sel)
                else:
                    self._setDefaultFormatVal()

        self.Layout()

    def _setDefaultFormatVal(self):
        """Set default format value.
        """
        try:
            i = self.formats_list.index('png')
            self.params['format'].SetSelection(i)
        except ValueError:
            pass

    def _updateFormatRadioBox(self, formats_list):
        """Helper function
        """
        if self.params['format']:
            self.req_page_sizer.Detach(self.params['format'])
            self.params['format'].Destroy()
        if len(self.formats_list) > 0:
            self.params['format'] = wx.RadioBox(
                parent=self.req_page_panel,
                id=wx.ID_ANY,
                label=_("Source image format"),
                pos=wx.DefaultPosition,
                choices=formats_list,
                majorDimension=4,
                style=wx.RA_SPECIFY_COLS)
            self.source_sizer.Insert(2, window=self.params['format'],
                                     flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                                     border=5)

    def _getFormats(self, layer=None):
        """Get formats

        WMS has formats defined generally for whole cap.
        In WMTS and NASA OnEarh formats are defined for layer.
        """
        formats_label = []
        if layer is None:
            formats_list = self.cap.GetFormats()
        else:
            formats_list = layer.GetLayerData('format')

        for frmt in formats_list:
            frmt = frmt.strip()
            label = self.drv_info.GetFormatLabel(frmt)

            if label:
                formats_label.append(label)

        return formats_label

    def _checkImportValues(self,):
        """Check if required widgets are selected/filled
        """
        warning_str = ""
        show_war = False
        if not self.list or not self.list.GetSelectedLayers():
            warning_str += _("Select layer in layer list.\n")
            show_war = True

        if self.params['format'] is not None and \
           self.params['format'].GetSelection() == -1:
            warning_str += _("Select source image format.\n")
            show_war = True

        if self.params['srs'] is not None and \
           self.params['srs'].GetSelection() == -1:
            warning_str += _("Select source projection.\n")
            show_war = True

        if not self.o_layer_name:
            warning_str += _("Choose output layer name.\n")
            show_war = True

        if show_war:
            GMessage(parent=self.parent, message=warning_str)
            return False

        return True

    def SetOutputLayerName(self, name):
        """Set name of layer to be added to layer tree
        """
        self.o_layer_name = name

    def GetOutputLayerName(self):
        return self.o_layer_name

    def GetCapFile(self):
        """Get path to file where capabilities are saved
        """
        return self.cap_file

    def GetWebService(self):
        """Get web service
        """
        return self.ws
Пример #6
0
    def __init__(self,
                 parent,
                 giface,
                 itype,
                 id=wx.ID_ANY,
                 title=_("Multiple import"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        self.parent = parent  # GMFrame
        self._giface = giface  # used to add layers
        self.importType = itype
        self.options = dict()  # list of options
        self.options_par = dict()

        self.commandId = -1  # id of running command

        wx.Dialog.__init__(self,
                           parent,
                           id,
                           title,
                           style=style,
                           name="MultiImportDialog")

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        self.layerBox = StaticBox(parent=self.panel, id=wx.ID_ANY)
        if self.importType == 'gdal':
            label = _("List of raster layers")
        elif self.importType == 'ogr':
            label = _("List of vector layers")
        else:
            label = _("List of %s layers") % self.importType.upper()
        self.layerBox.SetLabel(" %s - %s " %
                               (label, _("right click to (un)select all")))

        # list of layers
        columns = [
            _('Layer id'),
            _('Layer name'),
            _('Name for output GRASS map (editable)')
        ]
        if itype == 'ogr':
            columns.insert(2, _('Feature type'))
            columns.insert(3, _('Projection match'))
        elif itype == 'gdal':
            columns.insert(2, _('Projection match'))

        self.list = LayersList(parent=self.panel, columns=columns)
        self.list.LoadData()

        self.override = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_(
                "Override projection check (use current location's projection)"
            ))

        self.overwrite = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_("Allow output files to overwrite existing files"))
        self.overwrite.SetValue(
            UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
        self.overwrite.Bind(wx.EVT_CHECKBOX, self.OnCheckOverwrite)
        if UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'):
            self.list.validate = False

        self.add = wx.CheckBox(parent=self.panel, id=wx.ID_ANY)
        self.closeOnFinish = wx.CheckBox(parent=self.panel,
                                         id=wx.ID_ANY,
                                         label=_("Close dialog on finish"))
        self.closeOnFinish.SetValue(
            UserSettings.Get(group='cmd', key='closeDlg', subkey='enabled'))

        #
        # buttons
        #
        # cancel
        self.btn_close = CloseButton(parent=self.panel)
        self.btn_close.SetToolTip(_("Close dialog"))
        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        # run
        self.btn_run = Button(parent=self.panel,
                              id=wx.ID_OK,
                              label=_("&Import"))
        self.btn_run.SetToolTip(_("Import selected layers"))
        self.btn_run.SetDefault()
        self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun)

        self.Bind(wx.EVT_CLOSE, lambda evt: self.Destroy())

        self.notebook = GNotebook(parent=self, style=globalvar.FNPageDStyle)

        self.notebook.AddPage(page=self.panel,
                              text=_('Source settings'),
                              name='source')

        self.createSettingsPage()
Пример #7
0
    def _layout(self):
        """Creates the main panel with all the controls on it:
             * mpl canvas
             * mpl navigation toolbar
             * Control panel for interaction
        """
        self.mainPanel = wx.Panel(self)
        # Create the mpl Figure and FigCanvas objects.
        # 5x4 inches, 100 dots-per-inch
        #
        # color =  wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
        # ------------CANVAS AND TOOLBAR------------
        self.fig = Figure((5.0, 4.0), facecolor=(1, 1, 1))
        self.canvas = FigCanvas(self.mainPanel, wx.ID_ANY, self.fig)
        # axes are initialized later
        self.axes2d = None
        self.axes3d = None

        # Create the navigation toolbar, tied to the canvas
        #
        self.toolbar = NavigationToolbar(self.canvas)

        #
        # Layout
        #
        # ------------MAIN VERTICAL SIZER------------
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.EXPAND)
        self.vbox.Add(self.toolbar, 0, wx.EXPAND)
        # self.vbox.AddSpacer(10)

        # ------------ADD NOTEBOOK------------
        self.ntb = GNotebook(parent=self.mainPanel, style=FN.FNB_FANCY_TABS)

        # ------------ITEMS IN NOTEBOOK PAGE (RASTER)------------------------

        self.controlPanelRaster = wx.Panel(parent=self.ntb, id=wx.ID_ANY)
        self.datasetSelectLabelR = wx.StaticText(
            parent=self.controlPanelRaster,
            id=wx.ID_ANY,
            label=_('Raster temporal '
                    'dataset (strds)'))

        self.datasetSelectR = gselect.Select(
            parent=self.controlPanelRaster,
            id=wx.ID_ANY,
            size=globalvar.DIALOG_GSELECT_SIZE,
            type='strds',
            multiple=True)
        self.coor = wx.StaticText(parent=self.controlPanelRaster,
                                  id=wx.ID_ANY,
                                  label=_('X and Y coordinates separated by '
                                          'comma:'))
        try:
            self._giface.GetMapWindow()
            self.coorval = gselect.CoordinatesSelect(
                parent=self.controlPanelRaster, giface=self._giface)
        except:
            self.coorval = wx.TextCtrl(parent=self.controlPanelRaster,
                                       id=wx.ID_ANY,
                                       size=globalvar.DIALOG_TEXTCTRL_SIZE,
                                       validator=CoordinatesValidator())

        self.coorval.SetToolTipString(
            _("Coordinates can be obtained for example"
              " by right-clicking on Map Display."))
        self.controlPanelSizerRaster = wx.BoxSizer(wx.VERTICAL)
        # self.controlPanelSizer.Add(wx.StaticText(self.panel, id=wx.ID_ANY,
        # label=_("Select space time raster dataset(s):")),
        # pos=(0, 0), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        self.controlPanelSizerRaster.Add(self.datasetSelectLabelR,
                                         flag=wx.EXPAND)
        self.controlPanelSizerRaster.Add(self.datasetSelectR, flag=wx.EXPAND)

        self.controlPanelSizerRaster.Add(self.coor, flag=wx.EXPAND)
        self.controlPanelSizerRaster.Add(self.coorval, flag=wx.EXPAND)

        self.controlPanelRaster.SetSizer(self.controlPanelSizerRaster)
        self.controlPanelSizerRaster.Fit(self)
        self.ntb.AddPage(page=self.controlPanelRaster,
                         text=_('STRDS'),
                         name='STRDS')

        # ------------ITEMS IN NOTEBOOK PAGE (VECTOR)------------------------
        self.controlPanelVector = wx.Panel(parent=self.ntb, id=wx.ID_ANY)
        self.datasetSelectLabelV = wx.StaticText(
            parent=self.controlPanelVector,
            id=wx.ID_ANY,
            label=_('Vector temporal '
                    'dataset (stvds)\n'
                    'Press ENTER if you'
                    ' type the name of the'
                    ' stvds instead of'
                    ' selecting with the'
                    ' combobox'))
        self.datasetSelectV = gselect.Select(
            parent=self.controlPanelVector,
            id=wx.ID_ANY,
            size=globalvar.DIALOG_GSELECT_SIZE,
            type='stvds',
            multiple=True)
        self.datasetSelectV.Bind(wx.EVT_TEXT, self.OnVectorSelected)

        self.attribute = gselect.ColumnSelect(parent=self.controlPanelVector)
        self.attributeLabel = wx.StaticText(parent=self.controlPanelVector,
                                            id=wx.ID_ANY,
                                            label=_('Select attribute column'))
        # TODO fix the category selection as done for coordinates
        try:
            self._giface.GetMapWindow()
            self.cats = gselect.VectorCategorySelect(
                parent=self.controlPanelVector, giface=self._giface)
        except:
            self.cats = wx.TextCtrl(parent=self.controlPanelVector,
                                    id=wx.ID_ANY,
                                    size=globalvar.DIALOG_TEXTCTRL_SIZE)
        self.catsLabel = wx.StaticText(parent=self.controlPanelVector,
                                       id=wx.ID_ANY,
                                       label=_('Select category of vector(s)'))

        self.controlPanelSizerVector = wx.BoxSizer(wx.VERTICAL)
        # self.controlPanelSizer.Add(wx.StaticText(self.panel, id=wx.ID_ANY,
        # label=_("Select space time raster dataset(s):")),
        # pos=(0, 0), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        self.controlPanelSizerVector.Add(self.datasetSelectLabelV,
                                         flag=wx.EXPAND)
        self.controlPanelSizerVector.Add(self.datasetSelectV, flag=wx.EXPAND)

        self.controlPanelSizerVector.Add(self.attributeLabel, flag=wx.EXPAND)
        self.controlPanelSizerVector.Add(self.attribute, flag=wx.EXPAND)

        self.controlPanelSizerVector.Add(self.catsLabel, flag=wx.EXPAND)
        self.controlPanelSizerVector.Add(self.cats, flag=wx.EXPAND)

        self.controlPanelVector.SetSizer(self.controlPanelSizerVector)
        self.controlPanelSizerVector.Fit(self)
        self.ntb.AddPage(page=self.controlPanelVector,
                         text=_('STVDS'),
                         name='STVDS')

        # ------------Buttons on the bottom(draw,help)------------
        self.vButtPanel = wx.Panel(self.mainPanel, id=wx.ID_ANY)
        self.vButtSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.drawButton = wx.Button(self.vButtPanel,
                                    id=wx.ID_ANY,
                                    label=_("Draw"))
        self.drawButton.Bind(wx.EVT_BUTTON, self.OnRedraw)
        self.helpButton = wx.Button(self.vButtPanel,
                                    id=wx.ID_ANY,
                                    label=_("Help"))
        self.helpButton.Bind(wx.EVT_BUTTON, self.OnHelp)
        self.vButtSizer.Add(self.drawButton)
        self.vButtSizer.Add(self.helpButton)
        self.vButtPanel.SetSizer(self.vButtSizer)

        self.mainPanel.SetSizer(self.vbox)
        self.vbox.Add(self.ntb, flag=wx.EXPAND)
        self.vbox.Add(self.vButtPanel, flag=wx.EXPAND)
        self.vbox.Fit(self)
        self.mainPanel.Fit()
Пример #8
0
class ImportDialog(wx.Dialog):
    """Dialog for bulk import of various data (base class)"""
    def __init__(self,
                 parent,
                 giface,
                 itype,
                 id=wx.ID_ANY,
                 title=_("Multiple import"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        self.parent = parent  # GMFrame
        self._giface = giface  # used to add layers
        self.importType = itype
        self.options = dict()  # list of options
        self.options_par = dict()

        self.commandId = -1  # id of running command

        wx.Dialog.__init__(self,
                           parent,
                           id,
                           title,
                           style=style,
                           name="MultiImportDialog")

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        self.layerBox = StaticBox(parent=self.panel, id=wx.ID_ANY)
        if self.importType == 'gdal':
            label = _("List of raster layers")
        elif self.importType == 'ogr':
            label = _("List of vector layers")
        else:
            label = _("List of %s layers") % self.importType.upper()
        self.layerBox.SetLabel(" %s - %s " %
                               (label, _("right click to (un)select all")))

        # list of layers
        columns = [
            _('Layer id'),
            _('Layer name'),
            _('Name for output GRASS map (editable)')
        ]
        if itype == 'ogr':
            columns.insert(2, _('Feature type'))
            columns.insert(3, _('Projection match'))
        elif itype == 'gdal':
            columns.insert(2, _('Projection match'))

        self.list = LayersList(parent=self.panel, columns=columns)
        self.list.LoadData()

        self.override = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_(
                "Override projection check (use current location's projection)"
            ))

        self.overwrite = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_("Allow output files to overwrite existing files"))
        self.overwrite.SetValue(
            UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
        self.overwrite.Bind(wx.EVT_CHECKBOX, self.OnCheckOverwrite)
        if UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'):
            self.list.validate = False

        self.add = wx.CheckBox(parent=self.panel, id=wx.ID_ANY)
        self.closeOnFinish = wx.CheckBox(parent=self.panel,
                                         id=wx.ID_ANY,
                                         label=_("Close dialog on finish"))
        self.closeOnFinish.SetValue(
            UserSettings.Get(group='cmd', key='closeDlg', subkey='enabled'))

        #
        # buttons
        #
        # cancel
        self.btn_close = CloseButton(parent=self.panel)
        self.btn_close.SetToolTip(_("Close dialog"))
        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        # run
        self.btn_run = Button(parent=self.panel,
                              id=wx.ID_OK,
                              label=_("&Import"))
        self.btn_run.SetToolTip(_("Import selected layers"))
        self.btn_run.SetDefault()
        self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun)

        self.Bind(wx.EVT_CLOSE, lambda evt: self.Destroy())

        self.notebook = GNotebook(parent=self, style=globalvar.FNPageDStyle)

        self.notebook.AddPage(page=self.panel,
                              text=_('Source settings'),
                              name='source')

        self.createSettingsPage()

    def createSettingsPage(self):

        self._blackList = {
            'enabled': True,
            'items': {
                self._getCommand(): {
                    'params': self._getBlackListedParameters(),
                    'flags': self._getBlackListedFlags()
                }
            }
        }

        grass_task = gtask.parse_interface(self._getCommand(),
                                           blackList=self._blackList)

        self.advancedPagePanel = CmdPanel(parent=self,
                                          giface=None,
                                          task=grass_task,
                                          frame=None)

        self.notebook.AddPage(page=self.advancedPagePanel,
                              text=_('Import settings'),
                              name='settings')

    def doLayout(self):
        """Do layout"""
        dialogSizer = wx.BoxSizer(wx.VERTICAL)

        # dsn input
        dialogSizer.Add(self.dsnInput, proportion=0, flag=wx.EXPAND)

        #
        # list of DXF layers
        #
        layerSizer = wx.StaticBoxSizer(self.layerBox, wx.HORIZONTAL)

        layerSizer.Add(self.list,
                       proportion=1,
                       flag=wx.ALL | wx.EXPAND,
                       border=5)

        dialogSizer.Add(layerSizer,
                        proportion=1,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                        border=5)

        dialogSizer.Add(self.override,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)

        dialogSizer.Add(self.overwrite,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)

        dialogSizer.Add(self.add,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)

        dialogSizer.Add(self.closeOnFinish,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)
        #
        # buttons
        #
        btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL)

        btnsizer.Add(self.btn_close,
                     proportion=0,
                     flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)

        btnsizer.Add(self.btn_run,
                     proportion=0,
                     flag=wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)

        dialogSizer.Add(btnsizer,
                        proportion=0,
                        flag=wx.BOTTOM | wx.ALIGN_RIGHT,
                        border=10)

        # dialogSizer.SetSizeHints(self.panel)
        self.panel.SetAutoLayout(True)
        self.panel.SetSizer(dialogSizer)
        dialogSizer.Fit(self.panel)

        # auto-layout seems not work here - FIXME
        size = wx.Size(globalvar.DIALOG_GSELECT_SIZE[0] + 322, 550)
        self.SetMinSize(size)
        self.SetSize((size.width, size.height + 100))
        # width = self.GetSize()[0]
        # self.list.SetColumnWidth(col = 1, width = width / 2 - 50)
        self.Layout()

    def _getCommand(self):
        """Get command"""
        raise NotImplementedError()

    def _getBlackListedParameters(self):
        """Get parameters which will not be showed in Settings page"""
        raise NotImplementedError()

    def _getBlackListedFlags(self):
        """Get flags which will not be showed in Settings page"""
        raise NotImplementedError()

    def _nameValidationFailed(self, layers_list):
        """Output map name validation callback

        :param layers_list: LayersList class instance
        """
        if isinstance(layers_list.output_map, list):
            maps = ['<{}>'.format(m) for m in layers_list.output_map]
            message = _("Output map names %(names)s exist. ") % {
                'names': ', '.join(maps)
            }
        else:
            message = _("Output map name <%(name)s> exist. ") % {
                'name': layers_list.output_map
            }
        GError(parent=self, message=message, caption=_("Invalid name"))

    def _validateOutputMapName(self):
        """Enable/disable output map name validation according the
        overwrite state"""
        if not self.overwrite.IsChecked():
            if not self.list.GetValidator().\
               Validate(win=self.list, validate_all=True):
                return False
        return True

    def OnClose(self, event=None):
        """Close dialog"""
        self.Close()

    def OnRun(self, event):
        """Import/Link data (each layes as separate vector map)"""
        pass

    def OnCheckOverwrite(self, event):
        """Check/uncheck overwrite checkbox widget"""
        if self.overwrite.IsChecked():
            self.list.validate = False
        else:
            self.list.validate = True

    def AddLayers(self, returncode, cmd=None, userData=None):
        """Add imported/linked layers into layer tree"""
        if not self.add.IsChecked() or returncode != 0:
            return

        # TODO: if importing map creates more map the following does not work
        # * do nothing if map does not exist or
        # * try to determine names using regexp or
        # * persuade import tools to report map names
        self.commandId += 1
        layer, output = self.list.GetLayers()[self.commandId][:2]

        if '@' not in output:
            name = output + '@' + grass.gisenv()['MAPSET']
        else:
            name = output

        # add imported layers into layer tree
        # an alternative would be emit signal (mapCreated) and (optionally)
        # connect to this signal
        llist = self._giface.GetLayerList()
        if self.importType == 'gdal':
            if userData:
                nBands = int(userData.get('nbands', 1))
            else:
                nBands = 1

            if UserSettings.Get(group='rasterLayer',
                                key='opaque',
                                subkey='enabled'):
                nFlag = True
            else:
                nFlag = False

            for i in range(1, nBands + 1):
                nameOrig = name
                if nBands > 1:
                    mapName, mapsetName = name.split('@')
                    mapName += '.%d' % i
                    name = mapName + '@' + mapsetName

                cmd = ['d.rast', 'map=%s' % name]
                if nFlag:
                    cmd.append('-n')

                llist.AddLayer(ltype='raster',
                               name=name,
                               checked=True,
                               cmd=cmd)
                name = nameOrig
        else:
            llist.AddLayer(ltype='vector',
                           name=name,
                           checked=True,
                           cmd=['d.vect', 'map=%s' % name] +
                           GetDisplayVectSettings())

        self._giface.GetMapWindow().ZoomToMap()

    def OnAbort(self, event):
        """Abort running import

        .. todo::
            not yet implemented
        """
        pass

    def OnCmdDone(self, event):
        """Do what has to be done after importing"""
        pass

    def _getLayersToReprojetion(self, projMatch_idx, grassName_idx):
        """If there are layers with different projection from loation projection,
           show dialog to user to explicitly select layers which will be reprojected..."""
        differentProjLayers = []
        data = self.list.GetData(checked=True)

        for itm in data:

            layerId = itm[-1]

            # select only layers with different projetion
            if self.layersData[layerId][projMatch_idx] == 0:
                dt = [itm[0], itm[grassName_idx]]
                differentProjLayers.append(tuple(dt))

        layers = self.list.GetLayers()

        if not self.link and \
           differentProjLayers and \
           not self.override.IsChecked(): # '-o' not in self.getSettingsPageCmd():

            dlg = ReprojectionDialog(parent=self,
                                     giface=self._giface,
                                     data=differentProjLayers)

            ret = dlg.ShowModal()

            if ret == wx.ID_OK:

                # do not import unchecked layers
                for itm in reversed(list(dlg.GetData(checked=False))):
                    idx = itm[-1]
                    layers.pop(idx)
            else:
                return None

        return layers

    def getSettingsPageCmd(self):

        return self.advancedPagePanel.createCmd(ignoreErrors=True,
                                                ignoreRequired=True)
Пример #9
0
    def __init__(self,
                 parent,
                 giface,
                 itype,
                 id=wx.ID_ANY,
                 title=_("Multiple import"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        self.parent = parent  # GMFrame
        self._giface = giface  # used to add layers
        self.importType = itype
        self.options = dict()  # list of options
        self.options_par = dict()

        self.commandId = -1  # id of running command

        wx.Dialog.__init__(self,
                           parent,
                           id,
                           title,
                           style=style,
                           name="MultiImportDialog")

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        self.layerBox = StaticBox(parent=self.panel, id=wx.ID_ANY)
        if self.importType == 'gdal':
            label = _("List of raster layers")
        elif self.importType == 'ogr':
            label = _("List of vector layers")
        else:
            label = _("List of %s layers") % self.importType.upper()
        self.layerBox.SetLabel(" %s - %s " %
                               (label, _("right click to (un)select all")))

        # list of layers
        columns = [
            _('Layer id'),
            _('Layer name'),
            _('Name for output GRASS map (editable)')
        ]
        if itype == 'ogr':
            columns.insert(2, _('Feature type'))
            columns.insert(3, _('Projection match'))
        elif itype == 'gdal':
            columns.insert(2, _('Projection match'))

        self.list = LayersList(parent=self.panel, columns=columns)
        self.list.LoadData()

        self.override = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_(
                "Override projection check (use current location's projection)"
            ))

        self.overwrite = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_("Allow output files to overwrite existing files"))
        self.overwrite.SetValue(
            UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))

        self.add = wx.CheckBox(parent=self.panel, id=wx.ID_ANY)
        self.closeOnFinish = wx.CheckBox(parent=self.panel,
                                         id=wx.ID_ANY,
                                         label=_("Close dialog on finish"))
        self.closeOnFinish.SetValue(
            UserSettings.Get(group='cmd', key='closeDlg', subkey='enabled'))

        #
        # buttons
        #
        # cancel
        self.btn_close = Button(parent=self.panel, id=wx.ID_CLOSE)
        self.btn_close.SetToolTip(_("Close dialog"))
        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        # run
        self.btn_run = Button(parent=self.panel,
                              id=wx.ID_OK,
                              label=_("&Import"))
        self.btn_run.SetToolTip(_("Import selected layers"))
        self.btn_run.SetDefault()
        self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun)

        self.Bind(wx.EVT_CLOSE, lambda evt: self.Destroy())

        self.notebook = GNotebook(parent=self,
                                  style=FN.FNB_FANCY_TABS | FN.FNB_BOTTOM
                                  | FN.FNB_NO_X_BUTTON)

        self.notebook.AddPage(page=self.panel,
                              text=_('Source settings'),
                              name='source')

        self.createSettingsPage()

        # Enable copying to clipboard with cmd+c from dialog on macOS
        # (default key binding will close the dialog), trac #3592
        if sys.platform == "darwin":
            self.Bind(wx.EVT_MENU, self.OnCopyToClipboard, id=wx.ID_COPY)
            self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord("C"),
                                                   wx.ID_COPY)])
            self.SetAcceleratorTable(self.accel_tbl)
Пример #10
0
    def __init__(self, parent, Rinstance, controller, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)

        self.parent = parent
        self.border = 4

        #    1. Input data
        InputBoxSizer = wx.StaticBoxSizer(
            wx.StaticBox(self, id=wx.ID_ANY, label=_("Input Data")),
            orient=wx.HORIZONTAL,
        )

        flexSizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5)
        flexSizer.AddGrowableCol(1)

        flexSizer.Add(
            wx.StaticText(self, id=wx.ID_ANY, label=_("Point dataset:")),
            flag=wx.ALIGN_CENTER_VERTICAL,
        )
        self.InputDataMap = gselect.VectorSelect(parent=self,
                                                 ftype="points",
                                                 updateOnPopup=False)
        self.InputDataMap.SetFocus()
        flexSizer.Add(self.InputDataMap, flag=wx.ALIGN_CENTER_VERTICAL)

        RefreshButton = wx.Button(self, id=wx.ID_REFRESH)
        RefreshButton.Bind(wx.EVT_BUTTON, self.OnButtonRefresh)
        flexSizer.Add(RefreshButton, flag=wx.ALIGN_CENTER_VERTICAL)

        flexSizer.Add(
            wx.StaticText(self, id=wx.ID_ANY, label=_("Numeric column:")),
            flag=wx.ALIGN_CENTER_VERTICAL,
        )
        self.InputDataColumn = gselect.ColumnSelect(self, id=wx.ID_ANY)
        flexSizer.Add(self.InputDataColumn)

        self.InputDataMap.GetChildren()[0].Bind(wx.EVT_TEXT,
                                                self.OnInputMapChanged)
        self.InputDataColumn.GetChildren()[0].Bind(wx.EVT_TEXT,
                                                   self.OnInputColumnChanged)

        InputBoxSizer.Add(flexSizer)

        # 2. Kriging. In book pages one for each R package. Includes variogram
        # fit.
        KrigingSizer = wx.StaticBoxSizer(
            wx.StaticBox(self, id=wx.ID_ANY, label=_("Kriging")),
            wx.HORIZONTAL)

        self.RPackagesBook = GNotebook(parent=self,
                                       style=globalvar.FNPageDStyle)

        # , "geoR"]: #@TODO: enable it if/when it'll be implemented.
        for Rpackage in ["gstat"]:
            self.CreatePage(package=Rpackage,
                            Rinstance=Rinstance,
                            controller=controller)

        # Command output. From menuform module, cmdPanel class
        self._gconsole = gconsole.GConsole(guiparent=self)
        self.goutput = goutput.GConsoleWindow(parent=self,
                                              gconsole=self._gconsole,
                                              margin=False)
        self.goutputId = self.RPackagesBook.GetPageCount()
        self.outpage = self.RPackagesBook.AddPage(page=self.goutput,
                                                  text=_("Command output"),
                                                  name="output")
        self._gconsole.Bind(
            gconsole.EVT_CMD_RUN,
            lambda event: self._switchPageHandler(
                event=event, notification=Notification.MAKE_VISIBLE),
        )
        self._gconsole.Bind(
            gconsole.EVT_CMD_DONE,
            lambda event: self._switchPageHandler(
                event=event, notification=Notification.RAISE_WINDOW),
        )
        self.RPackagesBook.SetSelection(0)
        KrigingSizer.Add(self.RPackagesBook, proportion=1, flag=wx.EXPAND)

        #    3. Output Parameters.
        OutputSizer = wx.StaticBoxSizer(
            wx.StaticBox(self, id=wx.ID_ANY, label=_("Output")), wx.HORIZONTAL)

        OutputParameters = wx.GridBagSizer(hgap=5, vgap=5)
        OutputParameters.Add(
            wx.StaticText(self,
                          id=wx.ID_ANY,
                          label=_("Name for the output raster map:")),
            flag=wx.ALIGN_CENTER_VERTICAL,
            pos=(0, 0),
        )
        self.OutputMapName = gselect.Select(parent=self,
                                            id=wx.ID_ANY,
                                            type="raster",
                                            mapsets=[grass.gisenv()["MAPSET"]])
        OutputParameters.Add(self.OutputMapName,
                             flag=wx.EXPAND | wx.ALL,
                             pos=(0, 1))
        self.VarianceRasterCheckbox = wx.CheckBox(
            self, id=wx.ID_ANY, label=_("Export variance map as well: "))
        self.VarianceRasterCheckbox.SetValue(state=True)
        OutputParameters.Add(self.VarianceRasterCheckbox,
                             flag=wx.ALIGN_CENTER_VERTICAL,
                             pos=(1, 0))
        self.OutputVarianceMapName = gselect.Select(
            parent=self,
            id=wx.ID_ANY,
            type="raster",
            mapsets=[grass.gisenv()["MAPSET"]])
        self.VarianceRasterCheckbox.Bind(wx.EVT_CHECKBOX,
                                         self.OnVarianceCBChecked)
        OutputParameters.Add(self.OutputVarianceMapName,
                             flag=wx.EXPAND | wx.ALL,
                             pos=(1, 1))

        self.OverwriteCheckBox = wx.CheckBox(
            self,
            id=wx.ID_ANY,
            label=_("Allow output files to overwrite existing files"),
        )
        self.OverwriteCheckBox.SetValue(
            UserSettings.Get(group="cmd", key="overwrite", subkey="enabled"))
        OutputParameters.Add(self.OverwriteCheckBox, pos=(2, 0), span=(1, 2))

        OutputParameters.AddGrowableCol(1)
        OutputSizer.Add(OutputParameters,
                        proportion=0,
                        flag=wx.EXPAND | wx.ALL,
                        border=self.border)

        #    4. Run Button and Quit Button
        ButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
        HelpButton = wx.Button(self, id=wx.ID_HELP)
        HelpButton.Bind(wx.EVT_BUTTON, self.OnHelpButton)
        QuitButton = wx.Button(self, id=wx.ID_EXIT)
        QuitButton.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
        # no stock ID for Run button..
        self.RunButton = wx.Button(self, id=wx.ID_ANY, label=_("&Run"))
        self.RunButton.Bind(wx.EVT_BUTTON, self.OnRunButton)
        # disable it on loading the interface, as input map is not set
        self.RunButton.Enable(False)
        ButtonSizer.Add(HelpButton,
                        proportion=0,
                        flag=wx.ALIGN_LEFT | wx.ALL,
                        border=self.border)
        ButtonSizer.Add(QuitButton,
                        proportion=0,
                        flag=wx.ALIGN_RIGHT | wx.ALL,
                        border=self.border)
        ButtonSizer.Add(
            self.RunButton,
            proportion=0,
            flag=wx.ALIGN_RIGHT | wx.ALL,
            border=self.border,
        )

        #    Main Sizer. Add each child sizer as soon as it is ready.
        Sizer = wx.BoxSizer(wx.VERTICAL)
        Sizer.Add(InputBoxSizer,
                  proportion=0,
                  flag=wx.EXPAND | wx.ALL,
                  border=self.border)
        Sizer.Add(KrigingSizer,
                  proportion=1,
                  flag=wx.EXPAND | wx.ALL,
                  border=self.border)
        Sizer.Add(OutputSizer,
                  proportion=0,
                  flag=wx.EXPAND | wx.ALL,
                  border=self.border)
        Sizer.Add(ButtonSizer,
                  proportion=0,
                  flag=wx.ALIGN_RIGHT | wx.ALL,
                  border=self.border)
        self.SetSizerAndFit(Sizer)

        # last action of __init__: update imput data list.
        # it's performed in the few seconds gap while user examines interface before clicking anything.
        # @TODO: implement a splashcreen IF the maps cause a noticeable lag [markus' suggestion]
        self.InputDataMap.GetElementList()
Пример #11
0
class KrigingPanel(wx.Panel):
    """Main panel. Contains all widgets except Menus and Statusbar."""
    def __init__(self, parent, Rinstance, controller, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)

        self.parent = parent
        self.border = 4

        #    1. Input data
        InputBoxSizer = wx.StaticBoxSizer(
            wx.StaticBox(self, id=wx.ID_ANY, label=_("Input Data")),
            orient=wx.HORIZONTAL,
        )

        flexSizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5)
        flexSizer.AddGrowableCol(1)

        flexSizer.Add(
            wx.StaticText(self, id=wx.ID_ANY, label=_("Point dataset:")),
            flag=wx.ALIGN_CENTER_VERTICAL,
        )
        self.InputDataMap = gselect.VectorSelect(parent=self,
                                                 ftype="points",
                                                 updateOnPopup=False)
        self.InputDataMap.SetFocus()
        flexSizer.Add(self.InputDataMap, flag=wx.ALIGN_CENTER_VERTICAL)

        RefreshButton = wx.Button(self, id=wx.ID_REFRESH)
        RefreshButton.Bind(wx.EVT_BUTTON, self.OnButtonRefresh)
        flexSizer.Add(RefreshButton, flag=wx.ALIGN_CENTER_VERTICAL)

        flexSizer.Add(
            wx.StaticText(self, id=wx.ID_ANY, label=_("Numeric column:")),
            flag=wx.ALIGN_CENTER_VERTICAL,
        )
        self.InputDataColumn = gselect.ColumnSelect(self, id=wx.ID_ANY)
        flexSizer.Add(self.InputDataColumn)

        self.InputDataMap.GetChildren()[0].Bind(wx.EVT_TEXT,
                                                self.OnInputMapChanged)
        self.InputDataColumn.GetChildren()[0].Bind(wx.EVT_TEXT,
                                                   self.OnInputColumnChanged)

        InputBoxSizer.Add(flexSizer)

        # 2. Kriging. In book pages one for each R package. Includes variogram
        # fit.
        KrigingSizer = wx.StaticBoxSizer(
            wx.StaticBox(self, id=wx.ID_ANY, label=_("Kriging")),
            wx.HORIZONTAL)

        self.RPackagesBook = GNotebook(parent=self,
                                       style=globalvar.FNPageDStyle)

        # , "geoR"]: #@TODO: enable it if/when it'll be implemented.
        for Rpackage in ["gstat"]:
            self.CreatePage(package=Rpackage,
                            Rinstance=Rinstance,
                            controller=controller)

        # Command output. From menuform module, cmdPanel class
        self._gconsole = gconsole.GConsole(guiparent=self)
        self.goutput = goutput.GConsoleWindow(parent=self,
                                              gconsole=self._gconsole,
                                              margin=False)
        self.goutputId = self.RPackagesBook.GetPageCount()
        self.outpage = self.RPackagesBook.AddPage(page=self.goutput,
                                                  text=_("Command output"),
                                                  name="output")
        self._gconsole.Bind(
            gconsole.EVT_CMD_RUN,
            lambda event: self._switchPageHandler(
                event=event, notification=Notification.MAKE_VISIBLE),
        )
        self._gconsole.Bind(
            gconsole.EVT_CMD_DONE,
            lambda event: self._switchPageHandler(
                event=event, notification=Notification.RAISE_WINDOW),
        )
        self.RPackagesBook.SetSelection(0)
        KrigingSizer.Add(self.RPackagesBook, proportion=1, flag=wx.EXPAND)

        #    3. Output Parameters.
        OutputSizer = wx.StaticBoxSizer(
            wx.StaticBox(self, id=wx.ID_ANY, label=_("Output")), wx.HORIZONTAL)

        OutputParameters = wx.GridBagSizer(hgap=5, vgap=5)
        OutputParameters.Add(
            wx.StaticText(self,
                          id=wx.ID_ANY,
                          label=_("Name for the output raster map:")),
            flag=wx.ALIGN_CENTER_VERTICAL,
            pos=(0, 0),
        )
        self.OutputMapName = gselect.Select(parent=self,
                                            id=wx.ID_ANY,
                                            type="raster",
                                            mapsets=[grass.gisenv()["MAPSET"]])
        OutputParameters.Add(self.OutputMapName,
                             flag=wx.EXPAND | wx.ALL,
                             pos=(0, 1))
        self.VarianceRasterCheckbox = wx.CheckBox(
            self, id=wx.ID_ANY, label=_("Export variance map as well: "))
        self.VarianceRasterCheckbox.SetValue(state=True)
        OutputParameters.Add(self.VarianceRasterCheckbox,
                             flag=wx.ALIGN_CENTER_VERTICAL,
                             pos=(1, 0))
        self.OutputVarianceMapName = gselect.Select(
            parent=self,
            id=wx.ID_ANY,
            type="raster",
            mapsets=[grass.gisenv()["MAPSET"]])
        self.VarianceRasterCheckbox.Bind(wx.EVT_CHECKBOX,
                                         self.OnVarianceCBChecked)
        OutputParameters.Add(self.OutputVarianceMapName,
                             flag=wx.EXPAND | wx.ALL,
                             pos=(1, 1))

        self.OverwriteCheckBox = wx.CheckBox(
            self,
            id=wx.ID_ANY,
            label=_("Allow output files to overwrite existing files"),
        )
        self.OverwriteCheckBox.SetValue(
            UserSettings.Get(group="cmd", key="overwrite", subkey="enabled"))
        OutputParameters.Add(self.OverwriteCheckBox, pos=(2, 0), span=(1, 2))

        OutputParameters.AddGrowableCol(1)
        OutputSizer.Add(OutputParameters,
                        proportion=0,
                        flag=wx.EXPAND | wx.ALL,
                        border=self.border)

        #    4. Run Button and Quit Button
        ButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
        HelpButton = wx.Button(self, id=wx.ID_HELP)
        HelpButton.Bind(wx.EVT_BUTTON, self.OnHelpButton)
        QuitButton = wx.Button(self, id=wx.ID_EXIT)
        QuitButton.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
        # no stock ID for Run button..
        self.RunButton = wx.Button(self, id=wx.ID_ANY, label=_("&Run"))
        self.RunButton.Bind(wx.EVT_BUTTON, self.OnRunButton)
        # disable it on loading the interface, as input map is not set
        self.RunButton.Enable(False)
        ButtonSizer.Add(HelpButton,
                        proportion=0,
                        flag=wx.ALIGN_LEFT | wx.ALL,
                        border=self.border)
        ButtonSizer.Add(QuitButton,
                        proportion=0,
                        flag=wx.ALIGN_RIGHT | wx.ALL,
                        border=self.border)
        ButtonSizer.Add(
            self.RunButton,
            proportion=0,
            flag=wx.ALIGN_RIGHT | wx.ALL,
            border=self.border,
        )

        #    Main Sizer. Add each child sizer as soon as it is ready.
        Sizer = wx.BoxSizer(wx.VERTICAL)
        Sizer.Add(InputBoxSizer,
                  proportion=0,
                  flag=wx.EXPAND | wx.ALL,
                  border=self.border)
        Sizer.Add(KrigingSizer,
                  proportion=1,
                  flag=wx.EXPAND | wx.ALL,
                  border=self.border)
        Sizer.Add(OutputSizer,
                  proportion=0,
                  flag=wx.EXPAND | wx.ALL,
                  border=self.border)
        Sizer.Add(ButtonSizer,
                  proportion=0,
                  flag=wx.ALIGN_RIGHT | wx.ALL,
                  border=self.border)
        self.SetSizerAndFit(Sizer)

        # last action of __init__: update imput data list.
        # it's performed in the few seconds gap while user examines interface before clicking anything.
        # @TODO: implement a splashcreen IF the maps cause a noticeable lag [markus' suggestion]
        self.InputDataMap.GetElementList()

    def CreatePage(self, package, Rinstance, controller):
        """Creates the three notebook pages, one for each R package"""
        for package in [
                "gstat"
        ]:  # @TODO add here other packages when they will be implemented
            classobj = eval("RBook" + package + "Panel")
            setattr(
                self,
                "RBook" + package + "Panel",
                (classobj(self,
                          id=wx.ID_ANY,
                          Rinstance=Rinstance,
                          controller=controller)),
            )
            self.RPackagesBook.AddPage(page=getattr(
                self, "RBook" + package + "Panel"),
                                       text=package)

    def OnButtonRefresh(self, event):
        """Forces refresh of list of available layers."""
        self.InputDataMap.GetElementList()

    def OnCloseWindow(self, event):
        """Cancel button pressed"""
        self.parent.Close()
        event.Skip()

    def OnHelpButton(self, event):
        grass.run_command("g.manual", entry="v.krige")
        event.Skip()

    def OnInputMapChanged(self, event):
        """Refreshes list of columns."""
        MapName = event.GetString()
        self.InputDataColumn.InsertColumns(
            vector=MapName,
            layer=1,
            excludeKey=False,
            type=["integer", "double precision"],
        )

    def OnInputColumnChanged(self, event):
        """Fills output map name TextCtrl"""
        MapName = self.InputDataMap.GetValue()
        enable = bool(self.InputDataColumn.GetValue())
        self.RunButton.Enable(enable)
        self.RBookgstatPanel.PlotButton.Enable(enable)

        if enable:
            self.OutputMapName.SetValue(MapName.split("@")[0] + "_kriging")
            self.OutputVarianceMapName.SetValue(
                MapName.split("@")[0] + "_kriging.var")
        else:
            self.OutputMapName.SetValue("")
            self.OutputVarianceMapName.SetValue("")

    def OnRunButton(self, event):
        """Execute R analysis."""
        # @FIXME: send data to main method instead of running it here.

        # -1: get the selected notebook page. The user shall know that [s]he can modify settings in all
        # pages, but only the selected one will be executed when Run is
        # pressed.
        SelectedPanel = self.RPackagesBook.GetCurrentPage()

        if (self.RPackagesBook.GetPageText(
                self.RPackagesBook.GetSelection()) == "Command output"):
            self._gconsole.WriteError(
                'No parameters for running. Please select "gstat" tab, check parameters and re-run.'
            )
            return False  # no break invoked by above function

        # mount command string as it would have been written on CLI
        command = [
            "v.krige",
            "input=" + self.InputDataMap.GetValue(),
            "column=" + self.InputDataColumn.GetValue(),
            "output=" + self.OutputMapName.GetValue(),
            "package=" + "%s" %
            self.RPackagesBook.GetPageText(self.RPackagesBook.GetSelection()),
        ]

        if (not hasattr(SelectedPanel, "VariogramCheckBox")
                or not SelectedPanel.VariogramCheckBox.IsChecked()):
            command.append("model=" + "%s" % SelectedPanel.ModelChoicebox.
                           GetStringSelection().split(" ")[0])

        for i in ["Psill", "Nugget", "Range", "Kappa"]:
            if getattr(SelectedPanel, i + "ChextBox").IsChecked():
                command.append(i.lower() + "=" + "%s" %
                               getattr(SelectedPanel, i + "Ctrl").GetValue())

        if SelectedPanel.KrigingRadioBox.GetStringSelection(
        ) == "Block kriging":
            command.append("block=" +
                           "%s" % SelectedPanel.BlockSpinBox.GetValue())
        if self.OverwriteCheckBox.IsChecked():
            command.append("--overwrite")
        if self.VarianceRasterCheckbox.IsChecked():
            command.append("output_var=" +
                           self.OutputVarianceMapName.GetValue())

        # give it to the output console
        # @FIXME: it runs the command as a NEW instance. Reimports data, recalculates variogram fit..
        # otherwise I can use Controller() and mimic RunCmd behaviour.
        self._gconsole.RunCmd(command)

    def OnVarianceCBChecked(self, event):
        self.OutputVarianceMapName.Enable(event.IsChecked())

    def _switchPageHandler(self, event, notification):
        self._switchPage(notification=notification)
        event.Skip()

    def _switchPage(self, notification):
        """Manages @c 'output' notebook page according to event notification."""
        if notification == Notification.HIGHLIGHT:
            self.RPackagesBook.HighlightPageByName("output")
        if notification == Notification.MAKE_VISIBLE:
            self.RPackagesBook.SetSelectionByName("output")
        if notification == Notification.RAISE_WINDOW:
            self.RPackagesBook.SetSelectionByName("output")
            self.SetFocus()
            self.Raise()
Пример #12
0
    def __init__(self,
                 parent,
                 size=(650, 460),
                 title=_('About GRASS GIS'),
                 **kwargs):
        wx.Frame.__init__(self,
                          parent=parent,
                          id=wx.ID_ANY,
                          title=title,
                          size=size,
                          **kwargs)

        panel = wx.Panel(parent=self, id=wx.ID_ANY)

        # icon
        self.SetIcon(
            wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'),
                    wx.BITMAP_TYPE_ICO))

        # get version and web site
        vInfo = grass.version()

        infoTxt = ScrolledPanel(parent=panel)
        infoTxt.SetupScrolling()
        infoSizer = wx.BoxSizer(wx.VERTICAL)
        infoGridSizer = wx.GridBagSizer(vgap=5, hgap=5)
        logo = os.path.join(globalvar.ETCDIR, "gui", "icons",
                            "grass-64x64.png")
        logoBitmap = wx.StaticBitmap(parent=infoTxt,
                                     id=wx.ID_ANY,
                                     bitmap=wx.Bitmap(name=logo,
                                                      type=wx.BITMAP_TYPE_PNG))
        infoSizer.Add(item=logoBitmap,
                      proportion=0,
                      flag=wx.ALL | wx.ALIGN_CENTER,
                      border=20)

        info = wx.StaticText(parent=infoTxt,
                             id=wx.ID_ANY,
                             label='GRASS GIS ' + vInfo['version'] + '\n\n')
        info.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        info.SetForegroundColour(wx.Colour(35, 142, 35))
        infoSizer.Add(item=info,
                      proportion=0,
                      flag=wx.BOTTOM | wx.ALIGN_CENTER,
                      border=1)

        row = 0
        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label=_('Official GRASS site:')),
                          pos=(row, 0),
                          flag=wx.ALIGN_RIGHT)

        infoGridSizer.Add(item=HyperLinkCtrl(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label='http://grass.osgeo.org'),
                          pos=(row, 1),
                          flag=wx.ALIGN_LEFT)

        row += 2
        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label='%s:' % _('SVN Revision')),
                          pos=(row, 0),
                          flag=wx.ALIGN_RIGHT)

        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label=vInfo['revision']),
                          pos=(row, 1),
                          flag=wx.ALIGN_LEFT)

        row += 1
        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label='%s:' %
                                             _('GIS Library Revision')),
                          pos=(row, 0),
                          flag=wx.ALIGN_RIGHT)

        infoGridSizer.Add(
            item=wx.StaticText(parent=infoTxt,
                               id=wx.ID_ANY,
                               label=vInfo['libgis_revision'] + ' (' +
                               vInfo['libgis_date'].split(' ')[0] + ')'),
            pos=(row, 1),
            flag=wx.ALIGN_LEFT)

        row += 2
        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label='Python:'),
                          pos=(row, 0),
                          flag=wx.ALIGN_RIGHT)

        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label=platform.python_version()),
                          pos=(row, 1),
                          flag=wx.ALIGN_LEFT)

        row += 1
        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label='wxPython:'),
                          pos=(row, 0),
                          flag=wx.ALIGN_RIGHT)

        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label=wx.__version__),
                          pos=(row, 1),
                          flag=wx.ALIGN_LEFT)
        infoGridSizer.AddGrowableCol(0)
        infoGridSizer.AddGrowableCol(1)

        infoSizer.Add(item=infoGridSizer,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALIGN_CENTER
                      | wx.ALIGN_CENTER_VERTICAL)

        row += 2
        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label="%s:" % _('Language')),
                          pos=(row, 0),
                          flag=wx.ALIGN_RIGHT)
        lang = grass.gisenv().get('LANG', None)
        if not lang:
            import locale
            loc = locale.getdefaultlocale()
            if loc == (None, None):
                lang = _('unknown')
            else:
                lang = u'%s.%s' % (loc[0], loc[1])
        infoGridSizer.Add(item=wx.StaticText(parent=infoTxt,
                                             id=wx.ID_ANY,
                                             label=lang),
                          pos=(row, 1),
                          flag=wx.ALIGN_LEFT)

        # create a flat notebook for displaying information about GRASS
        aboutNotebook = GNotebook(panel,
                                  style=globalvar.FNPageStyle
                                  | FN.FNB_NO_X_BUTTON)
        aboutNotebook.SetTabAreaColour(globalvar.FNPageColor)

        for title, win in ((_("Info"), infoTxt), (_("Copyright"),
                                                  self._pageCopyright()),
                           (_("License"), self._pageLicense()),
                           (_("Authors"),
                            self._pageCredit()), (_("Contributors"),
                                                  self._pageContributors()),
                           (_("Extra contributors"),
                            self._pageContributors(extra=True)),
                           (_("Translators"), self._pageTranslators())):
            aboutNotebook.AddPage(page=win, text=title)
        wx.CallAfter(aboutNotebook.SetSelection, 0)

        # buttons
        btnClose = wx.Button(parent=panel, id=wx.ID_CLOSE)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(item=btnClose,
                     proportion=0,
                     flag=wx.ALL | wx.ALIGN_RIGHT,
                     border=5)
        # bindings
        btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)

        infoTxt.SetSizer(infoSizer)
        infoSizer.Fit(infoTxt)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(item=aboutNotebook,
                  proportion=1,
                  flag=wx.EXPAND | wx.ALL,
                  border=1)
        sizer.Add(item=btnSizer,
                  proportion=0,
                  flag=wx.ALL | wx.ALIGN_RIGHT,
                  border=1)
        panel.SetSizer(sizer)

        self.Layout()
        self.SetMinSize((400, 400))