예제 #1
0
    def GetLayersFromCmdFile(self):
        """Get list of map layers from cmdfile
        """
        if not self.cmdfile:
            return

        nlayers = 0
        try:
            fd = open(self.cmdfile, 'r')
            lines = fd.readlines()
            fd.close()
            # detect d.out.file, delete the line from the cmd file and export
            # graphics
            if len(lines) > 0:
                if lines[-1].startswith('d.out.file') or \
                   lines[-1].startswith('d.to.rast'):
                    dCmd = lines[-1].strip()
                    fd = open(self.cmdfile, 'w')
                    fd.writelines(lines[:-1])
                    fd.close()
                    if lines[-1].startswith('d.out.file'):
                        self.saveToFile.emit(cmd=utils.split(dCmd))
                    else:
                        self.dToRast.emit(cmd=utils.split(dCmd))
                    return
                if lines[-1].startswith('d.what'):
                    dWhatCmd = lines[-1].strip()
                    fd = open(self.cmdfile, 'w')
                    fd.writelines(lines[:-1])
                    fd.close()
                    if '=' in utils.split(dWhatCmd)[1]:
                        maps = utils.split(dWhatCmd)[1].split('=')[1].split(
                            ',')
                    else:
                        maps = utils.split(dWhatCmd)[1].split(',')
                    self.query.emit(
                        ltype=utils.split(dWhatCmd)[0].split('.')[-1],
                        maps=maps)
                    return
            else:
                # clean overlays after erase
                self.oldOverlays = []
                overlays = list(
                    self._giface.GetMapDisplay().decorations.keys())
                for each in overlays:
                    self._giface.GetMapDisplay().RemoveOverlay(each)

            existingLayers = self.GetListOfLayers()

            # holds new rendreing order for every layer in existingLayers
            layersOrder = [-1] * len(existingLayers)

            # next number in rendering order
            next_layer = 0
            mapFile = None
            render_env = dict()
            for line in lines:
                if line.startswith('#'):
                    if 'GRASS_RENDER_FILE' in line:
                        mapFile = line.split('=', 1)[1].strip()
                    try:
                        k, v = line[2:].strip().split('=', 1)
                    except:
                        pass
                    render_env[k] = v
                    continue

                cmd = utils.split(line.strip())

                ltype = None
                try:
                    ltype = utils.command2ltype[cmd[0]]
                except KeyError:
                    grass.warning(_("Unsupported command %s.") % cmd[0])
                    continue

                name = utils.GetLayerNameFromCmd(cmd,
                                                 fullyQualified=True,
                                                 layerType=ltype)[0]

                args = {}

                if ltype in ('barscale', 'rastleg', 'northarrow', 'text',
                             'vectleg'):
                    # TODO: this is still not optimal
                    # it is there to prevent adding the same overlay multiple times
                    if cmd in self.oldOverlays:
                        continue
                    if ltype == 'rastleg':
                        self._giface.GetMapDisplay().AddLegendRast(cmd=cmd)
                    elif ltype == 'barscale':
                        self._giface.GetMapDisplay().AddBarscale(cmd=cmd)
                    elif ltype == 'northarrow':
                        self._giface.GetMapDisplay().AddArrow(cmd=cmd)
                    elif ltype == 'text':
                        self._giface.GetMapDisplay().AddDtext(cmd=cmd)
                    elif ltype == 'vectleg':
                        self._giface.GetMapDisplay().AddLegendVect(cmd=cmd)
                    self.oldOverlays.append(cmd)
                    continue

                classLayer = MapLayer
                args['ltype'] = ltype

                exists = False
                for i, layer in enumerate(existingLayers):
                    if layer.GetCmd(string=True) == utils.GetCmdString(
                            cmdlist_to_tuple(cmd)):
                        exists = True

                        if layersOrder[i] == -1:
                            layersOrder[i] = next_layer
                            next_layer += 1
                        # layer must be put higher in render order (same cmd was insered more times)
                        # TODO delete rendurant cmds from cmd file?
                        else:
                            for j, l_order in enumerate(layersOrder):
                                if l_order > layersOrder[i]:
                                    layersOrder[j] -= 1
                            layersOrder[i] = next_layer - 1

                        break
                if exists:
                    continue

                mapLayer = classLayer(name=name,
                                      cmd=cmd,
                                      Map=None,
                                      hidden=True,
                                      render=False,
                                      mapfile=mapFile,
                                      **args)
                mapLayer.GetRenderMgr().updateProgress.connect(
                    self.GetRenderMgr().ReportProgress)
                if render_env:
                    mapLayer.GetRenderMgr().UpdateRenderEnv(render_env)
                    render_env = dict()

                newLayer = self._addLayer(mapLayer)

                existingLayers.append(newLayer)
                self.ownedLayers.append(newLayer)

                layersOrder.append(next_layer)
                next_layer += 1

                nlayers += 1

            reorderedLayers = [-1] * next_layer
            for i, layer in enumerate(existingLayers):

                # owned layer was not found in cmd file -> is deleted
                if layersOrder[i] == -1 and layer in self.ownedLayers:
                    self.ownedLayers.remove(layer)
                    self.DeleteLayer(layer)

                # other layer e. g. added by wx.vnet are added to the top
                elif layersOrder[i] == -1 and layer not in self.ownedLayers:
                    reorderedLayers.append(layer)

                # owned layer found in cmd file is added into proper rendering
                # position
                else:
                    reorderedLayers[layersOrder[i]] = layer

            self.SetLayers(reorderedLayers)

        except IOError as e:
            grass.warning(
                _("Unable to read cmdfile '%(cmd)s'. Details: %(det)s") % {
                    'cmd': self.cmdfile,
                    'det': e
                })
            return

        Debug.msg(
            1, "Map.GetLayersFromCmdFile(): cmdfile=%s, nlayers=%d" %
            (self.cmdfile, nlayers))

        self._giface.updateMap.emit(render=False)
