Пример #1
0
class ConnecMapTool(ParentMapTool):
    """ Button 20: User select connections from layer 'connec'
    Execute SQL function: 'gw_fct_connect_to_network' """
    def __init__(self, iface, settings, action, index_action):
        """ Class constructor """

        # Call ParentMapTool constructor
        super(ConnecMapTool, self).__init__(iface, settings, action,
                                            index_action)

        self.dragging = False

        # Select rectangle
        self.select_rect = QRect()

    """ QgsMapTools inherited event functions """

    def canvasMoveEvent(self, event):
        """ With left click the digitizing is finished """

        if event.buttons() == Qt.LeftButton:

            if not self.dragging:
                self.dragging = True
                self.select_rect.setTopLeft(event.pos())

            self.select_rect.setBottomRight(event.pos())
            self.set_rubber_band()

        else:

            # Hide marker and get coordinates
            self.vertex_marker.hide()
            event_point = self.snapper_manager.get_event_point(event)

            # Snapping
            result = self.snapper_manager.snap_to_background_layers(
                event_point)
            if self.snapper_manager.result_is_valid():
                # Check if it belongs to 'connec' or 'gully' group
                layer = self.snapper_manager.get_snapped_layer(result)
                exist_connec = self.snapper_manager.check_connec_group(layer)
                exist_gully = self.snapper_manager.check_gully_group(layer)
                if exist_connec or exist_gully:
                    self.snapper_manager.add_marker(result, self.vertex_marker)

    def canvasPressEvent(self, event):  #@UnusedVariable

        self.select_rect.setRect(0, 0, 0, 0)
        self.rubber_band.reset(2)

    def canvasReleaseEvent(self, event):
        """ With left click the digitizing is finished """

        if event.button() == Qt.LeftButton:

            # Get coordinates
            event_point = self.snapper_manager.get_event_point(event)

            # Simple selection
            if not self.dragging:

                # Snap to connec or gully
                result = self.snapper_manager.snap_to_background_layers(
                    event_point)
                if not self.snapper_manager.result_is_valid():
                    return

                # Check if it belongs to 'connec' or 'gully' group
                layer = self.snapper_manager.get_snapped_layer(result)
                feature_id = self.snapper_manager.get_snapped_feature_id(
                    result)
                exist_connec = self.snapper_manager.check_connec_group(layer)
                exist_gully = self.snapper_manager.check_gully_group(layer)
                if exist_connec or exist_gully:
                    key = QApplication.keyboardModifiers()
                    # If Ctrl+Shift is clicked: deselect snapped feature
                    if key == (Qt.ControlModifier | Qt.ShiftModifier):
                        layer.deselect([feature_id])
                    else:
                        # If Ctrl is not clicked: remove previous selection
                        if key != Qt.ControlModifier:
                            layer.removeSelection()
                        layer.select([feature_id])

                    # Hide marker
                    self.vertex_marker.hide()

            # Multiple selection
            else:

                # Set valid values for rectangle's width and height
                if self.select_rect.width() == 1:
                    self.select_rect.setLeft(self.select_rect.left() + 1)

                if self.select_rect.height() == 1:
                    self.select_rect.setBottom(self.select_rect.bottom() + 1)

                self.set_rubber_band()
                self.select_multiple_features(self.selected_rectangle)
                self.dragging = False

                # Refresh map canvas
                self.rubber_band.reset()

        elif event.button() == Qt.RightButton:

            # Check selected records
            number_features = 0
            layer = self.snapper_manager.layer_connec
            if layer:
                number_features += layer.selectedFeatureCount()

            if number_features > 0:
                message = "Number of features selected in the 'connec' group"
                title = "Interpolate value - Do you want to update values"
                answer = self.controller.ask_question(
                    message, title, parameter=str(number_features))
                if answer:
                    # Create link
                    self.link_selected_features('connec', layer)

            layer = self.snapper_manager.layer_gully
            if layer:
                # Check selected records
                number_features = 0
                number_features += layer.selectedFeatureCount()

                if number_features > 0:
                    message = "Number of features selected in the 'gully' group"
                    title = "Interpolate value - Do you want to update values"
                    answer = self.controller.ask_question(
                        message, title, parameter=str(number_features))
                    if answer:
                        # Create link
                        self.link_selected_features('gully', layer)

        # Force reload dataProvider of layer
        self.controller.indexing_spatial_layer('v_edit_link')
        self.controller.indexing_spatial_layer('v_edit_vnode')

    def activate(self):

        # Check button
        self.action().setChecked(True)

        # Rubber band
        self.rubber_band.reset()

        # Set main snapping layers
        self.snapper_manager.set_snapping_layers()

        # Store user snapping configuration
        self.snapper_manager.store_snapping_options()

        # Clear snapping
        self.snapper_manager.enable_snapping()

        # Set snapping to 'connec' and 'gully'
        self.snapper_manager.snap_to_connec_gully()

        # Change cursor
        cursor = self.get_cursor_multiple_selection()
        self.canvas.setCursor(cursor)

        # Show help message when action is activated
        if self.show_help:
            message = "Right click to use current selection, select connec points by clicking or dragging (selection box)"
            self.controller.show_info(message)

    def deactivate(self):

        ParentMapTool.deactivate(self)

    def link_selected_features(self, geom_type, layer):
        """ Link selected @geom_type to the pipe """

        # Check features selected
        number_features = layer.selectedFeatureCount()
        if number_features == 0:
            message = "You have to select at least one feature!"
            self.controller.show_warning(message)
            return

        # Get selected features from layers of selected @geom_type
        aux = "{"
        field_id = geom_type + "_id"

        if layer.selectedFeatureCount() > 0:
            # Get selected features of the layer
            features = layer.selectedFeatures()
            for feature in features:
                feature_id = feature.attribute(field_id)
                aux += str(feature_id) + ", "
            list_feature_id = aux[:-2] + "}"

            # Execute function
            function_name = "gw_fct_connect_to_network"
            sql = (f"SELECT {function_name} "
                   f"('{list_feature_id}', '{geom_type.upper()}');")
            self.controller.execute_sql(sql, log_sql=True)
            layer.removeSelection()

        # Refresh map canvas
        self.rubber_band.reset()
        self.refresh_map_canvas()
        self.iface.actionPan().trigger()

    def set_rubber_band(self):

        # Coordinates transform
        transform = self.canvas.getCoordinateTransform()

        # Coordinates
        ll = transform.toMapCoordinates(self.select_rect.left(),
                                        self.select_rect.bottom())
        lr = transform.toMapCoordinates(self.select_rect.right(),
                                        self.select_rect.bottom())
        ul = transform.toMapCoordinates(self.select_rect.left(),
                                        self.select_rect.top())
        ur = transform.toMapCoordinates(self.select_rect.right(),
                                        self.select_rect.top())

        # Rubber band
        self.rubber_band.reset(2)
        self.rubber_band.addPoint(ll, False)
        self.rubber_band.addPoint(lr, False)
        self.rubber_band.addPoint(ur, False)
        self.rubber_band.addPoint(ul, False)
        self.rubber_band.addPoint(ll, True)

        self.selected_rectangle = QgsRectangle(ll, ur)

    def select_multiple_features(self, selectGeometry):

        key = QApplication.keyboardModifiers()

        # If Ctrl+Shift clicked: remove features from selection
        if key == (Qt.ControlModifier | Qt.ShiftModifier):
            behaviour = QgsVectorLayer.RemoveFromSelection
        # If Ctrl clicked: add features to selection
        elif key == Qt.ControlModifier:
            behaviour = QgsVectorLayer.AddToSelection
        # If Ctrl not clicked: add features to selection
        else:
            behaviour = QgsVectorLayer.AddToSelection

        # Selection for all connec and gully layers
        layer = self.snapper_manager.layer_connec
        if layer:
            layer.selectByRect(selectGeometry, behaviour)

        layer = self.snapper_manager.layer_gully
        if layer:
            layer.selectByRect(selectGeometry, behaviour)
