예제 #1
0
파일: widgets.py 프로젝트: caomw/grass
 def __init__(self, **kwargs):
     Debug.msg(1, "FloatSlider.__init__()")
     wx.Slider.__init__(self, **kwargs)
     self.coef = 1.
     #init range
     self.minValueOrig = 0
     self.maxValueOrig = 1
예제 #2
0
파일: datacatalog.py 프로젝트: caomw/grass
 def OnEditLabel(self, event):
     """End label editing"""
     if (self.selected_layer):
         item = event.GetItem()
         self.old_name = self.GetItemText(item)
         Debug.msg(1, "End label edit "+self.old_name)
         wx.CallAfter(self.afterEdit, self, item)
예제 #3
0
파일: datacatalog.py 프로젝트: caomw/grass
 def OnDelete(self, event):
     """Delete layer or mapset"""
     if (self.selected_layer):
         string = self.GetItemText(self.selected_layer)
         self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))
         removed = 0
         # TODO: rewrite this that it will tell map type in the dialog
         if (self._confirmDialog(question=_('Do you really want to delete map <{m}>?').format(m=string),
                                 title=_('Delete map')) == wx.ID_YES):
             label = _("Deleting") + " " + string + " ..."
             self.showNotification.emit(message=label)
             if (self.GetItemText(self.selected_type)=='vect'):
                 removed = RunCommand('g.remove', flags='f', type='vect',
                                      pattern=string)
             elif (self.GetItemText(self.selected_type)=='rast'):
                 removed = RunCommand('g.remove', flags='f', type='rast',
                                      pattern=string)
             else:
                 removed = RunCommand('g.remove', flags='f', type='rast3d',
                                      pattern=string)
             if (removed==0):
                 self.Delete(self.selected_layer)
                 Debug.msg(1,"LAYER "+string+" DELETED")
                 label = "g.remove -f type="+self.GetItemText(self.selected_type)+" pattern="+string+"    -- completed" # generate this message (command) automatically?
                 self.showNotification.emit(message=label)
         self.RestoreBackup()
예제 #4
0
파일: dialogs.py 프로젝트: caomw/grass
 def OnSubmit(self, event):
     """Submit records"""
     layer = 1
     close = True
     enc = UserSettings.Get(group = 'atm', key = 'encoding', subkey = 'value')
     if not enc and 'GRASS_DB_ENCODING' in os.environ:
         enc = os.environ['GRASS_DB_ENCODING']
     
     for sql in self.GetSQLString(updateValues = True):
         if not sql:
             close = False
             continue
         if enc:
             sql = sql.encode(enc)
         else:
             sql = sql.encode('utf-8')
         
         driver, database = self.mapDBInfo.GetDbSettings(layer)
         Debug.msg(1, "SQL: %s" % sql)
         RunCommand('db.execute',
                    parent = self,
                    quiet = True,
                    input = '-',
                    stdin = sql,
                    driver = driver,
                    database = database)
         
         layer += 1
     
     if close and self.closeDialog.IsChecked():
         self.OnClose(event)
예제 #5
0
    def UpdateHist(self, img=None):
        """Update canvas if histogram options changes or window
        changes geometry
        """
        Debug.msg(
            2, "BufferedWindow.UpdateHist(%s): render=%s" %
            (img, self.render))
        
        if not self.render:
            return
        
        # render new map images
        # set default font and encoding environmental variables
        if "GRASS_FONT" in os.environ:
            self._oldfont = os.environ["GRASS_FONT"]
        if self.parent.font:
            os.environ["GRASS_FONT"] = self.parent.font
        if "GRASS_ENCODING" in os.environ:
            self._oldencoding = os.environ["GRASS_ENCODING"]
        if self.parent.encoding is not None and self.parent.encoding != "ISO-8859-1":
            os.environ[GRASS_ENCODING] = self.parent.encoding

        # using active comp region
        self.Map.GetRegion(update=True)

        self.Map.width, self.Map.height = self.GetClientSize()
        self.mapfile = self.Map.Render(force=self.render)
        self.Map.GetRenderMgr().renderDone.connect(self.UpdateHistDone)
예제 #6
0
 def OnEditLabel(self, node, event):
     """End label editing"""
     if self.selected_layer and not event.IsEditCancelled():
         self.old_name = node.label
         Debug.msg(1, "End label edit {name}".format(name=self.old_name))
         self.new_name = event.GetLabel()
         self.Rename()
예제 #7
0
 def OnDelete(self, event):
     """Delete layer or mapset"""
     if self.selected_layer:
         string = self.selected_layer.label
         gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, self.selected_mapset.label)
         removed = 0
         # TODO: rewrite this that it will tell map type in the dialog
         if self._confirmDialog(question=_('Do you really want to delete map <{m}>?').format(m=string),
                                title=_('Delete map')) == wx.ID_YES:
             label = _("Deleting {name}...").format(name=string)
             self.showNotification.emit(message=label)
             if self.selected_type.label == 'vector':
                 removed, cmd = self._runCommand('g.remove', flags='f', type='vector',
                                      name=string, env=env)
             elif self.selected_type.label == 'raster':
                 removed, cmd = self._runCommand('g.remove', flags='f', type='raster',
                                      name=string, env=env)
             else:
                 removed, cmd = self._runCommand('g.remove', flags='f', type='raster_3d',
                                      name=string, env=env)
             if removed == 0:
                 self._model.RemoveNode(self.selected_layer)
                 self.RefreshNode(self.selected_type, recursive=True)
                 Debug.msg(1, "LAYER " + string + " DELETED")
                 self.showNotification.emit(message= _("{cmd} -- completed").format(cmd=cmd))
         gscript.try_remove(gisrc)
예제 #8
0
파일: provider.py 프로젝트: rkrug/grass-ci
def _setEnvironment(width, height, filename, transparent, bgcolor):
    """Sets environmental variables for 2D rendering.

    :param width: rendering width
    :param height: rendering height
    :param filename: file name
    :param transparent: use transparency
    :param bgcolor: background color as a tuple of 3 values 0 to 255
    """
    Debug.msg(
        5,
        "_setEnvironment: width={w}, height={h}, "
        "filename={f}, transparent={t}, bgcolor={b}".format(
            w=width,
            h=height,
            f=filename,
            t=transparent,
            b=bgcolor))

    os.environ['GRASS_RENDER_WIDTH'] = str(width)
    os.environ['GRASS_RENDER_HEIGHT'] = str(height)
    driver = UserSettings.Get(group='display', key='driver', subkey='type')
    os.environ['GRASS_RENDER_IMMEDIATE'] = driver
    os.environ['GRASS_RENDER_BACKGROUNDCOLOR'] = '{r:02x}{g:02x}{b:02x}'.format(
        r=bgcolor[0], g=bgcolor[1], b=bgcolor[2])
    os.environ['GRASS_RENDER_TRUECOLOR'] = "TRUE"
    if transparent:
        os.environ['GRASS_RENDER_TRANSPARENT'] = "TRUE"
    else:
        os.environ['GRASS_RENDER_TRANSPARENT'] = "FALSE"
    os.environ['GRASS_RENDER_FILE'] = str(filename)
예제 #9
0
파일: provider.py 프로젝트: rkrug/grass-ci
    def LoadOverlay(self, cmd):
        """Creates raster legend with d.legend

        :param cmd: d.legend command as a list

        :return: bitmap with legend
        """
        Debug.msg(5, "BitmapProvider.LoadOverlay: cmd={c}".format(c=cmd))

        fileHandler, filename = tempfile.mkstemp(suffix=".png")
        os.close(fileHandler)
        # Set the environment variables for this process
        _setEnvironment(self.imageWidth, self.imageHeight, filename,
                        transparent=True, bgcolor=(0, 0, 0))

        Debug.msg(1, "Render raster legend " + str(filename))
        cmdTuple = cmdlist_to_tuple(cmd)
        returncode, stdout, messages = read2_command(
            cmdTuple[0], **cmdTuple[1])

        if returncode == 0:
            return wx.BitmapFromImage(autoCropImageFromFile(filename))
        else:
            os.remove(filename)
            raise GException(messages)
예제 #10
0
파일: provider.py 프로젝트: rkrug/grass-ci
    def Load(self, force=False, bgcolor=(255, 255, 255), nprocs=4):
        """Loads data, both 2D and 3D. In case of 2D, it creates composites,
        even when there is only 1 layer to compose (to be changed for speedup)

        :param force: if True reload all data, otherwise only missing data
        :param bgcolor: background color as a tuple of 3 values 0 to 255
        :param nprocs: number of procs to be used for rendering
        """
        Debug.msg(2, "BitmapProvider.Load: "
                     "force={f}, bgcolor={b}, nprocs={n}".format(f=force,
                                                                 b=bgcolor,
                                                                 n=nprocs))
        cmds = []
        regions = []
        if self._uniqueCmds:
            cmds.extend(self._uniqueCmds)
            regions.extend(self._regionsForUniqueCmds)
        if self._cmds3D:
            cmds.extend(self._cmds3D)
            regions.extend([None] * len(self._cmds3D))

        count = self._dryRender(cmds, regions, force=force)
        self.renderingStarted.emit(count=count)

        # create no data bitmap
        if None not in self._bitmapPool or force:
            self._bitmapPool[None] = createNoDataBitmap(
                self.imageWidth, self.imageHeight)

        ok = self._renderer.Render(
            cmds,
            regions,
            regionFor3D=self._regionFor3D,
            bgcolor=bgcolor,
            force=force,
            nprocs=nprocs)
        self.renderingFinished.emit()
        if not ok:
            self.mapsLoaded.emit()  # what to do here?
            return
        if self._cmdsForComposition:
            count = self._dryCompose(
                self._cmdsForComposition,
                self._regions,
                force=force)
            self.compositionStarted.emit(count=count)
            self._composer.Compose(
                self._cmdsForComposition,
                self._regions,
                self._opacities,
                bgcolor=bgcolor,
                force=force,
                nprocs=nprocs)
            self.compositionFinished.emit()
        if self._cmds3D:
            for cmd in self._cmds3D:
                self._bitmapPool[HashCmds([cmd], None)] = \
                    wx.Bitmap(GetFileFromCmd(self._tempDir, cmd, None))

        self.mapsLoaded.emit()
