Exemplo n.º 1
0
 def clear():
     with block_signals_to(self.QCBox_ThematicFile):
         self.QCBox_ThematicFile.setCurrentIndex(-1)
     self.render_widget.canvas.setLayers([])
     self.render_widget.refresh()
     self.PixelTable.clear()
     self.PixelTable.setRowCount(0)
     self.PixelTable.setColumnCount(0)
     with block_signals_to(self.QCBox_band_ThematicFile):
         self.QCBox_band_ThematicFile.clear()
Exemplo n.º 2
0
 def disable(self):
     with block_signals_to(self.render_widget):
         # deactivate some parts of this view
         self.layerStyleEditor.setDisabled(True)
         self.layerOpacity.setDisabled(True)
         # set status for view widget
         self.is_active = False
         self.parent_view.update()
Exemplo n.º 3
0
    def select_thematic_file_classes(self, layer):
        def clear():
            with block_signals_to(self.QCBox_ThematicFile):
                self.QCBox_ThematicFile.setCurrentIndex(-1)
            self.render_widget.canvas.setLayers([])
            self.render_widget.refresh()
            self.PixelTable.clear()
            self.PixelTable.setRowCount(0)
            self.PixelTable.setColumnCount(0)
            with block_signals_to(self.QCBox_band_ThematicFile):
                self.QCBox_band_ThematicFile.clear()

        if not layer:
            clear()
            return

        if layer.crs() != LayerToEdit.current.qgs_layer.crs():
            self.MsgBar.pushMessage(
                "The selected file \"{}\" doesn't have the same coordinate system with respect to "
                "the thematic layer to edit \"{}\"".format(
                    layer.name(), LayerToEdit.current.qgs_layer.name()),
                level=Qgis.Critical,
                duration=20)
            clear()
            return

        if (round(layer.rasterUnitsPerPixelX(), 3) != round(
                LayerToEdit.current.qgs_layer.rasterUnitsPerPixelX(), 3)
                or round(layer.rasterUnitsPerPixelY(), 3) != round(
                    LayerToEdit.current.qgs_layer.rasterUnitsPerPixelY(), 3)):
            self.MsgBar.pushMessage(
                "The selected file \"{}\" doesn't have the same pixel size with respect to "
                "the thematic layer to edit \"{}\"".format(
                    layer.name(), LayerToEdit.current.qgs_layer.name()),
                level=Qgis.Critical,
                duration=20)
            clear()
            return

        self.render_widget.canvas.setDestinationCrs(layer.crs())
        self.render_widget.canvas.setLayers([layer])
        self.render_widget.canvas.setExtent(layer.extent())
        self.render_widget.refresh()
        self.thematic_file_classes = layer

        # set band count
        with block_signals_to(self.QCBox_band_ThematicFile):
            self.QCBox_band_ThematicFile.clear()
            self.QCBox_band_ThematicFile.addItems([
                str(x)
                for x in range(1,
                               self.thematic_file_classes.bandCount() + 1)
            ])

        self.setup_thematic_file_classes()
Exemplo n.º 4
0
    def highlight_value_in_recode_pixel_table(self, value_to_select):
        """Highlight the current pixel value from mouse pointer on canvas"""
        from ThRasE.thrase import ThRasE
        if value_to_select is None:
            ThRasE.dialog.recodePixelTable.clearSelection()
            with block_signals_to(ThRasE.dialog.recodePixelTable):
                [ThRasE.dialog.recodePixelTable.item(idx, 2).setBackground(Qt.white) for idx in range(len(self.pixels))]
            return

        row_idx = next((idx for idx, i in enumerate(self.pixels) if i["value"] == value_to_select), None)
        if row_idx is not None:
            # select
            ThRasE.dialog.recodePixelTable.setCurrentCell(row_idx, 2)
            # set background
            with block_signals_to(ThRasE.dialog.recodePixelTable):
                [ThRasE.dialog.recodePixelTable.item(idx, 2).setBackground(Qt.white) for idx in range(len(self.pixels))]
                ThRasE.dialog.recodePixelTable.item(row_idx, 2).setBackground(Qt.yellow)
        else:
            ThRasE.dialog.recodePixelTable.clearSelection()
            with block_signals_to(ThRasE.dialog.recodePixelTable):
                [ThRasE.dialog.recodePixelTable.item(idx, 2).setBackground(Qt.white) for idx in range(len(self.pixels))]