class PlanetExtentMapTool(QgsMapTool):

    extentSelected = pyqtSignal(object)

    def __init__(self, canvas):
        QgsMapTool.__init__(self, canvas)

        self.canvas = canvas
        self.extent = None
        self.dragging = False
        self.rubber_band = None
        self.select_rect = QRect()

    def canvasPressEvent(self, event):
        self.select_rect.setRect(0, 0, 0, 0)
        self.rubber_band = QgsRubberBand(self.canvas,
                                         QgsWkbTypes.PolygonGeometry)
        self.rubber_band.setFillColor(RB_FILL)
        self.rubber_band.setStrokeColor(RB_STROKE)
        self.rubber_band.setWidth(1)

    def canvasMoveEvent(self, event):
        if event.buttons() != Qt.LeftButton:
            return

        if not self.dragging:
            self.dragging = True
            self.select_rect.setTopLeft(event.pos())

        self.select_rect.setBottomRight(event.pos())
        self._set_rubber_band()

    def canvasReleaseEvent(self, event):
        # If the user simply clicked without dragging ignore this
        if not self.dragging:
            return

        # Set valid values for rectangle's width and height
        if self.select_rect.width() == 1:
            self.select_rect.setLeft(self.select_rect.left() + 1)
        if self.select_rect.height() == 1:
            self.select_rect.setBottom(self.select_rect.bottom() + 1)

        if self.rubber_band:
            self._set_rubber_band()

            self.rubber_band.reset(QgsWkbTypes.PolygonGeometry)
            del self.rubber_band
            self.rubber_band = None

        self.dragging = False

        # noinspection PyUnresolvedReferences
        self.extentSelected.emit(self.extent)

    def _set_rubber_band(self):
        transform = self.canvas.getCoordinateTransform()

        ll = transform.toMapCoordinates(self.select_rect.left(),
                                        self.select_rect.bottom())
        ur = transform.toMapCoordinates(self.select_rect.right(),
                                        self.select_rect.top())

        if self.rubber_band:
            self.rubber_band.reset(QgsWkbTypes.PolygonGeometry)
            self.rubber_band.addPoint(ll, False)
            self.rubber_band.addPoint(QgsPointXY(ur.x(), ll.y()), False)
            self.rubber_band.addPoint(ur, False)
            self.rubber_band.addPoint(QgsPointXY(ll.x(), ur.y()), True)
            self.extent = QgsRectangle(ur, ll)
