Example #1
0
    def SetType(self, ltype):
        """Set layer type"""
        if ltype not in utils.command2ltype.values() + ['overlay', 'command']:
            raise GException(_("Unsupported map layer type '%s'") % ltype)

        if ltype == 'wms' and not isinstance(self.renderMgr, RenderWMSMgr):
            self.renderMgr = RenderWMSMgr(layer=self,
                                          mapfile=self.mapfile,
                                          maskfile=self.maskfile)
        elif self.type == 'wms' and ltype != 'wms':
            self.renderMgr = None

        self.type = ltype
Example #2
0
    def SetType(self, ltype):
        """!Set layer type"""
        if ltype not in utils.command2ltype.values() + ["overlay", "command"]:
            raise GException(_("Unsupported map layer type '%s'") % ltype)

        if ltype == "wms" and not isinstance(self.renderMgr, RenderWMSMgr):
            self.renderMgr = RenderWMSMgr(
                receiver=self.Map.GetReceiver(),
                layer=self,
                Map=self.Map,
                mapfile=self.mapfile,
                maskfile=self.maskfile,
            )
        elif self.type == "wms" and ltype != "wms":
            self.renderMgr = None

        self.type = ltype
Example #3
0
class Layer(object):
    """Virtual class which stores information about layers (map layers and
    overlays) of the map composition.

    - For map layer use MapLayer class.
    - For overlays use Overlay class.
    """
    def __init__(self, ltype, cmd, Map, name=None,
                 active=True, hidden=False, opacity=1.0):
        """Create new instance

        .. todo::

            pass cmd as tuple instead of list

        :param ltype: layer type ('raster', 'vector', 'overlay', 'command', etc.)
        :param cmd: GRASS command to render layer, given as list,
                    e.g. ['d.rast', 'map=elevation@PERMANENT']
        :param map: render.Map instance
        :param name: layer name, e.g. 'elevation@PERMANENT' (for layer tree)
        :param active: layer is active, will be rendered only if True
        :param hidden: layer is hidden, won't be listed in Layer Manager if True
        :param float opacity: layer opacity <0;1>
        """

        # generated file for each layer
        if USE_GPNMCOMP or ltype == 'overlay':
            if ltype == 'overlay':
                tempfile_sfx = ".png"
            else:
                tempfile_sfx = ".ppm"

            mapfile = tempfile.NamedTemporaryFile(suffix=tempfile_sfx, delete=False)
            # we don't want it open, we just need the name
            self.mapfile = mapfile.name
            mapfile.close()
            self.maskfile = self.mapfile.rsplit(".",1)[0] + ".pgm"
        else:
            self.mapfile = self.maskfile = None

        # stores class which manages rendering instead of simple command - e.g. WMS
        self.renderMgr = None

        self.Map = Map
        self.type = None
        self.SetType(ltype)
        self.name = name
        self.environ = os.environ.copy()

        if self.type == 'command':
            self.cmd = list()
            for c in cmd:
                self.cmd.append(utils.CmdToTuple(c))
        else:
            self.cmd = utils.CmdToTuple(cmd)

        self.active  = active
        self.hidden  = hidden
        self.opacity = opacity

        self.forceRender = True

        Debug.msg (3, "Layer.__init__(): type=%s, cmd='%s', name=%s, " \
                       "active=%d, opacity=%d, hidden=%d" % \
                       (self.type, self.GetCmd(string=True), self.name,
                        self.active, self.opacity, self.hidden))

    def __del__(self):
        Debug.msg (3, "Layer.__del__(): layer=%s, cmd='%s'" %
                   (self.name, self.GetCmd(string = True)))

    def Render(self):
        """Render layer to image

        :return: rendered image filename
        :return: None on error or if cmdfile is defined
        """
        if not self.cmd:
            return None

        # ignore in 2D
        if self.type == '3d-raster':
            return None

        Debug.msg (3, "Layer.Render(): type=%s, name=%s" % \
                       (self.type, self.name))

        # prepare command for each layer
        layertypes = utils.command2ltype.values() + ['overlay', 'command']

        if self.type not in layertypes:
            raise GException(_("<%(name)s>: layer type <%(type)s> is not supported") % \
                                 {'type' : self.type, 'name' : self.name})

        if self.mapfile:
            self.environ["GRASS_PNGFILE"] = self.mapfile

        # execute command
        try:
            if self.type == 'command':
                read = False
                for c in self.cmd:
                    ret, msg = self._runCommand(c)
                    if ret != 0:
                        break
                    if not read:
                        self.environ["GRASS_PNG_READ"] = "TRUE"

                self.environ["GRASS_PNG_READ"] = "FALSE"
            else:
                ret, msg = self._runCommand(self.cmd)
            if ret != 0:
                sys.stderr.write(_("Command '%s' failed\n") % self.GetCmd(string = True))
                if msg:
                    sys.stderr.write(_("Details: %s\n") % msg)
                raise GException()

        except GException:
            # clean up after problems
            for f in [self.mapfile, self.maskfile]:
                if not f:
                    continue
                try_remove(f)
                f = None

        self.forceRender = False

        return self.mapfile

    def _runCommand(self, cmd):
        """Run command to render data
        """
        if self.type == 'wms':
            ret = 0
            msg = ''
            self.renderMgr.Render(cmd, env=self.environ)
        else:
            ret, msg = RunCommand(cmd[0],
                                  getErrorMsg = True,
                                  quiet = True,
                                  env=self.environ,
                                  **cmd[1])

        return ret, msg

    def GetCmd(self, string = False):
        """Get GRASS command as list of string.

        :param string: get command as string if True otherwise as list

        :return: command list/string
        """
        if string:
            if self.type == 'command':
                scmd = []
                for c in self.cmd:
                    scmd.append(utils.GetCmdString(c))

                return ';'.join(scmd)
            else:
                return utils.GetCmdString(self.cmd)
        else:
            return self.cmd

    def GetType(self):
        """Get map layer type"""
        return self.type

    def GetElement(self):
        """Get map element type"""
        if self.type == 'raster':
            return 'cell'
        return self.type

    def GetOpacity(self):
        """
        Get layer opacity level

        :return: opacity level (<0, 1>)
        """
        return self.opacity

    def GetName(self, fullyQualified = True):
        """Get map layer name

        :param bool fullyQualified: True to return fully qualified name
                                    as a string 'name@mapset' otherwise
                                    directory { 'name', 'mapset' } is
                                    returned

        :return: string / directory
        """
        if fullyQualified:
            return self.name
        else:
            if '@' in self.name:
                return { 'name' : self.name.split('@')[0],
                         'mapset' : self.name.split('@')[1] }
            else:
                return { 'name' : self.name,
                         'mapset' : '' }

    def IsActive(self):
        """Check if layer is activated for rendering"""
        return self.active

    def IsHidden(self):
        """Check if layer is hidden"""
        return self.hidden

    def SetType(self, ltype):
        """Set layer type"""
        if ltype not in utils.command2ltype.values() + ['overlay', 'command']:
            raise GException(_("Unsupported map layer type '%s'") % ltype)

        if ltype == 'wms' and not isinstance(self.renderMgr, RenderWMSMgr):
            self.renderMgr = RenderWMSMgr(layer=self,
                                          mapfile=self.mapfile,
                                          maskfile=self.maskfile)
        elif self.type == 'wms' and ltype != 'wms':
            self.renderMgr = None

        self.type = ltype

    def SetName(self, name):
        """Set layer name"""
        self.name = name

    def SetActive(self, enable = True):
        """Active or deactive layer"""
        self.active = bool(enable)

    def SetHidden(self, enable = False):
        """Hide or show map layer in Layer Manager"""
        self.hidden = bool(enable)

    def SetOpacity(self, value):
        """Set opacity value"""
        if value < 0:
            value = 0.
        elif value > 1:
            value = 1.

        self.opacity = float(value)

    def SetCmd(self, cmd):
        """Set new command for layer"""
        if self.type == 'command':
            self.cmd = []
            for c in cmd:
                self.cmd.append(utils.CmdToTuple(c))
        else:
            self.cmd = utils.CmdToTuple(cmd)
        Debug.msg(3, "Layer.SetCmd(): cmd='%s'" % self.GetCmd(string = True))

        # for re-rendering
        self.forceRender = True

    def SetEnvironment(self, environ):
        """Sets environment for rendering."""
        self.environ = environ

    def IsDownloading(self):
        """Is data downloading from web server e. g. wms"""
        if self.renderMgr is None:
            return False
        else:
            return self.renderMgr.IsDownloading()

    def AbortThread(self):
        """Abort running thread e. g. downloading data"""
        if self.renderMgr is None:
            return
        else:
            self.renderMgr.Abort()

    def GetRenderMgr(self):
        """Get render manager """
        return self.renderMgr