예제 #11
0
파일: ghelp.py 프로젝트: rkrug/grass-ci
    def _pageStats(self):
        """Translation statistics info"""
        fname = "translation_status.json"
        statsfile = os.path.join(os.getenv("GISBASE"), fname)
        if os.path.exists(statsfile):
            statsFile = open(statsfile)
            import json
            jsStats = json.load(statsFile)
        else:
            jsStats = None
        self.statswin = ScrolledPanel(self.aboutNotebook)
        self.statswin.SetBackgroundColour('WHITE')
        self.statswin.SetAutoLayout(True)

        if not jsStats:
            Debug.msg(5, _("File <%s> not found") % fname)
            statsSizer = wx.BoxSizer(wx.VERTICAL)
            statstext = wx.StaticText(self.statswin, id=wx.ID_ANY,
                                      label=_('%s file missing') % fname)
            statsSizer.Add(item=statstext, proportion=1,
                           flag=wx.EXPAND | wx.ALL, border=3)
        else:
            languages = sorted(jsStats['langs'].keys())

            statsSizer = wx.BoxSizer(wx.VERTICAL)
            for lang in languages:
                v = jsStats['langs'][lang]
                panel = self._langPanel(lang, v)
                statsSizer.Add(panel)

        self.statswin.SetSizer(statsSizer)
        self.statswin.SetupScrolling(scroll_x=False, scroll_y=True)
        self.statswin.Layout()
        self.statswin.Fit()
        return self.statswin
예제 #12
0
 def OnTool(self, event):
     """Tool selected
     """
     if self.toolSwitcher:
         Debug.msg(3, "BaseToolbar.OnTool(): id = %s" % event.GetId())
         self.toolSwitcher.ToolChanged(event.GetId())
     event.Skip()
예제 #13
0
파일: tree.py 프로젝트: GRASS-GIS/grass-ci
 def OnDeleteMap(self, event):
     """Delete layer or mapset"""
     name = self.selected_layer.label
     gisrc, env = gscript.create_environment(
         gisenv()["GISDBASE"], self.selected_location.label, self.selected_mapset.label
     )
     if (
         self._confirmDialog(
             question=_(
                 "Do you really want to delete map <{m}> of type <{etype}> from mapset "
                 "<{mapset}> in location <{loc}>?"
             ).format(
                 m=name,
                 mapset=self.selected_mapset.label,
                 etype=self.selected_type.label,
                 loc=self.selected_location.label,
             ),
             title=_("Delete map"),
         )
         == wx.ID_YES
     ):
         label = _("Deleting {name}...").format(name=name)
         self.showNotification.emit(message=label)
         if self.selected_type.label == "vector":
             removed, cmd = self._runCommand("g.remove", flags="f", type="vector", name=name, env=env)
         elif self.selected_type.label == "raster":
             removed, cmd = self._runCommand("g.remove", flags="f", type="raster", name=name, env=env)
         else:
             removed, cmd = self._runCommand("g.remove", flags="f", type="raster_3d", name=name, env=env)
         if removed == 0:
             self._model.RemoveNode(self.selected_layer)
             self.RefreshNode(self.selected_type, recursive=True)
             Debug.msg(1, "LAYER " + name + " DELETED")
             self.showNotification.emit(message=_("g.remove completed").format(cmd=cmd))
     gscript.try_remove(gisrc)
예제 #14
0
    def AlignExtentFromDisplay(self):
        """Align region extent based on display size from center
        point"""
        # calculate new bounding box based on center of display
        if self.region["ewres"] > self.region["nsres"]:
            res = self.region["ewres"]
        else:
            res = self.region["nsres"]

        Debug.msg(3, "Map.AlignExtentFromDisplay(): width=%d, height=%d, res=%f, center=%f,%f" % \
                      (self.width, self.height, res, self.region['center_easting'],
                       self.region['center_northing']))

        ew = (self.width / 2) * res
        ns = (self.height / 2) * res

        self.region['n'] = self.region['center_northing'] + ns
        self.region['s'] = self.region['center_northing'] - ns
        self.region['e'] = self.region['center_easting'] + ew
        self.region['w'] = self.region['center_easting'] - ew

        # LL locations
        if self.projinfo['proj'] == 'll':
            self.region['n'] = min(self.region['n'], 90.0)
            self.region['s'] = max(self.region['s'], -90.0)
예제 #15
0
파일: histogram.py 프로젝트: caomw/grass
 def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0,0,0,0]):
     """Draws histogram or clears window
     """
     if drawid == None:
         if pdctype == 'image' :
             drawid = imagedict[img]
         elif pdctype == 'clear':
             drawid == None
         else:
             drawid = wx.NewId()
     else:
         pdc.SetId(drawid)
     
     pdc.BeginDrawing()
     
     Debug.msg (3, "BufferedWindow.Draw(): id=%s, pdctype=%s, coord=%s" % (drawid, pdctype, coords))
     
     if pdctype == 'clear': # erase the display
         bg = wx.WHITE_BRUSH
         pdc.SetBackground(bg)
         pdc.Clear()
         self.Refresh()
         pdc.EndDrawing()
         return
     
     if pdctype == 'image':
         bg = wx.TRANSPARENT_BRUSH
         pdc.SetBackground(bg)
         bitmap = wx.BitmapFromImage(img)
         w,h = bitmap.GetSize()
         pdc.DrawBitmap(bitmap, coords[0], coords[1], True) # draw the composite map
         pdc.SetIdBounds(drawid, (coords[0],coords[1],w,h))
     
     pdc.EndDrawing()
     self.Refresh()
예제 #16
0
    def CreateTool(self, label, bitmap, kind,
                   shortHelp, longHelp, handler, pos = -1):
        """Add tool to the toolbar
        
        :param pos: if -1 add tool, if > 0 insert at given pos
        :return: id of tool
        """
        bmpDisabled = wx.NullBitmap
        tool = -1
        if label:
            tool = vars(self)[label] = wx.NewId()
            Debug.msg(3, "CreateTool(): tool=%d, label=%s bitmap=%s" % \
                          (tool, label, bitmap))
            if pos < 0:
                toolWin = self.AddLabelTool(tool, label, bitmap,
                                            bmpDisabled, kind,
                                            shortHelp, longHelp)
            else:
                toolWin = self.InsertLabelTool(pos, tool, label, bitmap,
                                            bmpDisabled, kind,
                                            shortHelp, longHelp)
            self.handlers[tool] = handler
            self.Bind(wx.EVT_TOOL, handler, toolWin)
            self.Bind(wx.EVT_TOOL, self.OnTool, toolWin)
        else: # separator
            self.AddSeparator()

        return tool
예제 #17
0
    def DeleteLayer(self, layer, overlay = False):
        """Removes layer from list of layers

        :param layer: layer instance in layer tree
        :param overlay: delete overlay (use self.DeleteOverlay() instead)

        :return: removed layer on success or None
        """
        Debug.msg (3, "Map.DeleteLayer(): name=%s" % layer.name)

        if overlay:
            list = self.overlays
        else:
            list = self.layers

        if layer in list:
            if layer.mapfile:
                base = os.path.split(layer.mapfile)[0]
                mapfile = os.path.split(layer.mapfile)[1]
                tempbase = mapfile.split('.')[0]
                if base == '' or tempbase == '':
                    return None
                basefile = os.path.join(base, tempbase) + r'.*'
                for f in glob.glob(basefile):
                    os.remove(f)
            list.remove(layer)

            return layer

        return None
예제 #18
0
    def AddOverlay(self, id, ltype, command,
                   active = True, hidden = True, opacity = 1.0, render = False):
        """Adds overlay (grid, barscale, legend, etc.) to list of
        overlays

        :param id: overlay id (PseudoDC)
        :param ltype: overlay type (barscale, legend)
        :param command: GRASS command to render overlay
        :param active: overlay activated (True) or disabled (False)
        :param hidden: overlay is not shown in layer tree (if True)
        :param render: render an image (if True)

        :return: new layer on success
        :return: None on failure
        """
        Debug.msg (2, "Map.AddOverlay(): cmd=%s, render=%d" % (command, render))
        overlay = Overlay(id = id, ltype = ltype, cmd = command, Map = self,
                          active = active, hidden = hidden, opacity = opacity)

        # add maplayer to the list of layers
        self.overlays.append(overlay)

        if render and command != '' and not overlay.Render():
            raise GException(_("Unable to render overlay <%s>.") %
                             ltype)

        return self.overlays[-1]
예제 #19
0
    def Draw(self, dc):
        """Draws bitmap."""
        Debug.msg(5, "AnimationWindow.Draw()")

        dc.Clear()  # make sure you clear the bitmap!
        if self.bitmap.GetWidth() > 1:
            dc.DrawBitmap(self.bitmap, x=self.x, y=self.y)
예제 #20
0
 def ClearOverlay(self):
     """Clear overlay (legend) """
     Debug.msg(3, "AnimationWindow.ClearOverlay()")
     self._overlay = None
     self.bitmap_overlay = None
     self._pdc.RemoveAll()
     self.UpdateDrawing()
예제 #21
0
파일: toolbars.py 프로젝트: rkrug/grass-ci
 def OnAddPoint(self, event):
     """Add point to the vector map Laier"""
     Debug.msg(2, "VDigitToolbar.OnAddPoint()")
     self.action = {'desc': "addLine",
                    'type': "point",
                    'id': self.addPoint}
     self.MapWindow.mouse['box'] = 'point'
예제 #22
0
파일: toolbars.py 프로젝트: rkrug/grass-ci
 def OnAddLine(self, event):
     """Add line to the vector map layer"""
     Debug.msg(2, "VDigitToolbar.OnAddLine()")
     self.action = {'desc': "addLine",
                    'type': "line",
                    'id': self.addLine}
     self.MapWindow.mouse['box'] = 'line'
예제 #23
0
파일: widgets.py 프로젝트: rkrug/grass-ci
    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)
예제 #24
0
파일: catalog.py 프로젝트: rkrug/grass-ci
    def __init__(self, parent, giface=None, id=wx.ID_ANY,
                 title=_("Data catalog"), name='catalog', **kwargs):
        """Panel constructor  """
        self.showNotification = Signal('DataCatalog.showNotification')
        self.changeMapset = Signal('DataCatalog.changeMapset')
        self.changeLocation = Signal('DataCatalog.changeLocation')
        self.parent = parent
        self.baseTitle = title
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)
        self.SetName("DataCatalog")

        Debug.msg(1, "DataCatalog.__init__()")

        # toolbar
        self.toolbar = DataCatalogToolbar(parent=self)

        # tree with layers
        self.tree = DataCatalogTree(self, giface=giface)
        self.thread = gThread()
        self._loaded = False
        self.tree.showNotification.connect(self.showNotification)
        self.tree.changeMapset.connect(self.changeMapset)
        self.tree.changeLocation.connect(self.changeLocation)

        # some layout
        self._layout()