class GwConnectLinkButton(GwMaptool):
    """ Button 20: Connect Link
    User select connections from layer 'connec'
    Execute SQL function: 'gw_fct_setlinktonetwork ' """
    def __init__(self, icon_path, action_name, text, toolbar, action_group):

        super().__init__(icon_path, action_name, text, toolbar, action_group)
        self.dragging = False
        self.select_rect = QRect()

    # region QgsMapTools inherited
    """ QgsMapTools inherited event functions """

    def activate(self):

        # Check action. It works if is selected from toolbar. Not working if is selected from menu or shortcut keys
        if hasattr(self.action, "setChecked"):
            self.action.setChecked(True)

        # Rubber band
        tools_gw.reset_rubberband(self.rubber_band)

        # Store user snapping configuration
        self.previous_snapping = self.snapper_manager.get_snapping_options()

        # Clear snapping
        self.snapper_manager.set_snapping_status()

        # Set snapping to 'connec' and 'gully'
        self.snapper_manager.config_snap_to_connec()
        self.snapper_manager.config_snap_to_gully()

        # Change cursor
        cursor = tools_gw.get_cursor_multiple_selection()
        self.canvas.setCursor(cursor)

        # Show help message when action is activated
        if self.show_help:
            message = "Select connecs or gullies with qgis tool and use right click to connect them with network"
            tools_qgis.show_info(message)

    def canvasMoveEvent(self, event):
        """ With left click the digitizing is finished """

        if event.buttons() == Qt.LeftButton:

            if not self.dragging:
                self.dragging = True
                self.select_rect.setTopLeft(event.pos())

            self.select_rect.setBottomRight(event.pos())
            self._set_rubber_band()

    def canvasPressEvent(self, event):

        self.select_rect.setRect(0, 0, 0, 0)
        tools_gw.reset_rubberband(self.rubber_band, 2)

    def canvasReleaseEvent(self, event):
        """ With left click the digitizing is finished """

        # Manage if task is already running
        if hasattr(self,
                   'connect_link_task') and self.connect_link_task is not None:
            try:
                if self.connect_link_task.isActive():
                    message = "Connect link task is already active!"
                    tools_qgis.show_warning(message)
                    return
            except RuntimeError:
                pass

        if event.button() == Qt.LeftButton:

            # Get coordinates
            event_point = self.snapper_manager.get_event_point(event)

            # Simple selection
            if not self.dragging:

                # Snap to connec or gully
                result = self.snapper_manager.snap_to_project_config_layers(
                    event_point)
                if not result.isValid():
                    return

                # Check if it belongs to 'connec' or 'gully' group
                layer = self.snapper_manager.get_snapped_layer(result)
                feature_id = self.snapper_manager.get_snapped_feature_id(
                    result)
                layer_connec = tools_qgis.get_layer_by_tablename(layer)
                layer_gully = tools_qgis.get_layer_by_tablename(layer)
                if layer_connec or layer_gully:
                    key = QApplication.keyboardModifiers()
                    # If Ctrl+Shift is clicked: deselect snapped feature
                    if key == (Qt.ControlModifier | Qt.ShiftModifier):
                        layer.deselect([feature_id])
                    else:
                        # If Ctrl is not clicked: remove previous selection
                        if key != Qt.ControlModifier:
                            layer.removeSelection()
                        layer.select([feature_id])

                    # Hide marker
                    self.vertex_marker.hide()

            # Multiple selection
            else:
                # Set valid values for rectangle's width and height
                if self.select_rect.width() == 1:
                    self.select_rect.setLeft(self.select_rect.left() + 1)

                if self.select_rect.height() == 1:
                    self.select_rect.setBottom(self.select_rect.bottom() + 1)

                self._set_rubber_band()
                self._select_multiple_features(self.selected_rectangle)
                self.dragging = False

                # Refresh map canvas
                tools_gw.reset_rubberband(self.rubber_band)

            # Force reload dataProvider of layer
            tools_qgis.set_layer_index('v_edit_link')
            tools_qgis.set_layer_index('v_edit_vnode')

        elif event.button() == Qt.RightButton:
            # Check selected records
            number_connec_features = 0

            layer_connec = tools_qgis.get_layer_by_tablename('v_edit_connec')
            if layer_connec:
                number_connec_features += layer_connec.selectedFeatureCount()
            if number_connec_features > 0 and QgsProject.instance(
            ).layerTreeRoot().findLayer(layer_connec).isVisible():
                message = "Number of features selected in the group of"
                title = "Connect to network"
                answer = tools_qt.show_question(message,
                                                title,
                                                parameter='connec: ' +
                                                str(number_connec_features))
                if answer:
                    # Create link
                    self.connect_link_task = GwConnectLink(
                        "Connect link", self, 'connec', layer_connec)
                    QgsApplication.taskManager().addTask(
                        self.connect_link_task)
                    QgsApplication.taskManager().triggerTask(
                        self.connect_link_task)
                else:
                    self.manage_gully_result()
            else:
                self.manage_gully_result()

            if number_connec_features == 0 or QgsProject.instance(
            ).layerTreeRoot().findLayer(layer_connec).isVisible() is False:
                self.cancel_map_tool()

    def manage_result(self, result, layer):

        if result is not False and result['status'] != 'Failed':
            self.dlg_dtext = GwDialogTextUi('connect_to_network')
            tools_gw.load_settings(self.dlg_dtext)
            self.dlg_dtext.btn_accept.hide()
            self.dlg_dtext.setWindowTitle('Connect to network')
            self.dlg_dtext.btn_close.clicked.connect(
                partial(tools_gw.close_dialog, self.dlg_dtext))
            self.dlg_dtext.rejected.connect(
                partial(tools_gw.close_dialog, self.dlg_dtext))
            if layer.name() == 'Connec' and global_vars.project_type == 'ud':
                self.dlg_dtext.btn_close.clicked.connect(
                    partial(self.manage_gully_result))
                self.dlg_dtext.rejected.connect(
                    partial(self.manage_gully_result))
            tools_gw.fill_tab_log(self.dlg_dtext, result['body']['data'],
                                  False)
            tools_gw.open_dialog(self.dlg_dtext, dlg_name='dialog_text')

        layer.removeSelection()

        # Refresh map canvas
        if layer.name() == 'Gully' or global_vars.project_type == 'ws':
            tools_gw.reset_rubberband(self.rubber_band)
            self.refresh_map_canvas()
            self.iface.actionPan().trigger()

        # Force reload dataProvider of layer
        tools_qgis.set_layer_index('v_edit_link')
        tools_qgis.set_layer_index('v_edit_vnode')

    def manage_gully_result(self):

        # Manage if task is already running
        if hasattr(self,
                   'connect_link_task') and self.connect_link_task is not None:
            try:
                if self.connect_link_task.isActive():
                    message = "Connect link task is already active!"
                    tools_qgis.show_warning(message)
                    return
            except RuntimeError:
                pass

        layer_gully = tools_qgis.get_layer_by_tablename('v_edit_gully')
        if layer_gully:
            # Check selected records
            number_features = 0
            number_features += layer_gully.selectedFeatureCount()
            if number_features > 0 and QgsProject.instance().layerTreeRoot(
            ).findLayer(layer_gully).isVisible():
                message = "Number of features selected in the group of"
                title = "Connect to network"
                answer = tools_qt.show_question(message,
                                                title,
                                                parameter='gully: ' +
                                                str(number_features))
                if answer:
                    # Create link
                    self.connect_link_task = GwConnectLink(
                        "Connect link", self, 'gully', layer_gully)
                    QgsApplication.taskManager().addTask(
                        self.connect_link_task)
                    QgsApplication.taskManager().triggerTask(
                        self.connect_link_task)

            if number_features == 0 or QgsProject.instance().layerTreeRoot(
            ).findLayer(layer_gully).isVisible() is False:
                self.cancel_map_tool()

    # endregion

    # region private functions

    def _set_rubber_band(self):

        # Coordinates transform
        transform = self.canvas.getCoordinateTransform()

        # Coordinates
        ll = transform.toMapCoordinates(self.select_rect.left(),
                                        self.select_rect.bottom())
        lr = transform.toMapCoordinates(self.select_rect.right(),
                                        self.select_rect.bottom())
        ul = transform.toMapCoordinates(self.select_rect.left(),
                                        self.select_rect.top())
        ur = transform.toMapCoordinates(self.select_rect.right(),
                                        self.select_rect.top())

        # Rubber band
        tools_gw.reset_rubberband(self.rubber_band, 2)
        self.rubber_band.addPoint(ll, False)
        self.rubber_band.addPoint(lr, False)
        self.rubber_band.addPoint(ur, False)
        self.rubber_band.addPoint(ul, False)
        self.rubber_band.addPoint(ll, True)

        self.selected_rectangle = QgsRectangle(ll, ur)

    def _select_multiple_features(self, select_geometry):

        key = QApplication.keyboardModifiers()

        # If Ctrl+Shift clicked: remove features from selection
        if key == (Qt.ControlModifier | Qt.ShiftModifier):
            behaviour = QgsVectorLayer.RemoveFromSelection
        # If Ctrl clicked: add features to selection
        elif key == Qt.ControlModifier:
            behaviour = QgsVectorLayer.AddToSelection
        # If Ctrl not clicked: add features to selection
        else:
            behaviour = QgsVectorLayer.AddToSelection

        # Selection for all connec and gully layers
        layer = tools_qgis.get_layer_by_tablename('v_edit_connec')
        if layer:
            layer.selectByRect(select_geometry, behaviour)

        layer = tools_qgis.get_layer_by_tablename('v_edit_gully')
        if layer:
            layer.selectByRect(select_geometry, behaviour)