Exemplo n.º 5
0
    def update_render_layers(self):
        with block_signals_to(self):
            # set the CRS of the canvas view
            if self.crs:
                # use the crs of thematic raster to edit
                self.canvas.setDestinationCrs(self.crs)
            else:
                # use the crs set in Qgis
                self.canvas.setDestinationCrs(
                    iface.mapCanvas().mapSettings().destinationCrs())
            # get all valid activated layers
            valid_layers = [
                active_layer.layer for active_layer in self.active_layers
                if active_layer.is_active
            ]
            if len(valid_layers) == 0:
                self.canvas.setLayers([])
                self.refresh()
                return
            # set to canvas
            self.canvas.setLayers(valid_layers)
            # set init extent from other view if any is activated else set layer extent
            from ThRasE.gui.main_dialog import ThRasEDialog
            others_extents = [
                view_widget.render_widget.canvas.extent()
                for view_widget in ThRasEDialog.view_widgets
                if view_widget.is_active and view_widget.render_widget != self
                and not view_widget.render_widget.canvas.extent().isEmpty()
            ]
            if others_extents:
                # set extent using the extent of the other valid view (or self) with at least one layer
                extent = others_extents[0]
                self.update_canvas_to(extent)
            elif self.canvas.extent().isEmpty():
                # first layer to render
                # set the extent using the extent of the Qgis project but first transform the crs if it is different
                new_layer = valid_layers[0]
                transform = QgsCoordinateTransform(
                    new_layer.crs(),
                    self.canvas.mapSettings().destinationCrs(),
                    QgsProject.instance())
                new_extent = transform.transformBoundingBox(new_layer.extent())
                self.canvas.setExtent(new_extent)

            self.refresh()
Exemplo n.º 6
0
    def highlight(self, idx_tile=None):
        if idx_tile:  # from slider
            with block_signals_to(self.currentTile):
                self.currentTile.setValue(idx_tile)

        if idx_tile:
            tile = next((tile for tile in self.layer_to_edit.navigation.tiles
                         if tile.idx == idx_tile), None)
        else:
            tile = self.layer_to_edit.navigation.current_tile

        # unhighlight the before tile (rubber band)
        if self.highlight_tile:
            self.highlight_tile.reset(QgsWkbTypes.PolygonGeometry)

        self.highlight_tile = tile.create(self.render_widget.canvas,
                                          line_width=6,
                                          rbs_in="highlight")
Exemplo n.º 7
0
    def update_layer_opacity(self, opacity=None):
        if opacity is None:
            opacity = self.layerOpacity.value()

        if self.layer:
            if self.layer.type() == QgsMapLayer.VectorLayer:
                self.layer.setOpacity(opacity/100.0)
            else:
                self.layer.renderer().setOpacity(opacity/100.0)
            if hasattr(self.layer, "setCacheImage"):
                self.layer.setCacheImage(None)
            self.layer.triggerRepaint()

            from ThRasE.gui.main_dialog import ThRasEDialog
            same_layer_in_others_active_layer = \
                [active_layer for active_layer in [al for als in [view_widget.active_layers for view_widget in ThRasEDialog.view_widgets] for al in als]
                 if active_layer != self and active_layer.layer == self.layer]

            for active_layer in same_layer_in_others_active_layer:
                with block_signals_to(active_layer.layerOpacity):
                    active_layer.layerOpacity.setValue(opacity)

            self.opacity = opacity
Exemplo n.º 8
0
    def apply(self):
        pixel_table = self.PixelTable
        classes_selected = [
            int(pixel_table.item(row_idx, 1).text())
            for row_idx in range(len(self.pixel_classes))
            if pixel_table.item(row_idx, 2).checkState() == 2
        ]

        if not classes_selected:
            self.MsgBar.pushMessage(
                "Error, none of the class was selected to apply",
                level=Qgis.Warning)
            return

        extent_intercepted = LayerToEdit.current.qgs_layer.extent().intersect(
            self.thematic_file_classes.extent())

        ps_x = self.thematic_file_classes.rasterUnitsPerPixelX(
        )  # pixel size in x
        ps_y = self.thematic_file_classes.rasterUnitsPerPixelY(
        )  # pixel size in y

        # locate the pixel centroid in x and y for the pixel in min/max in the extent
        y_min = extent_intercepted.yMinimum() + (ps_y / 2.0)
        y_max = extent_intercepted.yMaximum() - (ps_y / 2.0)
        x_min = extent_intercepted.xMinimum() + (ps_x / 2.0)
        x_max = extent_intercepted.xMaximum() - (ps_x / 2.0)
        # index for extent intercepted start in the corner left-top respect to thematic file classes
        idx_x = int(
            (x_min - self.thematic_file_classes.extent().xMinimum()) / ps_x)
        idx_y = int(
            (self.thematic_file_classes.extent().yMaximum() - y_max) / ps_y)

        thematic_classes_band = int(self.QCBox_band_ThematicFile.currentText())

        # data array for the extent intercepted using the thematic file classes values
        ds_in = gdal.Open(get_file_path_of_layer(self.thematic_file_classes))
        da_intercepted = ds_in.GetRasterBand(
            thematic_classes_band).ReadAsArray(
                idx_x, idx_y, int(round((x_max - x_min) / ps_x + 1)),
                int(round((y_max - y_min) / ps_y + 1))).astype(np.int)
        del ds_in

        pixels_to_process = \
            [QgsPointXY(x, y)
             for n_y, y in enumerate(np.arange(y_min, y_max + ps_y/2.0, ps_y)[::-1])
             for n_x, x in enumerate(np.arange(x_min, x_max + ps_x/2.0, ps_x))
             if da_intercepted[n_y][n_x] in classes_selected]
        del da_intercepted

        # edit all pixels inside the classes selected based on the recode pixel table
        edit_status = [
            LayerToEdit.current.edit_pixel(pixel)
            for pixel in pixels_to_process
        ]
        if edit_status:
            if hasattr(LayerToEdit.current.qgs_layer, 'setCacheImage'):
                LayerToEdit.current.qgs_layer.setCacheImage(None)
            LayerToEdit.current.qgs_layer.reload()
            LayerToEdit.current.qgs_layer.triggerRepaint()
        else:
            self.MsgBar.pushMessage(
                "None of the pixel was edited with the classes selected",
                level=Qgis.Info)
            return

        # return to origin symbology
        symbology = \
            [(str(pixel["value"]), pixel["value"],
              (pixel["color"]["R"], pixel["color"]["G"], pixel["color"]["B"], pixel["color"]["A"]))
             for pixel in self.pixel_classes_backup]
        apply_symbology(self.thematic_file_classes, thematic_classes_band,
                        symbology)

        # clear
        self.PixelTable.clear()
        self.PixelTable.setRowCount(0)
        self.PixelTable.setColumnCount(0)
        self.render_widget.canvas.setLayers([])
        self.render_widget.canvas.clearCache()
        self.render_widget.refresh()
        self.QCBox_ThematicFile.setCurrentIndex(-1)
        with block_signals_to(self.QCBox_band_ThematicFile):
            self.QCBox_band_ThematicFile.clear()

        self.accept()
