Beispiel #1
0
def CompositeProcess(imageWidth, imageHeight, tempDir, cmdList, region,
                     opacities, bgcolor, fileQueue):
    """Performs the composition of image ppm files and writes the
       resulting ppm filename in the provided file queue

    :param imageWidth: image width
    :param imageHeight: image height
    :param tempDir: directory for rendering
    :param cmdList: list of d.rast/d.vect commands
    :param region: region as a dict or None
    :param opacites: list of opacities
    :param bgcolor: background color as a tuple of 3 values 0 to 255
    :param fileQueue: the inter process communication queue
                      storing the file name of the image
    """

    maps = []
    masks = []
    for cmd in cmdList:
        maps.append(GetFileFromCmd(tempDir, cmd, region))
        masks.append(GetFileFromCmd(tempDir, cmd, region, "pgm"))
    filename = GetFileFromCmds(tempDir, cmdList, region)
    # Set the environment variables for this process
    _setEnvironment(imageWidth,
                    imageHeight,
                    filename,
                    transparent=False,
                    bgcolor=bgcolor)

    opacities = [str(op) for op in opacities]
    bgcolor = ":".join([str(part) for part in bgcolor])
    returncode, stdout, messages = read2_command(
        "g.pnmcomp",
        overwrite=True,
        input="%s" % ",".join(reversed(maps)),
        mask="%s" % ",".join(reversed(masks)),
        opacity="%s" % ",".join(reversed(opacities)),
        bgcolor=bgcolor,
        width=imageWidth,
        height=imageHeight,
        output=filename,
    )

    if returncode != 0:
        gcore.warning("Rendering composite failed:\n" + messages)
        fileQueue.put(None)
        os.remove(filename)
        return

    fileQueue.put(filename)
Beispiel #2
0
def RenderProcess3D(imageWidth, imageHeight, tempDir, cmd, region, bgcolor, fileQueue):
    """Renders image with m.nviz.image and writes the
       resulting ppm filename in the provided file queue

    :param imageWidth: image width
    :param imageHeight: image height
    :param tempDir: directory for rendering
    :param cmd: m.nviz.image command as a list
    :param region: region as a dict
    :param bgcolor: background color as a tuple of 3 values 0 to 255
    :param fileQueue: the inter process communication queue
                      storing the file name of the image
    """

    filename = GetFileFromCmd(tempDir, cmd, None)
    os.environ["GRASS_REGION"] = gcore.region_env(region3d=True, **region)
    Debug.msg(1, "Render image to file " + str(filename))

    cmdTuple = cmdlist_to_tuple(cmd)
    cmdTuple[1]["output"] = os.path.splitext(filename)[0]
    # set size
    cmdTuple[1]["size"] = "%d,%d" % (imageWidth, imageHeight)
    # set format
    cmdTuple[1]["format"] = "ppm"
    cmdTuple[1]["bgcolor"] = bgcolor = ":".join([str(part) for part in bgcolor])
    returncode, stdout, messages = read2_command(cmdTuple[0], **cmdTuple[1])
    if returncode != 0:
        gcore.warning("Rendering failed:\n" + messages)
        fileQueue.put(None)
        os.environ.pop("GRASS_REGION")
        return

    os.environ.pop("GRASS_REGION")
    fileQueue.put(filename)
Beispiel #3
0
def RenderProcess2D(imageWidth, imageHeight, tempDir, cmd, region, bgcolor, fileQueue):
    """Render raster or vector files as ppm image and write the
       resulting ppm filename in the provided file queue

    :param imageWidth: image width
    :param imageHeight: image height
    :param tempDir: directory for rendering
    :param cmd: d.rast/d.vect command as a list
    :param region: region as a dict or None
    :param bgcolor: background color as a tuple of 3 values 0 to 255
    :param fileQueue: the inter process communication queue
                      storing the file name of the image
    """

    filename = GetFileFromCmd(tempDir, cmd, region)
    transparency = True

    # Set the environment variables for this process
    _setEnvironment(imageWidth, imageHeight, filename,
                    transparent=transparency, bgcolor=bgcolor)
    if region:
        os.environ['GRASS_REGION'] = gcore.region_env(**region)
    cmdTuple = CmdToTuple(cmd)
    returncode, stdout, messages = read2_command(cmdTuple[0], **cmdTuple[1])
    if returncode != 0:
        gcore.warning("Rendering failed:\n" + messages)
        fileQueue.put(None)
        if region:
            os.environ.pop('GRASS_REGION')
        os.remove(filename)
        return

    if region:
        os.environ.pop('GRASS_REGION')
    fileQueue.put(filename)
Beispiel #4
0
    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()
Beispiel #5
0
    def _dryRender(self, uniqueCmds, regions, force):
        """Determines how many files will be rendered.

        :param uniqueCmds: list of commands which are to be rendered
        :param force: if forced rerendering
        :param regions: list of regions assigned to the commands
        """
        count = 0
        for cmd, region in zip(uniqueCmds, 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):
                continue
            count += 1

        Debug.msg(3, "BitmapProvider._dryRender: {c} files to be rendered".format(c=count))

        return count
Beispiel #6
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):
            if cmd[0] == "m.nviz.image":
                region = None
            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