예제 #25
0
파일: toolbars.py 프로젝트: rkrug/grass-ci
    def OnTool(self, event):
        """Tool selected -> untoggles previusly selected tool in
        toolbar"""
        Debug.msg(3, "VDigitToolbar.OnTool(): id = %s" % event.GetId())
        # set cursor
        self.MapWindow.SetNamedCursor('cross')
        self.MapWindow.mouse['box'] = 'point'
        self.MapWindow.mouse['use'] = 'pointer'

        aId = self.action.get('id', -1)
        BaseToolbar.OnTool(self, event)

        # clear tmp canvas
        if self.action['id'] != aId or aId == -1:
            self.MapWindow.polycoords = []
            self.MapWindow.ClearLines(pdc=self.MapWindow.pdcTmp)
            if self.digit and \
                    len(self.MapWindow.digit.GetDisplay().GetSelected()) > 0:
                # cancel action
                self.MapWindow.OnMiddleDown(None)

        # set no action
        if self.action['id'] == -1:
            self.action = {'desc': '',
                           'type': '',
                           'id': -1}

        # set focus
        self.MapWindow.SetFocus()
예제 #26
0
    def GetPPM(self):
        """Get pixel per meter
        
        .. todo::
            now computed every time, is it necessary?
        
        .. todo::
            enable user to specify ppm (and store it in UserSettings)
        """
        # TODO: need to be fixed...
        ### screen X region problem
        ### user should specify ppm
        dc = wx.ScreenDC()
        dpSizePx = wx.DisplaySize()   # display size in pixels
        dpSizeMM = wx.DisplaySizeMM() # display size in mm (system)
        dpSizeIn = (dpSizeMM[0] / 25.4, dpSizeMM[1] / 25.4) # inches
        sysPpi  = dc.GetPPI()
        comPpi = (dpSizePx[0] / dpSizeIn[0],
                  dpSizePx[1] / dpSizeIn[1])

        ppi = comPpi                  # pixel per inch
        ppm = ((ppi[0] / 2.54) * 100, # pixel per meter
                    (ppi[1] / 2.54) * 100)
        
        Debug.msg(4, "MapFrameBase.GetPPM(): size: px=%d,%d mm=%f,%f "
                  "in=%f,%f ppi: sys=%d,%d com=%d,%d; ppm=%f,%f" % \
                  (dpSizePx[0], dpSizePx[1], dpSizeMM[0], dpSizeMM[1],
                   dpSizeIn[0], dpSizeIn[1],
                   sysPpi[0], sysPpi[1], comPpi[0], comPpi[1],
                   ppm[0], ppm[1]))
        
        return ppm
예제 #27
0
    def GetMapScale(self, map = None):
        """Get current map scale
        
        :param map: Map instance (if none self.Map is used)
        """
        if not map:
            map = self.GetMap()
        
        region = map.region
        ppm = self.GetPPM()

        heightCm = region['rows'] / ppm[1] * 100
        widthCm  = region['cols'] / ppm[0] * 100

        Debug.msg(4, "MapFrame.GetMapScale(): width_cm=%f, height_cm=%f" %
                  (widthCm, heightCm))

        xscale = (region['e'] - region['w']) / (region['cols'] / ppm[0])
        yscale = (region['n'] - region['s']) / (region['rows'] / ppm[1])
        scale = (xscale + yscale) / 2.
        
        Debug.msg(3, "MapFrame.GetMapScale(): xscale=%f, yscale=%f -> scale=%f" % \
                      (xscale, yscale, scale))
        
        return scale
예제 #28
0
파일: tree.py 프로젝트: GRASS-GIS/grass-ci
 def OnDisplayLayer(self, event):
     """Display layer in current graphics view"""
     layerName = []
     if self.selected_location.label == gisenv()["LOCATION_NAME"] and self.selected_mapset:
         string = self.selected_layer.label + "@" + self.selected_mapset.label
         layerName.append(string)
         label = _("Displaying {name}...").format(name=string)
         self.showNotification.emit(message=label)
         label = (
             "d."
             + self.selected_type.label[:4]
             + " --q map="
             + string
             + _(" -- completed. Go to Layers tab for further operations.")
         )
         if self.selected_type.label == "vector":
             self._giface.lmgr.AddMaps(layerName, "vector", True)
         elif self.selected_type.label == "raster":
             self._giface.lmgr.AddMaps(layerName, "raster", True)
         else:
             self._giface.lmgr.AddMaps(layerName, "raster_3d", True)
             # generate this message (command) automatically?
             label = "d.rast --q map=" + string + _(" -- completed. Go to Layers tab for further operations.")
         self.showNotification.emit(message=label)
         Debug.msg(1, "LAYER " + self.selected_layer.label + " DISPLAYED")
     else:
         GError(_("Failed to display layer: not in current mapset or invalid layer"), parent=self)
예제 #29
0
 def _resize(self):
     Debug.msg(1, "MapFrame._resize():")
     wm, hw = self.MapWindow.GetClientSize()
     wf, hf = self.GetSize()
     dw = wf - wm
     dh = hf - hw
     self.SetSize((wf + dw, hf + dh))
예제 #30
0
파일: widgets.py 프로젝트: rkrug/grass-ci
 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
예제 #31
0
 def __delitem__(self, key):
     self.referenceCount[key] -= 1
     Debug.msg(5,
               'DictRefCounter.__delitem__: -1 for key {k}'.format(k=key))
예제 #32
0
    def __init__(self,
                 parent,
                 toolSwitcher,
                 MapWindow,
                 digitClass,
                 giface,
                 tools=[]):
        self.MapWindow = MapWindow
        self.Map = MapWindow.GetMap()  # Map class instance
        self.tools = tools
        self.digitClass = digitClass
        BaseToolbar.__init__(self, parent, toolSwitcher)
        self.digit = None
        self._giface = giface
        self.fType = None  # feature type for simple features editing

        self.editingStarted = Signal("VDigitToolbar.editingStarted")
        self.editingStopped = Signal("VDigitToolbar.editingStopped")
        self.editingBgMap = Signal("VDigitToolbar.editingBgMap")
        self.quitDigitizer = Signal("VDigitToolbar.quitDigitizer")
        layerTree = self._giface.GetLayerTree()
        if layerTree:
            self.editingStarted.connect(layerTree.StartEditing)
            self.editingStopped.connect(layerTree.StopEditing)
            self.editingBgMap.connect(layerTree.SetBgMapForEditing)

        # bind events
        self.Bind(wx.EVT_SHOW, self.OnShow)

        # currently selected map layer for editing (reference to MapLayer
        # instance)
        self.mapLayer = None
        # list of vector layers from Layer Manager (only in the current mapset)
        self.layers = []

        self.comboid = self.combo = None
        self.undo = -1
        self.redo = -1

        # only one dialog can be open
        self.settingsDialog = None

        # create toolbars (two rows optionally)
        self.InitToolbar(self._toolbarData())

        self._default = -1
        # default action (digitize new point, line, etc.)
        self.action = {'desc': '', 'type': '', 'id': -1}
        self._currentAreaActionType = None

        # list of available vector maps
        self.UpdateListOfLayers(updateTool=True)

        for tool in ('addPoint', 'addLine', 'addBoundary', 'addCentroid',
                     'addArea', 'addVertex', 'deleteLine', 'deleteArea',
                     'displayAttr', 'displayCats', 'editLine', 'moveLine',
                     'moveVertex', 'removeVertex', 'additionalTools'):
            if hasattr(self, tool):
                tool = getattr(self, tool)
                self.toolSwitcher.AddToolToGroup(group='mouseUse',
                                                 toolbar=self,
                                                 tool=tool)
            else:
                Debug.msg(1, '%s skipped' % tool)

        # custom button for digitization of area/boundary/centroid
        # TODO: could this be somehow generalized?
        nAreaTools = 0
        if self.tools and 'addBoundary' in self.tools:
            nAreaTools += 1
        if self.tools and 'addCentroid' in self.tools:
            nAreaTools += 1
        if self.tools and 'addArea' in self.tools:
            nAreaTools += 1
        if nAreaTools != 1:
            self.areaButton = self.CreateSelectionButton(
                _("Select area/boundary/centroid tool"))
            self.areaButtonId = self.InsertControl(5, self.areaButton)
            self.areaButton.Bind(wx.EVT_BUTTON, self.OnAddAreaMenu)

        # realize toolbar
        self.Realize()
        # workaround for Mac bug. May be fixed by 2.8.8, but not before then.
        if self.combo:
            self.combo.Hide()
            self.combo.Show()

        # disable undo/redo
        if self.undo > 0:
            self.EnableTool(self.undo, False)
        if self.redo > 0:
            self.EnableTool(self.redo, False)

        self.FixSize(width=105)
예제 #33
0
파일: frame.py 프로젝트: ericrpatton/grass
    def OnSashChanging(self, event):
        """Sash position is changing, slider must be moved too."""
        Debug.msg(5, "SwipeMapPanel.OnSashChanging()")

        self.slider.SetValue(self.splitter.GetSashPosition())
        event.Skip()