Пример #4
0
class InfoTool(QgsMapTool):
    def __init__(self, canvas, snapradius=2):
        super(InfoTool, self).__init__(canvas)
        self.canvas = canvas
        self.radius = snapradius

        self.selectband = QgsRubberBand(self.canvas,
                                        QgsWkbTypes.PolygonGeometry)
        self.selectrect = QRect()
        self.dragging = False
        self.selectionlayers = {}

    def getFeatures(self, rect):
        # The MS SQL driver seems to crash with a empty rectangle.
        # Need to check QGIS to patch issue
        if rect.isEmpty():
            return

        for layer in self.selectionlayers.values():
            if (not layer.type() == QgsMapLayer.VectorLayer
                    or layer.geometryType() == QgsWkbTypes.NoGeometry):
                continue

            layerrect = self.toLayerCoordinates(layer, rect)
            rq = QgsFeatureRequest().setFilterRect(layerrect)\
                .setFlags(QgsFeatureRequest.ExactIntersect)
            features = []
            for feature in layer.getFeatures(rq):
                if feature.isValid():
                    features.append(feature)

            yield layer, features

    def toSearchRect(self, point):
        size = 20
        rect = QRectF()
        rect.setLeft(point.x() - size)
        rect.setRight(point.x() + size)
        rect.setTop(point.y() - size)
        rect.setBottom(point.y() + size)

        transform = self.canvas.getCoordinateTransform()
        ll = transform.toMapCoordinates(rect.left(), rect.bottom())
        ur = transform.toMapCoordinates(rect.right(), rect.top())

        rect = QgsRectangle(ur, ll)
        return rect

    def canvasPressEvent(self, event):
        self.dragging = False
        self.selectrect.setRect(0, 0, 0, 0)

        self.selectband = QgsRubberBand(self.canvas,
                                        QgsWkbTypes.PolygonGeometry)
        self.selectband.setColor(QColor.fromRgb(0, 0, 255, 65))
        self.selectband.setWidth(5)

    def canvasMoveEvent(self, event):
        if not event.buttons() == Qt.LeftButton:
            return

        if not self.dragging:
            self.selectrect.setTopLeft(event.pos())
            self.dragging = True
        self.selectrect.setBottomRight(event.pos())

        maptoolutils.setRubberBand(self.canvas, self.selectrect,
                                   self.selectband)

    def canvasReleaseEvent(self, event):
        if self.dragging:
            geometry = self.selectband.asGeometry()
            if not geometry:
                return

            rect = geometry.boundingBox()
        else:
            rect = self.toSearchRect(event.pos())

        self.dragging = False
        self.selectband.reset()

        results = OrderedDict((l, f) for l, f in self.getFeatures(rect))

        RoamEvents.selectioncleared.emit()
        RoamEvents.selectionchanged.emit(results)