Example #4
0
class Layer(object):
    """!Virtual class which stores information about layers (map layers and
    overlays) of the map composition.

    - For map layer use MapLayer class.
    - For overlays use Overlay class.
    """

    def __init__(
        self, ltype, cmd, Map, name=None, active=True, hidden=False, opacity=1.0
    ):
        """!Create new instance

        @todo pass cmd as tuple instead of list

        @param ltype layer type ('raster', 'vector', 'overlay', 'command', etc.)
        @param cmd GRASS command to render layer,
        given as list, e.g. ['d.rast', 'map=elevation@PERMANENT']
        @param Map render.Map instance
        @param name layer name, e.g. 'elevation@PERMANENT' (for layer tree)
        @param active layer is active, will be rendered only if True
        @param hidden layer is hidden, won't be listed in Layer Manager if True
        @param opacity layer opacity <0;1>
        """

        # generated file for each layer
        if USE_GPNMCOMP or ltype == "overlay":
            tmpfile = tempfile.mkstemp()[1]
            self.maskfile = tmpfile + ".pgm"
            if ltype == "overlay":
                self.mapfile = tmpfile + ".png"
            else:
                self.mapfile = tmpfile + ".ppm"
            grass.try_remove(tmpfile)
        else:
            self.mapfile = self.maskfile = None

        # stores class which manages rendering instead of simple command - e. g. wms
        self.renderMgr = None

        self.Map = Map
        self.type = None
        self.SetType(ltype)
        self.name = name

        if self.type == "command":
            self.cmd = list()
            for c in cmd:
                self.cmd.append(utils.CmdToTuple(c))
        else:
            self.cmd = utils.CmdToTuple(cmd)

        self.active = active
        self.hidden = hidden
        self.opacity = opacity

        self.forceRender = True

        Debug.msg(
            3,
            "Layer.__init__(): type=%s, cmd='%s', name=%s, "
            "active=%d, opacity=%d, hidden=%d"
            % (
                self.type,
                self.GetCmd(string=True),
                self.name,
                self.active,
                self.opacity,
                self.hidden,
            ),
        )

    def __del__(self):
        Debug.msg(
            3,
            "Layer.__del__(): layer=%s, cmd='%s'"
            % (self.name, self.GetCmd(string=True)),
        )

    def Render(self):
        """!Render layer to image

        @return rendered image filename
        @return None on error or if cmdfile is defined
        """
        if not self.cmd:
            return None

        # ignore in 2D
        if self.type == "3d-raster":
            return None

        Debug.msg(3, "Layer.Render(): type=%s, name=%s" % (self.type, self.name))

        # prepare command for each layer
        layertypes = utils.command2ltype.values() + ["overlay", "command"]

        if self.type not in layertypes:
            raise GException(
                _("<%(name)s>: layer type <%(type)s> is not supported")
                % {"type": self.type, "name": self.name}
            )

        if self.mapfile:
            os.environ["GRASS_RENDER_FILE"] = self.mapfile

        # execute command
        try:
            if self.type == "command":
                read = False
                for c in self.cmd:
                    ret, msg = self._runCommand(c)
                    if ret != 0:
                        break
                    if not read:
                        os.environ["GRASS_RENDER_FILE_READ"] = "TRUE"

                os.environ["GRASS_RENDER_FILE_READ"] = "FALSE"
            else:
                ret, msg = self._runCommand(self.cmd)
            if ret != 0:
                sys.stderr.write(_("Command '%s' failed\n") % self.GetCmd(string=True))
                if msg:
                    sys.stderr.write(_("Details: %s\n") % msg)
                raise GException()

        except GException:
            # clean up after problems
            for f in [self.mapfile, self.maskfile]:
                if not f:
                    continue
                grass.try_remove(f)
                f = None

        # stop monitor
        if self.mapfile and "GRASS_RENDER_FILE" in os.environ:
            del os.environ["GRASS_RENDER_FILE"]

        self.forceRender = False

        return self.mapfile

    def _runCommand(self, cmd):
        """!Run command to render data"""
        if self.type == "wms":
            ret = 0
            msg = ""
            self.renderMgr.Render(cmd)
        else:
            ret, msg = RunCommand(cmd[0], getErrorMsg=True, quiet=True, **cmd[1])

        return ret, msg

    def GetCmd(self, string=False):
        """!Get GRASS command as list of string.

        @param string get command as string if True otherwise as list

        @return command list/string
        """
        if string:
            if self.type == "command":
                scmd = []
                for c in self.cmd:
                    scmd.append(utils.GetCmdString(c))

                return ";".join(scmd)
            else:
                return utils.GetCmdString(self.cmd)
        else:
            return self.cmd

    def GetType(self):
        """!Get map layer type"""
        return self.type

    def GetElement(self):
        """!Get map element type"""
        if self.type == "raster":
            return "cell"
        return self.type

    def GetOpacity(self, float=False):
        """
        Get layer opacity level

        @param float get opacity level in <0,1> otherwise <0,100>

        @return opacity level
        """
        if float:
            return self.opacity

        return int(self.opacity * 100)

    def GetName(self, fullyQualified=True):
        """!Get map layer name

        @param fullyQualified True to return fully qualified name as a
        string 'name@mapset' otherwise directory { 'name', 'mapset' }
        is returned

        @return string / directory
        """
        if fullyQualified:
            return self.name
        else:
            if "@" in self.name:
                return {
                    "name": self.name.split("@")[0],
                    "mapset": self.name.split("@")[1],
                }
            else:
                return {"name": self.name, "mapset": ""}

    def IsActive(self):
        """!Check if layer is activated for rendering"""
        return self.active

    def SetType(self, ltype):
        """!Set layer type"""
        if ltype not in utils.command2ltype.values() + ["overlay", "command"]:
            raise GException(_("Unsupported map layer type '%s'") % ltype)

        if ltype == "wms" and not isinstance(self.renderMgr, RenderWMSMgr):
            self.renderMgr = RenderWMSMgr(
                receiver=self.Map.GetReceiver(),
                layer=self,
                Map=self.Map,
                mapfile=self.mapfile,
                maskfile=self.maskfile,
            )
        elif self.type == "wms" and ltype != "wms":
            self.renderMgr = None

        self.type = ltype

    def SetName(self, name):
        """!Set layer name"""
        self.name = name

    def SetActive(self, enable=True):
        """!Active or deactive layer"""
        self.active = bool(enable)

    def SetHidden(self, enable=False):
        """!Hide or show map layer in Layer Manager"""
        self.hidden = bool(enable)

    def SetOpacity(self, value):
        """!Set opacity value"""
        if value < 0:
            value = 0.0
        elif value > 1:
            value = 1.0

        self.opacity = float(value)

    def SetCmd(self, cmd):
        """!Set new command for layer"""
        if self.type == "command":
            self.cmd = []
            for c in cmd:
                self.cmd.append(utils.CmdToTuple(c))
        else:
            self.cmd = utils.CmdToTuple(cmd)
        Debug.msg(3, "Layer.SetCmd(): cmd='%s'" % self.GetCmd(string=True))

        # for re-rendering
        self.forceRender = True

    def IsDownloading(self):
        """!Is data downloading from web server e. g. wms"""
        if self.renderMgr is None:
            return False
        else:
            return self.renderMgr.IsDownloading()

    def AbortThread(self):
        """!Abort running thread e. g. downloading data"""
        if self.renderMgr is None:
            return
        else:
            self.renderMgr.Abort()

    def GetRenderMgr(self):
        """!Get render manager"""
        return self.renderMgr