예제 #34
0
    def GetSQLString(self, updateValues=False):
        """Create SQL statement string based on self.sqlStatement

        Show error message when invalid values are entered.

        If updateValues is True, update dataFrame according to values
        in textfields.
        """
        sqlCommands = []
        # find updated values for each layer/category
        for layer in self.mapDBInfo.layers.keys():  # for each layer
            table = self.mapDBInfo.GetTable(layer)
            key = self.mapDBInfo.GetKeyColumn(layer)
            columns = self.mapDBInfo.GetTableDesc(table)
            for idx in range(len(columns[key]['values'])):  # for each category
                updatedColumns = []
                updatedValues = []
                for name in columns.keys():
                    if name == key:
                        cat = columns[name]['values'][idx]
                        continue
                    ctype = columns[name]['ctype']
                    value = columns[name]['values'][idx]
                    id = columns[name]['ids'][idx]
                    try:
                        newvalue = self.FindWindowById(id).GetValue()
                    except:
                        newvalue = self.FindWindowById(id).GetLabel()

                    if newvalue:
                        try:
                            if ctype == int:
                                newvalue = int(newvalue)
                            elif ctype == float:
                                newvalue = float(newvalue)
                        except ValueError:
                            GError(
                                parent=self,
                                message=
                                _("Column <%(col)s>: Value '%(value)s' needs to be entered as %(type)s."
                                  ) % {
                                      'col': name,
                                      'value': str(newvalue),
                                      'type': columns[name]['type'].lower()
                                  },
                                showTraceback=False)
                            sqlCommands.append(None)
                            continue
                    else:
                        if self.action == 'add':
                            continue

                    if newvalue != value:
                        updatedColumns.append(name)
                        if not newvalue:
                            updatedValues.append('NULL')
                        else:
                            if ctype != str:
                                updatedValues.append(str(newvalue))
                            else:
                                updatedValues.append(
                                    "'" + newvalue.replace("'", "''") + "'")
                        columns[name]['values'][idx] = newvalue

                if self.action != "add" and len(updatedValues) == 0:
                    continue

                if self.action == "add":
                    sqlString = "INSERT INTO %s (%s," % (table, key)
                else:
                    sqlString = "UPDATE %s SET " % table

                for idx in range(len(updatedColumns)):
                    name = updatedColumns[idx]
                    if self.action == "add":
                        sqlString += name + ","
                    else:
                        sqlString += name + "=" + updatedValues[idx] + ","

                sqlString = sqlString[:-1]  # remove last comma

                if self.action == "add":
                    sqlString += ") VALUES (%s," % cat
                    for value in updatedValues:
                        sqlString += value + ","
                    sqlString = sqlString[:-1]  # remove last comma
                    sqlString += ")"
                else:
                    sqlString += " WHERE %s=%s" % (key, cat)
                sqlCommands.append(sqlString)
            # for each category
        # for each layer END

        Debug.msg(3,
                  "DisplayAttributesDialog.GetSQLString(): %s" % sqlCommands)

        return sqlCommands
예제 #35
0
    def OnPasteMap(self, event):
        """Paste layer"""
        # copying between mapsets of one location
        if not self.copy_layer:
            GMessage(_("No map selected for copying."), parent=self)
            return
        if self.selected_location == self.copy_location:
            gisrc, env = getEnvironment(gisenv()['GISDBASE'],
                                        self.selected_location.label,
                                        mapset=self.selected_mapset.label)
            new_name = self._getNewMapName(_('New name'),
                                           _('Copy map'),
                                           self.copy_layer.label,
                                           env=env,
                                           mapset=self.selected_mapset.label,
                                           element=self.copy_type.label)
            if not new_name:
                return
            if map_exists(new_name,
                          element=self.copy_type.label,
                          env=env,
                          mapset=self.selected_mapset.label):
                GMessage(_("Failed to copy map: new map has the same name"),
                         parent=self)
                return

            if not self.selected_type:
                found = self._model.SearchNodes(parent=self.selected_mapset,
                                                type='element',
                                                name=self.copy_type.label)
                self.selected_type = found[0] if found else None

            overwrite = False
            if self.selected_type:
                found = self._model.SearchNodes(parent=self.selected_type,
                                                type=self.copy_type.label,
                                                name=new_name)
                if found and found[0]:
                    dlg = wx.MessageDialog(
                        parent=self,
                        message=_("Map <{map}> already exists "
                                  "in the current mapset. "
                                  "Do you want to overwrite it?").format(
                                      map=new_name),
                        caption=_("Overwrite?"),
                        style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
                    ret = dlg.ShowModal()
                    dlg.Destroy()
                    if ret == wx.ID_YES:
                        overwrite = True

            string = self.copy_layer.label + '@' + self.copy_mapset.label + ',' + new_name

            pasted = 0
            label = _("Copying <{name}>...").format(name=string)
            self.showNotification.emit(message=label)
            if self.copy_type.label == 'vector':
                pasted, cmd = self._runCommand('g.copy',
                                               vector=string,
                                               overwrite=overwrite,
                                               env=env)
                node = 'vector'
            elif self.copy_type.label == 'raster':
                pasted, cmd = self._runCommand('g.copy',
                                               raster=string,
                                               overwrite=overwrite,
                                               env=env)
                node = 'raster'
            else:
                pasted, cmd = self._runCommand('g.copy',
                                               raster_3d=string,
                                               overwrite=overwrite,
                                               env=env)
                node = 'raster_3d'
            if pasted == 0:
                self.InsertLayer(name=new_name,
                                 mapset_node=self.selected_mapset,
                                 element_name=node)
                Debug.msg(1, "COPIED TO: " + new_name)
                self.showNotification.emit(
                    message=_("g.copy completed").format(cmd=cmd))
            gscript.try_remove(gisrc)
        else:
            GError(_(
                "Failed to copy map: action is allowed only within the same location."
            ),
                   parent=self)

        # expand selected mapset
        self.ExpandNode(self.selected_mapset, recursive=True)
예제 #36
0
파일: frame.py 프로젝트: ericrpatton/grass
    def __init__(self,
                 parent=None,
                 giface=None,
                 title=_("Map Swipe"),
                 name="swipe",
                 **kwargs):
        DoubleMapPanel.__init__(
            self,
            parent=parent,
            title=title,
            name=name,
            firstMap=Map(),
            secondMap=Map(),
            **kwargs,
        )
        Debug.msg(1, "SwipeMapPanel.__init__()")
        #
        # Add toolbars
        #
        for name in ("swipeMain", "swipeMap", "swipeMisc"):
            self.AddToolbar(name)
        self._mgr.Update()

        self._giface = giface
        #
        # create widgets
        #
        self.splitter = MapSplitter(parent=self, id=wx.ID_ANY)

        self.sliderH = Slider(self, id=wx.ID_ANY, style=wx.SL_HORIZONTAL)
        self.sliderV = Slider(self, id=wx.ID_ANY, style=wx.SL_VERTICAL)

        self.mapWindowProperties = MapWindowProperties()
        self.mapWindowProperties.setValuesFromUserSettings()
        self.mapWindowProperties.autoRenderChanged.connect(
            self.OnAutoRenderChanged)
        self.firstMapWindow = SwipeBufferedWindow(
            parent=self.splitter,
            giface=self._giface,
            properties=self.mapWindowProperties,
            Map=self.firstMap,
        )
        self.secondMapWindow = SwipeBufferedWindow(
            parent=self.splitter,
            giface=self._giface,
            properties=self.mapWindowProperties,
            Map=self.secondMap,
        )
        # bind query signal
        self.firstMapWindow.mapQueried.connect(self.Query)
        self.secondMapWindow.mapQueried.connect(self.Query)

        # bind tracking cursosr to mirror it
        self.firstMapWindow.Bind(wx.EVT_MOTION,
                                 lambda evt: self.TrackCursor(evt))
        self.secondMapWindow.Bind(wx.EVT_MOTION,
                                  lambda evt: self.TrackCursor(evt))

        self.MapWindow = self.firstMapWindow  # current by default
        self.firstMapWindow.zoomhistory = self.secondMapWindow.zoomhistory
        self.SetBindRegions(True)

        self._mode = "swipe"

        # statusbar items
        statusbarItems = [
            sb.SbCoordinates,
            sb.SbRegionExtent,
            sb.SbCompRegionExtent,
            sb.SbShowRegion,
            sb.SbAlignExtent,
            sb.SbResolution,
            sb.SbDisplayGeometry,
            sb.SbMapScale,
            sb.SbGoTo,
            sb.SbProjection,
        ]
        self.statusbar = self.CreateStatusbar(statusbarItems)

        self._addPanes()
        self._bindWindowsActivation()
        self._setUpMapWindow(self.firstMapWindow)
        self._setUpMapWindow(self.secondMapWindow)

        self._mgr.GetPane("sliderV").Hide()
        self._mgr.GetPane("sliderH").Show()
        self.slider = self.sliderH

        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_IDLE, self.OnIdle)

        self.SetSize((800, 600))

        self._mgr.Update()

        self.rasters = {"first": None, "second": None}

        self._inputDialog = None
        self._preferencesDialog = None
        self._queryDialog = None

        # default action in map toolbar
        self.GetMapToolbar().SelectDefault()

        self.resize = False

        wx.CallAfter(self.CallAfterInit)
예제 #37
0
파일: frame.py 프로젝트: ericrpatton/grass
 def OnSize(self, event):
     Debug.msg(4, "SwipeMapPanel.OnSize()")
     self.resize = grass.clock()
     super(SwipeMapPanel, self).OnSize(event)
예제 #38
0
파일: frame.py 프로젝트: ericrpatton/grass
    def OnSashChanged(self, event):
        """Sash position changed, slider must be moved too."""
        Debug.msg(5, "SwipeMapPanel.OnSashChanged()")

        self.OnSashChanging(event)
        event.Skip()
예제 #39
0
파일: ws.py 프로젝트: rkanavath/grass-ci
    def Render(self, cmd, env):
        """If it is needed, download missing WMS data.

        .. todo::
            lmgr deletes mapfile and maskfile when order of layers
            was changed (drag and drop) - if deleted, fetch data again
        """
        if not haveGdal:
            return

        Debug.msg(
            1, "RenderWMSMgr.Render(%s): force=%d img=%s" %
            (self.layer, self.layer.forceRender, self.layer.mapfile))

        env = copy.copy(env)
        self.dstSize['cols'] = int(env["GRASS_RENDER_WIDTH"])
        self.dstSize['rows'] = int(env["GRASS_RENDER_HEIGHT"])

        region = self._getRegionDict(env)
        self._fitAspect(region, self.dstSize)

        self.updateMap = True
        fetchData = True  # changed to True when calling Render()
        zoomChanged = False

        if self.renderedRegion is None or \
           cmd != self.fetched_data_cmd:
            fetchData = True
        else:
            for c in ['north', 'south', 'east', 'west']:
                if self.renderedRegion and \
                   region[c] != self.renderedRegion[c]:
                    fetchData = True
                    break

            for c in ['e-w resol', 'n-s resol']:
                if self.renderedRegion and \
                        region[c] != self.renderedRegion[c]:
                    zoomChanged = True
                    break

        if fetchData:
            self.fetched_data_cmd = None
            self.renderedRegion = region

            try_remove(self.layer.mapfile)
            try_remove(self.tempMap)

            self.currentPid = self.thread.GetId()
            # self.thread.Terminate()
            self.downloading = True

            self.fetching_cmd = cmd

            env["GRASS_RENDER_FILE"] = self.tempMap
            env["GRASS_REGION"] = self._createRegionStr(region)

            cmd_render = copy.deepcopy(cmd)
            cmd_render[1]['quiet'] = True  # be quiet

            self._startTime = time.time()
            self.thread.Run(callable=self._render,
                            cmd=cmd_render,
                            env=env,
                            ondone=self.OnRenderDone)
            self.layer.forceRender = False

        self.updateProgress.emit(layer=self.layer)