class GwConnectLinkButton(GwParentMapTool):
    """ Button 20: User select connections from layer 'connec'
    Execute SQL function: 'gw_fct_connect_to_network' """
    def __init__(self, icon_path, text, toolbar, action_group):
        """ Class constructor """

        super().__init__(icon_path, text, toolbar, action_group)

        self.dragging = False

        # Select rectangle
        self.select_rect = QRect()

    """ QgsMapTools inherited event functions """

    def canvasMoveEvent(self, event):
        """ With left click the digitizing is finished """

        if event.buttons() == Qt.LeftButton:

            if not self.dragging:
                self.dragging = True
                self.select_rect.setTopLeft(event.pos())

            self.select_rect.setBottomRight(event.pos())
            self.set_rubber_band()

    def canvasPressEvent(self, event):  # @UnusedVariable

        self.select_rect.setRect(0, 0, 0, 0)
        self.rubber_band.reset(2)

    def canvasReleaseEvent(self, event):
        """ With left click the digitizing is finished """

        if event.button() == Qt.LeftButton:

            # Get coordinates
            event_point = get_event_point(event)

            # Simple selection
            if not self.dragging:

                # Snap to connec or gully
                result = snap_to_background_layers(event_point)
                if not result.isValid():
                    return

                # Check if it belongs to 'connec' or 'gully' group
                layer = get_snapped_layer(result)
                feature_id = get_snapped_feature_id(result)
                exist_connec = check_connec_group(layer)
                exist_gully = check_gully_group(layer)
                if exist_connec or exist_gully:
                    key = QApplication.keyboardModifiers()
                    # If Ctrl+Shift is clicked: deselect snapped feature
                    if key == (Qt.ControlModifier | Qt.ShiftModifier):
                        layer.deselect([feature_id])
                    else:
                        # If Ctrl is not clicked: remove previous selection
                        if key != Qt.ControlModifier:
                            layer.removeSelection()
                        layer.select([feature_id])

                    # Hide marker
                    self.vertex_marker.hide()

            # Multiple selection
            else:

                # Set valid values for rectangle's width and height
                if self.select_rect.width() == 1:
                    self.select_rect.setLeft(self.select_rect.left() + 1)

                if self.select_rect.height() == 1:
                    self.select_rect.setBottom(self.select_rect.bottom() + 1)

                self.set_rubber_band()
                self.select_multiple_features(self.selected_rectangle)
                self.dragging = False

                # Refresh map canvas
                self.rubber_band.reset()

        elif event.button() == Qt.RightButton:

            # Check selected records
            number_features = 0
            layer = get_layer('v_edit_connec')
            if layer:
                number_features += layer.selectedFeatureCount()

            if number_features > 0:
                message = "Number of features selected in the group of"
                title = "Interpolate value - Do you want to update values"
                answer = self.controller.ask_question(message,
                                                      title,
                                                      parameter='connec: ' +
                                                      str(number_features))
                if answer:
                    # Create link
                    self.link_selected_features('connec', layer)
                    self.cancel_map_tool()

            layer = get_layer('v_edit_gully')
            if layer:
                # Check selected records
                number_features = 0
                number_features += layer.selectedFeatureCount()

                if number_features > 0:
                    message = "Number of features selected in the group of"
                    title = "Interpolate value - Do you want to update values"
                    answer = self.controller.ask_question(message,
                                                          title,
                                                          parameter='gully: ' +
                                                          str(number_features))
                    if answer:
                        # Create link
                        self.link_selected_features('gully', layer)
                        self.cancel_map_tool()

        # Force reload dataProvider of layer
        self.controller.set_layer_index('v_edit_link')
        self.controller.set_layer_index('v_edit_vnode')

    def activate(self):

        # Check button
        self.action.setChecked(True)

        # Rubber band
        self.rubber_band.reset()

        # Store user snapping configuration
        self.previous_snapping = get_snapping_options()

        # Clear snapping
        enable_snapping()

        # Set snapping to 'connec' and 'gully'
        snap_to_connec_gully()

        # Change cursor
        cursor = get_cursor_multiple_selection()
        self.canvas.setCursor(cursor)

        # Show help message when action is activated
        if self.show_help:
            message = "Right click to use current selection, select connec points by clicking or dragging (selection box)"
            self.controller.show_info(message)

    def deactivate(self):
        super().deactivate()

    def link_selected_features(self, geom_type, layer):
        """ Link selected @geom_type to the pipe """

        # Check features selected
        number_features = layer.selectedFeatureCount()
        if number_features == 0:
            message = "You have to select at least one feature!"
            self.controller.show_warning(message)
            return

        # Get selected features from layers of selected @geom_type
        aux = "["
        field_id = geom_type + "_id"

        if layer.selectedFeatureCount() > 0:
            # Get selected features of the layer
            features = layer.selectedFeatures()
            for feature in features:
                feature_id = feature.attribute(field_id)
                aux += str(feature_id) + ", "
            list_feature_id = aux[:-2] + "]"
            feature_id = f'"id":"{list_feature_id}"'
            extras = f'"feature_type":"{geom_type.upper()}"'
            body = create_body(feature=feature_id, extras=extras)
            # Execute SQL function and show result to the user
            result = self.controller.get_json('gw_fct_connect_to_network',
                                              body)
            if result:
                self.dlg_dtext = DialogTextUi()
                load_settings(self.dlg_dtext)
                self.dlg_dtext.btn_accept.hide()
                self.dlg_dtext.setWindowTitle('Connect to network')
                self.dlg_dtext.btn_close.clicked.connect(
                    partial(close_dialog, self.dlg_dtext))
                self.dlg_dtext.rejected.connect(
                    partial(close_dialog, self.dlg_dtext))
                populate_info_text(self.dlg_dtext, result['body']['data'],
                                   False)
                open_dialog(self.dlg_dtext, dlg_name='dialog_text')

            layer.removeSelection()

        # Refresh map canvas
        self.rubber_band.reset()
        self.refresh_map_canvas()
        self.iface.actionPan().trigger()

    def set_rubber_band(self):

        # Coordinates transform
        transform = self.canvas.getCoordinateTransform()

        # Coordinates
        ll = transform.toMapCoordinates(self.select_rect.left(),
                                        self.select_rect.bottom())
        lr = transform.toMapCoordinates(self.select_rect.right(),
                                        self.select_rect.bottom())
        ul = transform.toMapCoordinates(self.select_rect.left(),
                                        self.select_rect.top())
        ur = transform.toMapCoordinates(self.select_rect.right(),
                                        self.select_rect.top())

        # Rubber band
        self.rubber_band.reset(2)
        self.rubber_band.addPoint(ll, False)
        self.rubber_band.addPoint(lr, False)
        self.rubber_band.addPoint(ur, False)
        self.rubber_band.addPoint(ul, False)
        self.rubber_band.addPoint(ll, True)

        self.selected_rectangle = QgsRectangle(ll, ur)

    def select_multiple_features(self, selectGeometry):

        key = QApplication.keyboardModifiers()

        # If Ctrl+Shift clicked: remove features from selection
        if key == (Qt.ControlModifier | Qt.ShiftModifier):
            behaviour = QgsVectorLayer.RemoveFromSelection
        # If Ctrl clicked: add features to selection
        elif key == Qt.ControlModifier:
            behaviour = QgsVectorLayer.AddToSelection
        # If Ctrl not clicked: add features to selection
        else:
            behaviour = QgsVectorLayer.AddToSelection

        # Selection for all connec and gully layers
        layer = get_layer('v_edit_connec')
        if layer:
            layer.selectByRect(selectGeometry, behaviour)

        layer = get_layer('v_edit_gully')
        if layer:
            layer.selectByRect(selectGeometry, behaviour)