Exemplo n.º 9
0
    def set_pixel_table(self):
        # clear table
        self.PixelTable.clear()
        self.PixelTable.setRowCount(0)
        self.PixelTable.setColumnCount(0)
        if not self.thematic_file_classes:
            return

        with block_signals_to(self.PixelTable):
            header = ["", "class value", "select"]
            row_length = len(self.pixel_classes)
            # init table
            self.PixelTable.setRowCount(row_length)
            self.PixelTable.setColumnCount(3)
            self.PixelTable.horizontalHeader().setMinimumSectionSize(45)
            # hidden row labels
            self.PixelTable.verticalHeader().setVisible(False)
            # add Header
            self.PixelTable.setHorizontalHeaderLabels(header)
            # insert items
            for col_idx, header in enumerate(header):
                if header == "":
                    for row_idx, pixel in enumerate(self.pixel_classes):
                        item_table = QTableWidgetItem()
                        item_table.setFlags(item_table.flags()
                                            & ~Qt.ItemIsSelectable)
                        item_table.setBackground(
                            QColor(pixel["color"]["R"], pixel["color"]["G"],
                                   pixel["color"]["B"], pixel["color"]["A"]))
                        self.PixelTable.setItem(row_idx, col_idx, item_table)
                if header == "class value":
                    for row_idx, pixel in enumerate(self.pixel_classes):
                        item_table = QTableWidgetItem(str(pixel["value"]))
                        item_table.setFlags(item_table.flags()
                                            & ~Qt.ItemIsSelectable)
                        item_table.setFlags(item_table.flags()
                                            & ~Qt.ItemIsEditable)
                        item_table.setTextAlignment(Qt.AlignCenter
                                                    | Qt.AlignVCenter)
                        self.PixelTable.setItem(row_idx, col_idx, item_table)
                if header == "select":
                    for row_idx, pixel in enumerate(self.pixel_classes):
                        item_table = QTableWidgetItem()
                        item_table.setFlags(item_table.flags()
                                            | Qt.ItemIsUserCheckable)
                        item_table.setFlags(item_table.flags()
                                            | Qt.ItemIsEnabled)
                        item_table.setFlags(item_table.flags()
                                            & ~Qt.ItemIsSelectable)
                        item_table.setTextAlignment(Qt.AlignCenter
                                                    | Qt.AlignVCenter)
                        if pixel["select"]:
                            item_table.setCheckState(Qt.Checked)
                        else:
                            item_table.setCheckState(Qt.Unchecked)
                        self.PixelTable.setItem(row_idx, col_idx, item_table)

            # adjust size of Table
            self.PixelTable.resizeColumnsToContents()
            self.PixelTable.resizeRowsToContents()
            # adjust the editor block based on table content
            table_width = self.PixelTable.horizontalHeader().length() + 40
            self.TableBlock.setMaximumWidth(table_width)
            self.TableBlock.setMinimumWidth(table_width)
Exemplo n.º 10
0
 def change_tile_from_spinbox(self, idx_tile):
     with block_signals_to(self.SliderNavigation):
         self.SliderNavigation.setValue(idx_tile)
     self.go_to_tile(idx_tile)
Exemplo n.º 11
0
 def change_tile_from_slider(self, idx_tile):
     with block_signals_to(self.currentTile):
         self.currentTile.setValue(idx_tile)
     self.go_to_tile(idx_tile)
Exemplo n.º 12
0
 def update_canvas_to(self, new_extent):
     with block_signals_to(self.canvas):
         self.canvas.setExtent(new_extent)
         self.refresh()