예제 #40
0
 def OnAddPoint(self, event):
     """Add point to the vector map Laier"""
     Debug.msg(2, "VDigitToolbar.OnAddPoint()")
     self.action = {'desc': "addLine", 'type': "point", 'id': self.addPoint}
     self.MapWindow.mouse['box'] = 'point'
예제 #41
0
    def _onMouseMoving(self, event):
        self.mouse['end'] = event.GetPosition()

        Debug.msg(5, "VDigitWindow.OnMouseMoving(): coords=%f,%f" %
                  (self.mouse['end'][0], self.mouse['end'][1]))

        action = self.toolbar.GetAction()
        if action == "addLine" and \
                self.toolbar.GetAction('type') in ["line", "boundary", "area"]:
            if len(self.polycoords) > 0:
                self.MouseDraw(pdc=self.pdcTmp,
                               begin=self.Cell2Pixel(self.polycoords[-1]))

        elif action in ["moveLine", "moveVertex", "editLine"] \
                and hasattr(self, "moveInfo"):
            dx = self.mouse['end'][0] - self.mouse['begin'][0]
            dy = self.mouse['end'][1] - self.mouse['begin'][1]

            # draw lines on new position
            if action == "moveLine" and \
                    len(self.moveInfo['id']) > 0:
                # move line
                for id in self.moveInfo['id']:
                    self.pdcTmp.TranslateId(id, dx, dy)
            elif action in ["moveVertex", "editLine"]:
                # move vertex ->
                # (vertex, left vertex, left line,
                # right vertex, right line)

                # do not draw static lines
                if action == "moveVertex" and \
                        len(self.moveInfo['id']) > 0:
                    self.polycoords = []
                    self.pdcTmp.RemoveId(self.moveInfo['id'][0])
                    if self.moveInfo['id'][1] > 0:  # previous vertex
                        x, y = self.Pixel2Cell(
                            self.pdcTmp.GetIdBounds(
                                self.moveInfo['id'][1])[
                                0:2])
                        self.pdcTmp.RemoveId(self.moveInfo['id'][1] + 1)
                        self.polycoords.append((x, y))
                    self.polycoords.append(self.Pixel2Cell(self.mouse['end']))

                    if self.moveInfo['id'][2] > 0:  # next vertex
                        x, y = self.Pixel2Cell(
                            self.pdcTmp.GetIdBounds(
                                self.moveInfo['id'][2])[
                                0:2])
                        self.pdcTmp.RemoveId(self.moveInfo['id'][2] - 1)
                        self.polycoords.append((x, y))

                    self.ClearLines(pdc=self.pdcTmp)
                    self.DrawLines(pdc=self.pdcTmp)

                if action == "editLine":
                    self.MouseDraw(pdc=self.pdcTmp,
                                   begin=self.Cell2Pixel(self.polycoords[-1]))

            self.Refresh()  # TODO: use RefreshRect()
            self.mouse['begin'] = self.mouse['end']

        elif action == "zbulkLine":
            if len(self.polycoords) == 1:
                # draw mouse moving
                self.MouseDraw(self.pdcTmp)
예제 #42
0
파일: frame.py 프로젝트: ericrpatton/grass
    def OnSliderPositionChanged(self, event):
        """Slider position changed, sash must be moved too."""
        Debug.msg(5, "SwipeMapPanel.OnSliderPositionChanged()")

        self.splitter.SetSashPosition(event.GetPosition())
        self.splitter.OnSashChanged(None)