예제 #2
0
    def GetLayersFromCmdFile(self):
        """Get list of map layers from cmdfile
        """
        if not self.cmdfile:
            return

        nlayers = 0

        try:
            fd = open(self.cmdfile, 'r')
            lines = fd.readlines()
            fd.close()
            # detect d.out.file, delete the line from the cmd file and export graphics
            if len(lines) > 0:
                if lines[-1].startswith('d.out.file') or lines[-1].startswith(
                        'd.to.rast'):
                    dCmd = lines[-1].strip()
                    fd = open(self.cmdfile, 'w')
                    fd.writelines(lines[:-1])
                    fd.close()
                    if lines[-1].startswith('d.out.file'):
                        self.saveToFile.emit(cmd=utils.split(dCmd))
                    else:
                        self.dToRast.emit(cmd=utils.split(dCmd))
                    return
                if lines[-1].startswith('d.what'):
                    dWhatCmd = lines[-1].strip()
                    fd = open(self.cmdfile, 'w')
                    fd.writelines(lines[:-1])
                    fd.close()
                    if '=' in utils.split(dWhatCmd)[1]:
                        maps = utils.split(dWhatCmd)[1].split('=')[1].split(
                            ',')
                    else:
                        maps = utils.split(dWhatCmd)[1].split(',')
                    self.query.emit(
                        ltype=utils.split(dWhatCmd)[0].split('.')[-1],
                        maps=maps)
                    return

            existingLayers = self.GetListOfLayers()

            # holds new rendreing order for every layer in existingLayers
            layersOrder = [-1] * len(self.GetListOfLayers())

            # next number in rendering order
            next_layer = 0

            for line in lines:
                cmd = utils.split(line.strip())
                ltype = None

                try:
                    ltype = utils.command2ltype[cmd[0]]
                except KeyError:
                    grass.warning(_("Unsupported command %s.") % cmd[0])
                    continue

                name = utils.GetLayerNameFromCmd(cmd,
                                                 fullyQualified=True,
                                                 layerType=ltype)[0]

                # creating temporary layer object to compare commands
                # neccessary to get the same format
                # supposing that there are no side effects
                tmpMapLayer = MapLayer(ltype=ltype,
                                       name=name,
                                       cmd=cmd,
                                       Map=None,
                                       active=False,
                                       hidden=True,
                                       opacity=0)
                exists = False
                for i, layer in enumerate(existingLayers):
                    if layer.GetCmd(string=True) == tmpMapLayer.GetCmd(
                            string=True):
                        exists = True

                        if layersOrder[i] == -1:
                            layersOrder[i] = next_layer
                            next_layer += 1
                        # layer must be put higher in render order (same cmd was insered more times)
                        # TODO delete rendurant cmds from cmd file?
                        else:
                            for j, l_order in enumerate(layersOrder):
                                if l_order > layersOrder[i]:
                                    layersOrder[j] -= 1
                            layersOrder[i] = next_layer - 1

                        break
                if exists:
                    continue

                newLayer = Map.AddLayer(self,
                                        ltype=ltype,
                                        command=cmd,
                                        active=True,
                                        name=name)

                existingLayers.append(newLayer)
                self.ownedLayers.append(newLayer)

                layersOrder.append(next_layer)
                next_layer += 1

                nlayers += 1

            reorderedLayers = [-1] * next_layer
            for i, layer in enumerate(existingLayers):

                # owned layer was not found in cmd file -> is deleted
                if layersOrder[i] == -1 and layer in self.ownedLayers:
                    self.ownedLayers.remove(layer)
                    self.DeleteLayer(layer)

                # other layer e. g. added by wx.vnet are added to the top
                elif layersOrder[i] == -1 and layer not in self.ownedLayers:
                    reorderedLayers.append(layer)

                # owned layer found in cmd file is added into proper rendering position
                else:
                    reorderedLayers[layersOrder[i]] = layer

            self.SetLayers(reorderedLayers)

        except IOError as e:
            grass.warning(_("Unable to read cmdfile '%(cmd)s'. Details: %(det)s") % \
                              { 'cmd' : self.cmdfile, 'det' : e })
            return

        self._giface.updateMap.emit()

        Debug.msg(1, "Map.GetLayersFromCmdFile(): cmdfile=%s" % self.cmdfile)
        Debug.msg(1, "                            nlayers=%d" % nlayers)