예제 #43
0
    def __init__(self,
                 parent,
                 map,
                 query=None,
                 cats=None,
                 line=None,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                 pos=wx.DefaultPosition,
                 action="add",
                 ignoreError=False):
        """Standard dialog used to add/update/display attributes linked
        to the vector map.

        Attribute data can be selected based on layer and category number
        or coordinates.

        :param parent:
        :param map: vector map
        :param query: query coordinates and distance (used for v.edit)
        :param cats: {layer: cats}
        :param line: feature id (requested for cats)
        :param style:
        :param pos:
        :param action: (add, update, display)
        :param ignoreError: True to ignore errors
        """
        self.parent = parent  # mapdisplay.BufferedWindow
        self.map = map
        self.action = action

        # ids/cats of selected features
        # fid : {layer : cats}
        self.cats = {}
        self.fid = -1  # feature id

        # get layer/table/column information
        self.mapDBInfo = VectorDBInfo(self.map)

        layers = self.mapDBInfo.layers.keys()  # get available layers

        # check if db connection / layer exists
        if len(layers) <= 0:
            if not ignoreError:
                dlg = wx.MessageDialog(
                    parent=self.parent,
                    message=_("No attribute table found.\n\n"
                              "Do you want to create a new attribute table "
                              "and defined a link to vector map <%s>?") %
                    self.map,
                    caption=_("Create table?"),
                    style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
                if dlg.ShowModal() == wx.ID_YES:
                    lmgr = self.parent.lmgr
                    lmgr.OnShowAttributeTable(event=None, selection='layers')

                dlg.Destroy()

            self.mapDBInfo = None

        wx.Dialog.__init__(self,
                           parent=self.parent,
                           id=wx.ID_ANY,
                           title="",
                           style=style,
                           pos=pos)

        # dialog body
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        # notebook
        self.notebook = wx.Notebook(parent=self,
                                    id=wx.ID_ANY,
                                    style=wx.BK_DEFAULT)

        self.closeDialog = wx.CheckBox(parent=self,
                                       id=wx.ID_ANY,
                                       label=_("Close dialog on submit"))
        self.closeDialog.SetValue(True)
        if self.action == 'display':
            self.closeDialog.Enable(False)

        # feature id (text/choice for duplicates)
        self.fidMulti = wx.Choice(parent=self, id=wx.ID_ANY, size=(150, -1))
        self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
        self.fidText = wx.StaticText(parent=self, id=wx.ID_ANY)

        self.noFoundMsg = wx.StaticText(parent=self,
                                        id=wx.ID_ANY,
                                        label=_("No attributes found"))

        self.UpdateDialog(query=query, cats=cats)

        # set title
        if self.action == "update":
            self.SetTitle(_("Update attributes"))
        elif self.action == "add":
            self.SetTitle(_("Define attributes"))
        else:
            self.SetTitle(_("Display attributes"))

        # buttons
        btnCancel = wx.Button(self, wx.ID_CANCEL)
        btnReset = wx.Button(self, wx.ID_UNDO, _("&Reload"))
        btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit"))
        if self.action == 'display':
            btnSubmit.Enable(False)

        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(btnCancel)
        btnSizer.AddButton(btnReset)
        btnSizer.SetNegativeButton(btnReset)
        btnSubmit.SetDefault()
        btnSizer.AddButton(btnSubmit)
        btnSizer.Realize()

        mainSizer.Add(self.noFoundMsg,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        mainSizer.Add(self.notebook,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        fidSizer = wx.BoxSizer(wx.HORIZONTAL)
        fidSizer.Add(wx.StaticText(parent=self,
                                   id=wx.ID_ANY,
                                   label=_("Feature id:")),
                     proportion=0,
                     border=5,
                     flag=wx.ALIGN_CENTER_VERTICAL)
        fidSizer.Add(self.fidMulti,
                     proportion=0,
                     flag=wx.EXPAND | wx.ALL,
                     border=5)
        fidSizer.Add(self.fidText,
                     proportion=0,
                     flag=wx.EXPAND | wx.ALL,
                     border=5)
        mainSizer.Add(fidSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
                      border=5)
        mainSizer.Add(self.closeDialog,
                      proportion=0,
                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
                      border=5)
        mainSizer.Add(btnSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
                      border=5)

        # bindigs
        btnReset.Bind(wx.EVT_BUTTON, self.OnReset)
        btnSubmit.Bind(wx.EVT_BUTTON, self.OnSubmit)
        btnCancel.Bind(wx.EVT_BUTTON, self.OnClose)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

        # set min size for dialog
        w, h = self.GetBestSize()
        w += 50
        if h < 200:
            self.SetMinSize((w, 200))
        else:
            self.SetMinSize((w, h))

        if self.notebook.GetPageCount() == 0:
            Debug.msg(2, "DisplayAttributesDialog(): Nothing found!")
예제 #44
0
    def OnLeftDownUndo(self, event):
        """Left mouse button pressed with control key - vector
        digitizer undo functionality
        """
        if self.mouse["use"] != "pointer" or not self.toolbar:
            return

        action = self.toolbar.GetAction()
        if (action == "addLine" and self.toolbar.GetAction('type')
                in ["line", "boundary", "area"]) or action == "editLine":
            # add line or boundary -> remove last point from the line
            try:
                removed = self.polycoords.pop()
                Debug.msg(
                    4, "VDigitWindow.OnMiddleDown(): polycoords_poped=%s" %
                    [removed, ])
                # self.mouse['begin'] = self.Cell2Pixel(self.polycoords[-1])
            except:
                pass

        if action == "editLine":
            # remove last vertex & line
            if len(self.moveInfo['id']) > 1:
                self.moveInfo['id'].pop()

            self.UpdateMap(render=False, renderVector=False)

        elif action in ["deleteLine", "deleteArea", "moveLine", "splitLine",
                        "addVertex", "removeVertex", "moveVertex",
                        "copyCats", "flipLine", "mergeLine",
                        "snapLine", "connectLine", "copyLine",
                        "queryLine", "breakLine", "typeConv"]:
            # various tools -> unselected selected features
            self.digit.GetDisplay().SetSelected([])

            if action in ["moveLine", "moveVertex", "editLine"] and \
                    hasattr(self, "moveInfo"):
                del self.moveInfo

            elif action == "copyCats":
                try:
                    del self.copyCatsList
                    del self.copyCatsIds
                except AttributeError:
                    pass

            elif action == "copyLine":
                del self.copyIds
                if self.layerTmp:
                    self.Map.DeleteLayer(self.layerTmp)
                    self.UpdateMap(render=True, renderVector=False)
                del self.layerTmp

            self.polycoords = []
            self.UpdateMap(render=False)  # render vector

        elif action == "zbulkLine":
            # reset polyline
            self.polycoords = []
            self.digit.GetDisplay().SetSelected([])
            self.UpdateMap(render=False)

        self.redrawAll = True
        self.UpdateMap(render=False, renderVector=False)
예제 #45
0
 def OnAddLine(self, event):
     """Add line to the vector map layer"""
     Debug.msg(2, "VDigitToolbar.OnAddLine()")
     self.action = {'desc': "addLine", 'type': "line", 'id': self.addLine}
     self.MapWindow.mouse['box'] = 'line'
예제 #46
0
                        continue
                    if name not in grassCmd:
                        grassCmd.add(name)
                        Debug.msg(3, "AddOn commands: %s", name)
                        nCmd += 1
                if ext == SCT_EXT and \
                        ext in grassScripts.keys() and \
                        name not in grassScripts[ext]:
                    grassScripts[ext].append(name)
            else:
                if fname not in grassCmd:
                    grassCmd.add(fname)
                    Debug.msg(3, "AddOn commands: %s", fname)
                    nCmd += 1

    Debug.msg(1, "Number of GRASS AddOn commands: %d", nCmd)


"""@brief Collected GRASS-relared binaries/scripts"""
grassCmd, grassScripts = get_commands()
Debug.msg(1, "Number of core GRASS commands: %d", len(grassCmd))
UpdateGRASSAddOnCommands()
"""@Toolbar icon size"""
toolbarSize = (24, 24)
"""@Check version of wxPython, use agwStyle for 2.8.11+"""
hasAgw = CheckWxVersion([2, 8, 11, 0])
wxPython3 = CheckWxVersion([3, 0, 0, 0])
"""@Add GUIDIR/scripts into path"""
os.environ['PATH'] = os.path.join(GUIDIR,
                                  'scripts') + os.pathsep + os.environ['PATH']
예제 #47
0
 def OnRemoveVertex(self, event):
     """Remove line vertex"""
     Debug.msg(2, "Digittoolbar.OnRemoveVertex():")
     self.action = {'desc': "removeVertex", 'id': self.removeVertex}
     self.MapWindow.mouse['box'] = 'point'
예제 #48
0
    def Render(self, cmdList, regions, regionFor3D, bgcolor, force, nprocs):
        """Renders all maps and stores files.

        :param cmdList: list of rendering commands to run
        :param regions: regions for 2D rendering assigned to commands
        :param regionFor3D: region for setting 3D view
        :param bgcolor: background color as a tuple of 3 values 0 to 255
        :param force: if True reload all data, otherwise only missing data
        :param nprocs: number of procs to be used for rendering
        """
        Debug.msg(3, "BitmapRenderer.Render")
        count = 0

        # Variables for parallel rendering
        proc_count = 0
        proc_list = []
        queue_list = []
        cmd_list = []

        filteredCmdList = []
        for cmd, region in zip(cmdList, regions):
            filename = GetFileFromCmd(self._tempDir, cmd, region)
            if not force and os.path.exists(
                    filename) and self._mapFilesPool.GetSize(
                        HashCmd(cmd, region)) == (self.imageWidth,
                                                  self.imageHeight):
                # for reference counting
                self._mapFilesPool[HashCmd(cmd, region)] = filename
                continue
            filteredCmdList.append((cmd, region))

        mapNum = len(filteredCmdList)
        stopped = False
        self._isRendering = True
        for cmd, region in filteredCmdList:
            count += 1

            # Queue object for interprocess communication
            q = Queue()
            # The separate render process
            if cmd[0] == 'm.nviz.image':
                p = Process(target=RenderProcess3D,
                            args=(self.imageWidth, self.imageHeight,
                                  self._tempDir, cmd, regionFor3D, bgcolor, q))
            else:
                p = Process(target=RenderProcess2D,
                            args=(self.imageWidth, self.imageHeight,
                                  self._tempDir, cmd, region, bgcolor, q))
            p.start()

            queue_list.append(q)
            proc_list.append(p)
            cmd_list.append((cmd, region))

            proc_count += 1
            # Wait for all running processes and read/store the created images
            if proc_count == nprocs or count == mapNum:
                for i in range(len(cmd_list)):
                    proc_list[i].join()
                    filename = queue_list[i].get()
                    self._mapFilesPool[HashCmd(cmd_list[i][0],
                                               cmd_list[i][1])] = filename
                    self._mapFilesPool.SetSize(
                        HashCmd(cmd_list[i][0], cmd_list[i][1]),
                        (self.imageWidth, self.imageHeight))

                proc_count = 0
                proc_list = []
                queue_list = []
                cmd_list = []

            self.renderingContinues.emit(current=count,
                                         text=_("Rendering map layers"))
            if self._stopRendering:
                self._stopRendering = False
                stopped = True
                break

        self._isRendering = False
        return not stopped
예제 #49
0
    def __init__(self, parent, title,
                 vectorName, query=None, cats=None,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
        """Dialog used to display/modify categories of vector objects

        :param parent:
        :param title: dialog title
        :param query: {coordinates, qdist} - used by v.edit/v.what
        :param cats: directory of lines (layer/categories) - used by vdigit
        :param style: dialog style
        """
        self.parent = parent  # map window class instance
        self.digit = parent.digit

        # map name
        self.vectorName = vectorName

        # line : {layer: [categories]}
        self.cats = {}

        # do not display dialog if no line is found (-> self.cats)
        if cats is None:
            if self._getCategories(query[0], query[1]) == 0 or not self.line:
                Debug.msg(3, "VDigitCategoryDialog(): nothing found!")
        else:
            self.cats = cats
            for line in cats.keys():
                for layer in cats[line].keys():
                    self.cats[line][layer] = list(cats[line][layer])

            layers = []
            for layer in self.digit.GetLayers():
                layers.append(str(layer))

        # make copy of cats (used for 'reload')
        self.cats_orig = copy.deepcopy(self.cats)

        wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY, title=title,
                           style=style, **kwargs)

        # list of categories
        box = wx.StaticBox(
            parent=self, id=wx.ID_ANY, label=" %s " %
            _("List of categories - right-click to delete"))
        listSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
        self.list = CategoryListCtrl(parent=self, id=wx.ID_ANY,
                                     style=wx.LC_REPORT |
                                     wx.BORDER_NONE |
                                     wx.LC_SORT_ASCENDING |
                                     wx.LC_HRULES |
                                     wx.LC_VRULES)
        # sorter
        self.fid = self.cats.keys()[0]
        self.itemDataMap = self.list.Populate(self.cats[self.fid])
        listmix.ColumnSorterMixin.__init__(self, 2)
        self.fidMulti = wx.Choice(parent=self, id=wx.ID_ANY,
                                  size=(150, -1))
        self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
        self.fidText = wx.StaticText(parent=self, id=wx.ID_ANY)
        if len(self.cats.keys()) == 1:
            self.fidMulti.Show(False)
            self.fidText.SetLabel(str(self.fid))
        else:
            self.fidText.Show(False)
            choices = []
            for fid in self.cats.keys():
                choices.append(str(fid))
            self.fidMulti.SetItems(choices)
            self.fidMulti.SetSelection(0)

        listSizer.Add(item=self.list, proportion=1, flag=wx.EXPAND)

        # add new category
        box = wx.StaticBox(parent=self, id=wx.ID_ANY,
                           label=" %s " % _("Add new category"))
        addSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
        flexSizer = wx.FlexGridSizer(cols=5, hgap=5, vgap=5)
        flexSizer.AddGrowableCol(3)

        layerNewTxt = wx.StaticText(parent=self, id=wx.ID_ANY,
                                    label="%s:" % _("Layer"))
        self.layerNew = wx.Choice(parent=self, id=wx.ID_ANY, size=(75, -1),
                                  choices=layers)
        if len(layers) > 0:
            self.layerNew.SetSelection(0)

        catNewTxt = wx.StaticText(parent=self, id=wx.ID_ANY,
                                  label="%s:" % _("Category"))

        try:
            newCat = max(self.cats[self.fid][1]) + 1
        except KeyError:
            newCat = 1
        self.catNew = SpinCtrl(parent=self, id=wx.ID_ANY, size=(75, -1),
                                  initial=newCat, min=0, max=1e9)
        btnAddCat = wx.Button(self, wx.ID_ADD)
        flexSizer.Add(item=layerNewTxt, proportion=0,
                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(item=self.layerNew, proportion=0,
                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(item=catNewTxt, proportion=0,
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
                      border=10)
        flexSizer.Add(item=self.catNew, proportion=0,
                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(item=btnAddCat, proportion=0,
                      flag=wx.EXPAND | wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
        addSizer.Add(
            item=flexSizer,
            proportion=1,
            flag=wx.ALL | wx.EXPAND,
            border=5)

        # buttons
        btnApply = wx.Button(self, wx.ID_APPLY)
        btnApply.SetToolTipString(_("Apply changes"))
        btnCancel = wx.Button(self, wx.ID_CANCEL)
        btnCancel.SetToolTipString(_("Ignore changes and close dialog"))
        btnOk = wx.Button(self, wx.ID_OK)
        btnOk.SetToolTipString(_("Apply changes and close dialog"))
        btnOk.SetDefault()

        # sizers
        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(btnCancel)
        # btnSizer.AddButton(btnReload)
        # btnSizer.SetNegativeButton(btnReload)
        btnSizer.AddButton(btnApply)
        btnSizer.AddButton(btnOk)
        btnSizer.Realize()

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(item=listSizer, proportion=1,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
        mainSizer.Add(item=addSizer, proportion=0,
                      flag=wx.EXPAND | wx.ALIGN_CENTER |
                      wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
        fidSizer = wx.BoxSizer(wx.HORIZONTAL)
        fidSizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY,
                                        label=_("Feature id:")),
                     proportion=0, border=5,
                     flag=wx.ALIGN_CENTER_VERTICAL)
        fidSizer.Add(item=self.fidMulti, proportion=0,
                     flag=wx.EXPAND | wx.ALL, border=5)
        fidSizer.Add(item=self.fidText, proportion=0,
                     flag=wx.EXPAND | wx.ALL, border=5)
        mainSizer.Add(item=fidSizer, proportion=0,
                      flag=wx.EXPAND | wx.ALL, border=5)
        mainSizer.Add(item=btnSizer, proportion=0,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)

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

        # set min size for dialog
        self.SetMinSize(self.GetBestSize())

        # bindings
        btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
        btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
        btnAddCat.Bind(wx.EVT_BUTTON, self.OnAddCat)
        btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
        self.Bind(wx.EVT_CLOSE, lambda evt: self.Hide())

        # list
        self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightUp)  # wxMSW
        self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)  # wxGTK
        self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list)
        self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit, self.list)
        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
예제 #50
0
    def Compose(self, cmdLists, regions, opacityList, bgcolor, force, nprocs):
        """Performs the composition of ppm/pgm files.

        :param cmdLists: lists of rendering commands lists to compose
        :param regions: regions for 2D rendering assigned to commands
        :param opacityList: list of lists of opacity values
        :param bgcolor: background color as a tuple of 3 values 0 to 255
        :param force: if True reload all data, otherwise only missing data
        :param nprocs: number of procs to be used for rendering
        """
        Debug.msg(3, "BitmapComposer.Compose")

        count = 0

        # Variables for parallel rendering
        proc_count = 0
        proc_list = []
        queue_list = []
        cmd_lists = []

        filteredCmdLists = []
        for cmdList, region in zip(cmdLists, regions):
            if not force and HashCmds(
                    cmdList,
                    region) in self._bitmapPool and self._bitmapPool[HashCmds(
                        cmdList, region)].GetSize() == (self.imageWidth,
                                                        self.imageHeight):
                # TODO: find a better way than to assign the same to increase
                # the reference
                self._bitmapPool[HashCmds(cmdList,
                                          region)] = self._bitmapPool[HashCmds(
                                              cmdList, region)]
                continue
            filteredCmdLists.append((cmdList, region))

        num = len(filteredCmdLists)

        self._isComposing = True
        for cmdList, region in filteredCmdLists:
            count += 1
            # Queue object for interprocess communication
            q = Queue()
            # The separate render process
            p = Process(target=CompositeProcess,
                        args=(self.imageWidth, self.imageHeight, self._tempDir,
                              cmdList, region, opacityList, bgcolor, q))
            p.start()

            queue_list.append(q)
            proc_list.append(p)
            cmd_lists.append((cmdList, region))

            proc_count += 1

            # Wait for all running processes and read/store the created images
            if proc_count == nprocs or count == num:
                for i in range(len(cmd_lists)):
                    proc_list[i].join()
                    filename = queue_list[i].get()
                    if filename is None:
                        self._bitmapPool[HashCmds(
                            cmd_lists[i][0],
                            cmd_lists[i][1])] = createNoDataBitmap(
                                self.imageWidth,
                                self.imageHeight,
                                text="Failed to render")
                    else:
                        self._bitmapPool[HashCmds(
                            cmd_lists[i][0],
                            cmd_lists[i][1])] = BitmapFromImage(
                                wx.Image(filename))
                        os.remove(filename)
                proc_count = 0
                proc_list = []
                queue_list = []
                cmd_lists = []

            self.compositionContinues.emit(current=count,
                                           text=_("Overlaying map layers"))
            if self._stopComposing:
                self._stopComposing = False
                break

        self._isComposing = False
예제 #51
0
    def RunCmd(self,
               command,
               compReg=True,
               env=None,
               skipInterface=False,
               onDone=None,
               onPrepare=None,
               userData=None,
               addLayer=None,
               notification=Notification.MAKE_VISIBLE):
        """Run command typed into console command prompt (GPrompt).

        .. todo::
            Document the other event.
        .. todo::
            Solve problem with the other event (now uses gOutputText
            event but there is no text, use onPrepare handler instead?)
        .. todo::
            Skip interface is ignored and determined always automatically.

        Posts event EVT_IGNORED_CMD_RUN when command which should be ignored
        (according to ignoredCmdPattern) is run.
        For example, see layer manager which handles d.* on its own.

        :param command: command given as a list (produced e.g. by utils.split())
        :param compReg: True use computation region
        :param notification: form of notification
        :param bool skipInterface: True to do not launch GRASS interface
                                   parser when command has no arguments
                                   given
        :param onDone: function to be called when command is finished
        :param onPrepare: function to be called before command is launched
        :param addLayer: to be passed in the mapCreated signal
        :param userData: data defined for the command
        """
        if len(command) == 0:
            Debug.msg(2, "GPrompt:RunCmd(): empty command")
            return

        # update history file
        self.UpdateHistoryFile(' '.join(command))

        if command[0] in globalvar.grassCmd:
            # send GRASS command without arguments to GUI command interface
            # except ignored commands (event is emitted)
            if self._ignoredCmdPattern and \
                    re.compile(self._ignoredCmdPattern).search(' '.join(command)) and \
                    '--help' not in command and '--ui' not in command:
                event = gIgnoredCmdRun(cmd=command)
                wx.PostEvent(self, event)
                return

            else:
                # other GRASS commands (r|v|g|...)
                try:
                    task = GUI(show=None).ParseCommand(command)
                except GException as e:
                    GError(parent=self._guiparent,
                           message=unicode(e),
                           showTraceback=False)
                    return

                hasParams = False
                if task:
                    options = task.get_options()
                    hasParams = options['params'] and options['flags']
                    # check for <input>=-
                    for p in options['params']:
                        if p.get('prompt', '') == 'input' and \
                                p.get('element', '') == 'file' and \
                                p.get('age', 'new') == 'old' and \
                                p.get('value', '') == '-':
                            GError(
                                parent=self._guiparent,
                                message=
                                _("Unable to run command:\n%(cmd)s\n\n"
                                  "Option <%(opt)s>: read from standard input is not "
                                  "supported by wxGUI") % {
                                      'cmd': ' '.join(command),
                                      'opt': p.get('name', '')
                                  })
                            return

                if len(command) == 1:
                    if command[0].startswith('g.gui.'):
                        import imp
                        import inspect
                        pyFile = command[0]
                        if sys.platform == 'win32':
                            pyFile += '.py'
                        pyPath = os.path.join(os.environ['GISBASE'], 'scripts',
                                              pyFile)
                        if not os.path.exists(pyPath):
                            pyPath = os.path.join(
                                os.environ['GRASS_ADDON_BASE'], 'scripts',
                                pyFile)
                        if not os.path.exists(pyPath):
                            GError(parent=self._guiparent,
                                   message=_("Module <%s> not found.") %
                                   command[0])
                        pymodule = imp.load_source(
                            command[0].replace('.', '_'), pyPath)
                        pymain = inspect.getargspec(pymodule.main)
                        if pymain and 'giface' in pymain.args:
                            pymodule.main(self._giface)
                            return

                    # no arguments given
                    if hasParams and \
                       not isinstance(self._guiparent, FormNotebook):
                        # also parent must be checked, see #3135 for details
                        try:
                            GUI(parent=self._guiparent,
                                giface=self._giface).ParseCommand(command)
                        except GException as e:
                            print(e, file=sys.stderr)

                        return

                if env:
                    env = env.copy()
                else:
                    env = os.environ.copy()
                # activate computational region (set with g.region)
                # for all non-display commands.
                if compReg and "GRASS_REGION" in env:
                    del env["GRASS_REGION"]

                # process GRASS command with argument
                self.cmdThread.RunCmd(command,
                                      stdout=self.cmdStdOut,
                                      stderr=self.cmdStdErr,
                                      onDone=onDone,
                                      onPrepare=onPrepare,
                                      userData=userData,
                                      addLayer=addLayer,
                                      env=env,
                                      notification=notification)
                self.cmdOutputTimer.Start(50)

                # we don't need to change computational region settings
                # because we work on a copy
        else:
            # Send any other command to the shell. Send output to
            # console output window
            #
            # Check if the script has an interface (avoid double-launching
            # of the script)

            # check if we ignore the command (similar to grass commands part)
            if self._ignoredCmdPattern and \
               re.compile(self._ignoredCmdPattern).search(' '.join(command)):
                event = gIgnoredCmdRun(cmd=command)
                wx.PostEvent(self, event)
                return

            skipInterface = True
            if os.path.splitext(command[0])[1] in ('.py', '.sh'):
                try:
                    sfile = open(command[0], "r")
                    for line in sfile.readlines():
                        if len(line) < 2:
                            continue
                        if line[0] is '#' and line[1] is '%':
                            skipInterface = False
                            break
                    sfile.close()
                except IOError:
                    pass

            if len(command) == 1 and not skipInterface:
                try:
                    task = gtask.parse_interface(command[0])
                except:
                    task = None
            else:
                task = None

            if task:
                # process GRASS command without argument
                GUI(parent=self._guiparent,
                    giface=self._giface).ParseCommand(command)
            else:
                self.cmdThread.RunCmd(command,
                                      stdout=self.cmdStdOut,
                                      stderr=self.cmdStdErr,
                                      onDone=onDone,
                                      onPrepare=onPrepare,
                                      userData=userData,
                                      addLayer=addLayer,
                                      env=env,
                                      notification=notification)
            self.cmdOutputTimer.Start(50)
예제 #52
0
 def RequestStopRendering(self):
     """Requests to stop rendering/composition"""
     Debug.msg(2, "BitmapProvider.RequestStopRendering")
     self._renderer.RequestStopRendering()
     self._composer.RequestStopComposing()
예제 #53
0
    def __init__(
        self,
        cmd,
        stdin=None,
        verbose=None,
        wait=True,
        rerr=False,
        stdout=None,
        stderr=None,
    ):
        """
        :param cmd: command given as list
        :param stdin: standard input stream
        :param verbose: verbose level [0, 3] (--q, --v)
        :param wait: wait for child execution terminated
        :param rerr: error handling (when GException raised).
                     True for redirection to stderr, False for GUI
                     dialog, None for no operation (quiet mode)
        :param stdout:  redirect standard output or None
        :param stderr:  redirect standard error output or None
        """
        Debug.msg(1, "gcmd.Command(): %s" % " ".join(cmd))
        self.cmd = cmd
        self.stderr = stderr

        #
        # set verbosity level
        #
        verbose_orig = None
        if ("--q" not in self.cmd and "--quiet" not in self.cmd) and (
            "--v" not in self.cmd and "--verbose" not in self.cmd
        ):
            if verbose is not None:
                if verbose == 0:
                    self.cmd.append("--quiet")
                elif verbose == 3:
                    self.cmd.append("--verbose")
                else:
                    verbose_orig = os.getenv("GRASS_VERBOSE")
                    os.environ["GRASS_VERBOSE"] = str(verbose)

        #
        # create command thread
        #
        self.cmdThread = CommandThread(cmd, stdin, stdout, stderr)
        self.cmdThread.start()

        if wait:
            self.cmdThread.join()
            if self.cmdThread.module:
                self.cmdThread.module.wait()
                self.returncode = self.cmdThread.module.returncode
            else:
                self.returncode = 1
        else:
            self.cmdThread.join(0.5)
            self.returncode = None

        if self.returncode is not None:
            Debug.msg(
                3,
                "Command(): cmd='%s', wait=%s, returncode=%d, alive=%s"
                % (" ".join(cmd), wait, self.returncode, self.cmdThread.isAlive()),
            )
            if rerr is not None and self.returncode != 0:
                if rerr is False:  # GUI dialog
                    raise GException(
                        "%s '%s'%s%s%s %s%s"
                        % (
                            _("Execution failed:"),
                            " ".join(self.cmd),
                            os.linesep,
                            os.linesep,
                            _("Details:"),
                            os.linesep,
                            _("Error: ") + self.__GetError(),
                        )
                    )
                elif rerr == sys.stderr:  # redirect message to sys
                    stderr.write("Execution failed: '%s'" % (" ".join(self.cmd)))
                    stderr.write(
                        "%sDetails:%s%s"
                        % (os.linesep, _("Error: ") + self.__GetError(), os.linesep)
                    )
            else:
                pass  # nop
        else:
            Debug.msg(
                3,
                "Command(): cmd='%s', wait=%s, returncode=?, alive=%s"
                % (" ".join(cmd), wait, self.cmdThread.isAlive()),
            )

        if verbose_orig:
            os.environ["GRASS_VERBOSE"] = verbose_orig
        elif "GRASS_VERBOSE" in os.environ:
            del os.environ["GRASS_VERBOSE"]
예제 #54
0
    def OnCmdDone(self, event):
        """Command done (or aborted)

        Sends signal mapCreated if map is recognized in output
        parameters or for specific modules (as r.colors).
        """
        # Process results here
        try:
            ctime = time.time() - event.time
            if ctime < 60:
                stime = _("%d sec") % int(ctime)
            else:
                mtime = int(ctime / 60)
                stime = _("%(min)d min %(sec)d sec") % {
                    'min': mtime,
                    'sec': int(ctime - (mtime * 60))
                }
        except KeyError:
            # stopped deamon
            stime = _("unknown")

        if event.aborted:
            # Thread aborted (using our convention of None return)
            self.WriteWarning(
                _('Please note that the data are left in'
                  ' inconsistent state and may be corrupted'))
            msg = _('Command aborted')
        else:
            msg = _('Command finished')

        self.WriteCmdLog('(%s) %s (%s)' % (str(time.ctime()), msg, stime),
                         notification=event.notification)

        if event.onDone:
            event.onDone(event)

        self.cmdOutputTimer.Stop()

        if event.cmd[0] == 'g.gisenv':
            Debug.SetLevel()
            self.Redirect()

        # do nothing when no map added
        if event.returncode != 0 or event.aborted:
            event.Skip()
            return

        if event.cmd[0] not in globalvar.grassCmd:
            return

        # find which maps were created
        try:
            task = GUI(show=None).ParseCommand(event.cmd)
        except GException as e:
            print(e, file=sys.stderr)
            task = None
            return

        name = task.get_name()
        for p in task.get_options()['params']:
            prompt = p.get('prompt', '')
            if prompt in ('raster', 'vector', 'raster_3d') and p.get(
                    'value', None):
                if p.get('age',
                         'old') == 'new' or name in ('r.colors', 'r3.colors',
                                                     'v.colors', 'v.proj',
                                                     'r.proj'):
                    # if multiple maps (e.g. r.series.interp), we need add each
                    if p.get('multiple', False):
                        lnames = p.get('value').split(',')
                        # in case multiple input (old) maps in r.colors
                        # we don't want to rerender it multiple times! just
                        # once
                        if p.get('age', 'old') == 'old':
                            lnames = lnames[0:1]
                    else:
                        lnames = [p.get('value')]
                    for lname in lnames:
                        if '@' not in lname:
                            lname += '@' + grass.gisenv()['MAPSET']
                        if grass.find_file(
                                lname, element=p.get('element'))['fullname']:
                            self.mapCreated.emit(name=lname,
                                                 ltype=prompt,
                                                 add=event.addLayer)
        if name == 'r.mask':
            self.updateMap.emit()

        event.Skip()
예제 #55
0
 def OnPaint(self, event):
     Debug.msg(5, "AnimationWindow.OnPaint()")
     # All that is needed here is to draw the buffer to screen
     dc = wx.BufferedPaintDC(self, self._Buffer)
     if self._overlay:
         self._pdc.DrawToDC(dc)
예제 #56
0
def RunCommand(
    prog,
    flags="",
    overwrite=False,
    quiet=False,
    verbose=False,
    parent=None,
    read=False,
    parse=None,
    stdin=None,
    getErrorMsg=False,
    env=None,
    **kwargs,
):
    """Run GRASS command

    :param prog: program to run
    :param flags: flags given as a string
    :param overwrite, quiet, verbose: flags
    :param parent: parent window for error messages
    :param read: fetch stdout
    :param parse: fn to parse stdout (e.g. grass.parse_key_val) or None
    :param stdin: stdin or None
    :param getErrorMsg: get error messages on failure
    :param env: environment (optional, uses os.environ if not provided)
    :param kwargs: program parameters

    The environment passed to the function (env or os.environ) is not modified (a copy is used internally).

    :return: returncode (read == False and getErrorMsg == False)
    :return: returncode, messages (read == False and getErrorMsg == True)
    :return: stdout (read == True and getErrorMsg == False)
    :return: returncode, stdout, messages (read == True and getErrorMsg == True)
    :return: stdout, stderr
    """
    cmdString = " ".join(
        grass.make_command(prog, flags, overwrite, quiet, verbose, **kwargs)
    )

    Debug.msg(1, "gcmd.RunCommand(): %s" % cmdString)

    kwargs["stderr"] = subprocess.PIPE

    if read:
        kwargs["stdout"] = subprocess.PIPE

    if stdin:
        kwargs["stdin"] = subprocess.PIPE

    # Do not change the environment, only a local copy.
    if env:
        env = env.copy()
    else:
        env = os.environ.copy()

    if parent:
        env["GRASS_MESSAGE_FORMAT"] = "standard"

    start = time.time()

    ps = grass.start_command(prog, flags, overwrite, quiet, verbose, env=env, **kwargs)

    if stdin:
        ps.stdin.write(encode(stdin))
        ps.stdin.close()
        ps.stdin = None

    stdout, stderr = ps.communicate()
    stderr = decode(stderr)
    stdout = decode(stdout) if read else stdout

    ret = ps.returncode
    Debug.msg(
        1,
        "gcmd.RunCommand(): get return code %d (%.6f sec)"
        % (ret, (time.time() - start)),
    )

    if ret != 0:
        if stderr:
            Debug.msg(2, "gcmd.RunCommand(): error %s" % stderr)
        else:
            Debug.msg(2, "gcmd.RunCommand(): nothing to print ???")

        if parent:
            GError(parent=parent, caption=_("Error in %s") % prog, message=stderr)

    if not read:
        if not getErrorMsg:
            return ret
        else:
            return ret, _formatMsg(stderr)

    if stdout:
        Debug.msg(3, "gcmd.RunCommand(): return stdout\n'%s'" % stdout)
    else:
        Debug.msg(3, "gcmd.RunCommand(): return stdout = None")

    if parse:
        stdout = parse(stdout)

    if not getErrorMsg:
        return stdout

    if read and getErrorMsg:
        return ret, stdout, _formatMsg(stderr)

    return stdout, _formatMsg(stderr)
예제 #57
0
 def StatusbarUpdate(self):
     """Update statusbar content"""
     if self.statusbarManager:
         Debug.msg(5, "MapFrameBase.StatusbarUpdate()")
         self.statusbarManager.Update()
예제 #58
0
 def OnPaint(self, event):
     Debug.msg(5, "BufferedWindow.OnPaint()")
     # All that is needed here is to draw the buffer to screen
     dc = wx.BufferedPaintDC(self, self._Buffer)
예제 #59
0
    def _initTreeItems(self, locations=None, mapsets=None):
        """Add locations, mapsets and layers to the tree.
        Runs in multiple processes. Saves resulting data and error."""
        # mapsets param currently unused
        genv = gisenv()
        if not locations:
            locations = GetListOfLocations(genv['GISDBASE'])

        loc_count = proc_count = 0
        queue_list = []
        proc_list = []
        loc_list = []
        nprocs = 4
        try:
            nprocs = cpu_count()
        except NotImplementedError:
            nprocs = 4

        results = dict()
        errors = []
        location_nodes = []
        nlocations = len(locations)
        grassdata_node = self._model.AppendNode(
            parent=self._model.root,
            label=_('GRASS locations in {0}').format(genv['GISDBASE']),
            data=dict(type='grassdata'))
        for location in locations:
            results[location] = dict()
            varloc = self._model.AppendNode(parent=grassdata_node,
                                            label=location,
                                            data=dict(type='location',
                                                      name=location))
            location_nodes.append(varloc)
            loc_count += 1

            Debug.msg(
                3, "Scanning location <{0}> ({1}/{2})".format(
                    location, loc_count, nlocations))

            q = Queue()
            p = Process(target=getLocationTree,
                        args=(genv['GISDBASE'], location, q))
            p.start()

            queue_list.append(q)
            proc_list.append(p)
            loc_list.append(location)

            proc_count += 1
            # Wait for all running processes
            if proc_count == nprocs or loc_count == nlocations:
                Debug.msg(4, "Process subresults")
                for i in range(len(loc_list)):
                    maps, error = queue_list[i].get()
                    proc_list[i].join()
                    if error:
                        errors.append(error)

                    for key in sorted(maps.keys()):
                        mapset_node = self._model.AppendNode(
                            parent=location_nodes[i],
                            label=key,
                            data=dict(type='mapset', name=key))
                        self._populateMapsetItem(mapset_node, maps[key])

                proc_count = 0
                proc_list = []
                queue_list = []
                loc_list = []
                location_nodes = []

        if errors:
            wx.CallAfter(GWarning, '\n'.join(errors))
        Debug.msg(1, "Tree filled")
        self.RefreshItems()
예제 #60
0
    def OnSize(self, event):
        Debug.msg(5, "AnimationWindow.OnSize()")

        BufferedWindow.OnSize(self, event)
        if event:
            event.Skip()