Beispiel #1
0
    def prepare_identify_plot(self):
        """
            Custom Identify tool was activated, prepare everything for identifying plots
        """
        self.active_map_tool_before_custom = self.utils.canvas.mapTool()

        self.btn_identify_plot.setChecked(True)

        self.utils.canvas.mapToolSet.connect(self.initialize_maptool)

        if self.utils._supplies_layers[
                self.utils._supplies_db.names.GC_PLOT_T] is None:
            self.utils.add_layers()

        self.maptool_identify.setLayer(self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PLOT_T])
        cursor = QCursor()
        cursor.setShape(Qt.PointingHandCursor)
        self.maptool_identify.setCursor(cursor)
        self.utils.canvas.setMapTool(self.maptool_identify)

        try:
            self.maptool_identify.featureIdentified.disconnect()
        except TypeError as e:
            pass
        self.maptool_identify.featureIdentified.connect(self.get_info_by_plot)
Beispiel #2
0
    def activate(self):

        cursor = QCursor()
        cursor.setShape(Qt.ArrowCursor)
        self.iface.mapCanvas().setCursor(cursor)

        layers = {
            self.params.junctions_vlay: QgsSnappingConfig.Vertex,
            self.params.reservoirs_vlay: QgsSnappingConfig.Vertex,
            self.params.tanks_vlay: QgsSnappingConfig.Vertex,
            self.params.pipes_vlay: QgsSnappingConfig.VertexAndSegment
        }
        self.snapper = NetworkUtils.set_up_snapper(layers,
                                                   self.iface.mapCanvas(),
                                                   self.params.snap_tolerance)
        self.snapper.toggleEnabled()

        # Editing
        if not self.params.junctions_vlay.isEditable():
            self.params.junctions_vlay.startEditing()
        if not self.params.reservoirs_vlay.isEditable():
            self.params.reservoirs_vlay.startEditing()
        if not self.params.tanks_vlay.isEditable():
            self.params.tanks_vlay.startEditing()
        if not self.params.pipes_vlay.isEditable():
            self.params.pipes_vlay.startEditing()
        if not self.params.pumps_vlay.isEditable():
            self.params.pumps_vlay.startEditing()
        if not self.params.valves_vlay.isEditable():
            self.params.valves_vlay.startEditing()
    def select_feature(self):
        self.setVisible(False)  # Make wizard disappear

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.canvas)
        self.maptool_identify.setLayer(self._current_layer)
        cursor = QCursor()
        cursor.setShape(Qt.CrossCursor)
        self.maptool_identify.setCursor(cursor)
        self.canvas.setMapTool(self.maptool_identify)
        self.maptool_identify.featureIdentified.connect(self.get_feature_id)
Beispiel #4
0
    def btn_sel_element_clicked(self):

        if self.output_reader is None:
            self.iface.messageBar().pushMessage(
                Parameters.plug_in_name,
                'Please select the simulation out file.',
                Qgis.Warning,
                5)  # TODO: softcode
            return

        self.tool = SelectTool(self, self.params)
        self.iface.mapCanvas().setMapTool(self.tool)

        cursor = QCursor()
        cursor.setShape(Qt.ArrowCursor)
        self.iface.mapCanvas().setCursor(cursor)
    def __init__(self, canvas, layer, multi=True):
        self.canvas = canvas
        QgsMapToolEmitPoint.__init__(self, self.canvas)
        self._multi = multi
        self._layer = layer

        # Cursor
        cursor = QCursor()
        cursor.setShape(Qt.CrossCursor)
        self.setCursor(cursor)

        # RubberBand Style
        self.rubberBand = QgsRubberBand(self.canvas, True)
        self.rubberBand.setBrushStyle(Qt.Dense4Pattern)
        self.rubberBand.setColor(QColor(255, 181, 92))
        self.rubberBand.setStrokeColor(QColor(232, 137, 72))
        self.rubberBand.setWidth(0.2)
        self.reset()
Beispiel #6
0
class TidalPredictionTool(QgsMapToolIdentify):
    def __init__(self, canvas, dock):
        super(QgsMapToolIdentify, self).__init__(canvas)
        self.canvas = canvas
        self.dock = dock

        self.selectionMode = self.AllLayers

        self.cursor = QCursor()
        self.cursor.setShape(Qt.ArrowCursor)
        self.setCursor(self.cursor)

    def canvasPressEvent(self, mouseEvent):
        return

    def canvasMoveEvent(self, mouseEvent):
        return

    def canvasReleaseEvent(self, mouseEvent):
        self.currentMoveAction = QgsMapCanvasAnnotationItem.NoAction
        self.setCursor(self.cursor)

        layers = []
        currentStations = currentStationsLayer()
        if currentStations is not None:
            layers.append(currentStations)

        results = self.identify(mouseEvent.x(), mouseEvent.y(), layers)
        for r in results:
            layer = r.mLayer

            if layer == currentStations:
                feature = r.mFeature
                if feature['surface'] > 0:
                    self.dock.activate()
                    self.dock.setCurrentStation(feature)
                    break

    def activate(self):
        self.dock.activate()

    def deactivate(self):
        self.dock.deactivate()
Beispiel #7
0
    def _prepare_identify_plot(self):
        """
        Custom Identify tool was activated, prepare everything for identifying plots
        """
        self.active_map_tool_before_custom = self.canvas.mapTool()
        self.btn_identify_plot.setChecked(True)

        self.canvas.mapToolSet.connect(self._initialize_tools)

        self.maptool_identify.setLayer(self._controller.plot_layer())
        cursor = QCursor()
        cursor.setShape(Qt.PointingHandCursor)
        self.maptool_identify.setCursor(cursor)
        self.canvas.setMapTool(self.maptool_identify)

        try:
            self.maptool_identify.featureIdentified.disconnect()
        except TypeError as e:
            pass
        self.maptool_identify.featureIdentified.connect(
            self._search_data_by_plot)
Beispiel #8
0
class ParentMapTool(QgsMapTool):
    def __init__(self, iface, settings, action, index_action):
        """ Class constructor """

        self.iface = iface
        self.canvas = self.iface.mapCanvas()
        self.settings = settings
        self.show_help = bool(int(self.settings.value('status/show_help', 1)))
        self.index_action = index_action
        self.layer_arc = None
        self.layer_connec = None
        self.layer_gully = None
        self.layer_node = None
        self.schema_name = None
        self.controller = None
        self.dao = None
        self.snapper_manager = None

        # Call superclass constructor and set current action
        QgsMapTool.__init__(self, self.canvas)
        self.setAction(action)

        # Change map tool cursor
        self.cursor = QCursor()
        self.cursor.setShape(Qt.CrossCursor)

        # Get default cursor
        # noinspection PyCallingNonCallable
        self.std_cursor = self.parent().cursor()

        # Set default vertex marker
        color = QColor(255, 100, 255)
        self.vertex_marker = QgsVertexMarker(self.canvas)
        self.vertex_marker.setIconType(QgsVertexMarker.ICON_CIRCLE)
        self.vertex_marker.setColor(color)
        self.vertex_marker.setIconSize(15)
        self.vertex_marker.setPenWidth(3)

        # Set default rubber band
        color_selection = QColor(254, 178, 76, 63)
        self.rubber_band = QgsRubberBand(self.canvas, 2)
        self.rubber_band.setColor(color)
        self.rubber_band.setFillColor(color_selection)
        self.rubber_band.setWidth(1)
        self.reset()

        self.force_active_layer = True

    def get_cursor_multiple_selection(self):
        """ Set cursor for multiple selection """

        path_folder = os.path.join(os.path.dirname(__file__), os.pardir)
        path_cursor = os.path.join(path_folder, 'icons', '201.png')
        if os.path.exists(path_cursor):
            cursor = QCursor(QPixmap(path_cursor))
        else:
            cursor = QCursor(Qt.ArrowCursor)

        return cursor

    def set_controller(self, controller):

        self.controller = controller
        self.schema_name = controller.schema_name
        self.plugin_dir = self.controller.plugin_dir
        if self.snapper_manager is None:
            self.snapper_manager = SnappingConfigManager(self.iface)
        self.snapper_manager.controller = controller

    def deactivate(self):

        # Uncheck button
        self.action().setChecked(False)

        # Restore previous snapping
        self.snapper_manager.recover_snapping_options()

        # Enable snapping
        self.snapper_manager.enable_snapping(True)

        # Recover cursor
        self.canvas.setCursor(self.std_cursor)

        # Remove highlight
        self.vertex_marker.hide()

    def recover_previus_maptool(self):
        if self.controller.prev_maptool:
            self.iface.mapCanvas().setMapTool(self.controller.prev_maptool)
            self.controller.prev_maptool = None

    def remove_vertex(self):
        """ Remove vertex_marker from canvas"""
        vertex_items = [
            i for i in self.iface.mapCanvas().scene().items()
            if issubclass(type(i), QgsVertexMarker)
        ]

        for ver in vertex_items:
            if ver in self.iface.mapCanvas().scene().items():
                if self.vertex_marker == ver:
                    self.iface.mapCanvas().scene().removeItem(ver)

    def set_icon(self, widget, icon):
        """ Set @icon to selected @widget """

        # Get icons folder
        icons_folder = os.path.join(self.plugin_dir, 'icons')
        icon_path = os.path.join(icons_folder, str(icon) + ".png")
        if os.path.exists(icon_path):
            widget.setIcon(QIcon(icon_path))
        else:
            self.controller.log_info("File not found", parameter=icon_path)

    def set_action_pan(self):
        """ Set action 'Pan' """
        try:
            self.iface.actionPan().trigger()
        except Exception:
            pass

    def reset_rubber_band(self, geom_type="polygon"):

        try:
            if geom_type == "polygon":
                geom_type = QgsWkbTypes.PolygonGeometry
            elif geom_type == "line":
                geom_type = QgsWkbTypes.LineString
            self.rubber_band.reset(geom_type)
        except:
            pass

    def reset(self):

        self.reset_rubber_band()
        self.snapped_feat = None

    def cancel_map_tool(self):
        """ Executed if user press right button or escape key """

        # Reset rubber band
        self.reset()

        # Deactivate map tool
        self.deactivate()
        self.set_action_pan()

    def remove_markers(self):
        """ Remove previous markers """

        vertex_items = [
            i for i in list(self.canvas.scene().items())
            if issubclass(type(i), QgsVertexMarker)
        ]
        for ver in vertex_items:
            if ver in list(self.canvas.scene().items()):
                self.canvas.scene().removeItem(ver)

    def refresh_map_canvas(self):
        """ Refresh all layers present in map canvas """

        self.canvas.refreshAllLayers()
        for layer_refresh in self.canvas.layers():
            layer_refresh.triggerRepaint()

    def open_dialog(self,
                    dlg=None,
                    dlg_name=None,
                    info=True,
                    maximize_button=True,
                    stay_on_top=True):
        """ Open dialog """

        # Check database connection before opening dialog
        if not self.controller.check_db_connection():
            return

        if dlg is None or type(dlg) is bool:
            dlg = self.dlg

        # Manage i18n of the dialog
        if dlg_name:
            self.controller.manage_translation(dlg_name, dlg)

        # Manage stay on top, maximize/minimize button and information button
        # if info is True maximize flag will be ignored
        # To enable maximize button you must set info to False
        flags = Qt.WindowCloseButtonHint
        if info:
            flags |= Qt.WindowSystemMenuHint | Qt.WindowContextHelpButtonHint
        else:
            if maximize_button:
                flags |= Qt.WindowMinMaxButtonsHint

        if stay_on_top:
            flags |= Qt.WindowStaysOnTopHint

        dlg.setWindowFlags(flags)

        # Open dialog
        if issubclass(type(dlg), GwDialog):
            dlg.open()
        elif issubclass(type(dlg), GwMainWindow):
            dlg.show()
        else:
            dlg.show()

    def close_dialog(self, dlg=None, set_action_pan=True):
        """ Close dialog """

        if dlg is None or type(dlg) is bool:
            dlg = self.dlg
        try:
            self.save_settings(dlg)
            dlg.close()
            if set_action_pan:
                map_tool = self.canvas.mapTool()
                # If selected map tool is from the plugin, set 'Pan' as current one
                if map_tool.toolName() == '':
                    self.set_action_pan()
        except AttributeError:
            pass

    def load_settings(self, dialog=None):
        """ Load QGIS settings related with dialog position and size """

        if dialog is None:
            dialog = self.dlg

        try:
            x = self.controller.plugin_settings_value(dialog.objectName() +
                                                      "_x")
            y = self.controller.plugin_settings_value(dialog.objectName() +
                                                      "_y")
            width = self.controller.plugin_settings_value(
                dialog.objectName() + "_width", dialog.property('width'))
            height = self.controller.plugin_settings_value(
                dialog.objectName() + "_height", dialog.property('height'))

            if int(x) < 0 or int(y) < 0:
                dialog.resize(int(width), int(height))
            else:
                screens = ctypes.windll.user32
                screen_x = screens.GetSystemMetrics(78)
                screen_y = screens.GetSystemMetrics(79)
                if int(x) > screen_x:
                    x = int(screen_x) - int(width)
                if int(y) > screen_y:
                    y = int(screen_y)
                dialog.setGeometry(int(x), int(y), int(width), int(height))
        except:
            pass

    def save_settings(self, dialog=None):
        """ Save QGIS settings related with dialog position and size """

        if dialog is None:
            dialog = self.dlg

        try:
            self.controller.plugin_settings_set_value(
                dialog.objectName() + "_width", dialog.property('width'))
            self.controller.plugin_settings_set_value(
                dialog.objectName() + "_height", dialog.property('height'))
            self.controller.plugin_settings_set_value(
                dialog.objectName() + "_x",
                dialog.pos().x())
            self.controller.plugin_settings_set_value(
                dialog.objectName() + "_y",
                dialog.pos().y())
        except:
            pass

    def check_expression(self, expr_filter, log_info=False):
        """ Check if expression filter @expr is valid """

        if log_info:
            self.controller.log_info(expr_filter)
        expr = QgsExpression(expr_filter)
        if expr.hasParserError():
            message = "Expression Error"
            self.controller.log_warning(message, parameter=expr_filter)
            return False, expr

        return True, expr

    def get_composers_list(self):

        layour_manager = QgsProject.instance().layoutManager().layouts()
        active_composers = [layout for layout in layour_manager]

        return active_composers

    def get_composer_index(self, name):

        index = 0
        composers = self.get_composers_list()
        for comp_view in composers:
            composer_name = comp_view.name()
            if composer_name == name:
                break
            index += 1

        return index

    def canvasMoveEvent(self, event):

        # Make sure active layer is always 'v_edit_node'
        cur_layer = self.iface.activeLayer()
        if cur_layer != self.layer_node and self.force_active_layer:
            self.iface.setActiveLayer(self.layer_node)

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

        # Snapping
        result = self.snapper_manager.snap_to_current_layer(event_point)
        if self.snapper_manager.result_is_valid():
            self.snapper_manager.add_marker(result, self.vertex_marker)

    def create_body(self, form='', feature='', filter_fields='', extras=None):
        """ Create and return parameters as body to functions"""

        client = f'$${{"client":{{"device":4, "infoType":1, "lang":"ES"}}, '
        form = f'"form":{{{form}}}, '
        feature = '"feature":{' + feature + '}, '
        filter_fields = '"filterFields":{' + filter_fields + '}'
        page_info = '"pageInfo":{}'
        data = '"data":{' + filter_fields + ', ' + page_info
        if extras:
            data += ', ' + extras
        data += f'}}}}$$'
        body = "" + client + form + feature + data

        return body

    def refresh_legend(self):
        """ This function solves the bug generated by changing the type of feature.
        Mysteriously this bug is solved by checking and unchecking the categorization of the tables.
        # TODO solve this bug
        """
        layers = [
            self.controller.get_layer_by_tablename('v_edit_node'),
            self.controller.get_layer_by_tablename('v_edit_connec'),
            self.controller.get_layer_by_tablename('v_edit_gully')
        ]

        for layer in layers:
            if layer:
                ltl = QgsProject.instance().layerTreeRoot().findLayer(
                    layer.id())
                ltm = self.iface.layerTreeView().model()
                legendNodes = ltm.layerLegendNodes(ltl)
                for ln in legendNodes:
                    current_state = ln.data(Qt.CheckStateRole)
                    ln.setData(Qt.Unchecked, Qt.CheckStateRole)
                    ln.setData(Qt.Checked, Qt.CheckStateRole)
                    ln.setData(current_state, Qt.CheckStateRole)

    def put_layer_into_toc(self,
                           tablename=None,
                           the_geom="the_geom",
                           field_id="id",
                           group='GW Layers'):
        """ Put layer from postgres DB into TOC"""
        schema_name = self.controller.credentials['schema'].replace('"', '')
        uri = QgsDataSourceUri()
        uri.setConnection(self.controller.credentials['host'],
                          self.controller.credentials['port'],
                          self.controller.credentials['db'],
                          self.controller.credentials['user'],
                          self.controller.credentials['password'])
        if not field_id:
            field_id = self.controller.get_pk(tablename)
            if not field_id:
                field_id = "id"
        uri.setDataSource(schema_name, f'{tablename}', the_geom, None,
                          field_id)
        layer = QgsVectorLayer(uri.uri(), f'{tablename}', "postgres")

        root = QgsProject.instance().layerTreeRoot()
        my_group = root.findGroup(group)
        if my_group is None:
            my_group = root.insertGroup(0, group)

        my_group.insertLayer(0, layer)
        self.iface.mapCanvas().refresh()
        return layer

    def populate_info_text(self,
                           dialog,
                           data,
                           force_tab=True,
                           reset_text=True,
                           tab_idx=1):

        change_tab = False
        text = qt_tools.getWidgetText(dialog,
                                      'txt_infolog',
                                      return_string_null=False)
        if reset_text:
            text = ""
        for item in data['info']['values']:
            if 'message' in item:
                if item['message'] is not None:
                    text += str(item['message']) + "\n"
                    if force_tab:
                        change_tab = True
                else:
                    text += "\n"

        qt_tools.setWidgetText(dialog, 'txt_infolog', text + "\n")
        qtabwidget = dialog.findChild(QTabWidget, 'mainTab')
        if change_tab and qtabwidget is not None:
            qtabwidget.setCurrentIndex(tab_idx)

        return change_tab
class CadApiInfo(ParentMapTool):
    """ Button 37: Info """
    def __init__(self, iface, settings, action, index_action):
        """ Class constructor """

        super(CadApiInfo, self).__init__(iface, settings, action, index_action)
        self.index_action = index_action
        self.tab_type = None
        # Used when the signal 'signal_activate' is emitted from the info, do not open another form
        self.block_signal = False
        self.previous_api_cf = None

    def create_point(self, event):

        x = event.pos().x()
        y = event.pos().y()
        try:
            point = QgsMapToPixel.toMapCoordinates(
                self.canvas.getCoordinateTransform(), x, y)
        except (TypeError, KeyError):
            self.iface.actionPan().trigger()
            return False

        return point

    """ QgsMapTools inherited event functions """

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Escape:
            for rb in self.rubberband_list:
                rb.reset()
            self.api_cf.resetRubberbands()
            self.action().trigger()
            return

    def canvasMoveEvent(self, event):
        pass

    def canvasReleaseEvent(self, event):

        for rb in self.rubberband_list:
            rb.reset()

        if self.block_signal:
            self.block_signal = False
            return

        self.controller.init_docker()

        if event.button() == Qt.LeftButton:
            point = self.create_point(event)
            if point is False:
                return
            api_cf = ApiCF(self.iface, self.settings, self.controller,
                           self.controller.plugin_dir, self.tab_type)
            api_cf.signal_activate.connect(self.reactivate_map_tool)
            api_cf.open_form(point, tab_type=self.tab_type)
            # Remove previous rubberband when open new docker
            if isinstance(self.previous_api_cf,
                          ApiCF) and self.controller.dlg_docker is not None:
                self.previous_api_cf.resetRubberbands()
            self.previous_api_cf = api_cf

        elif event.button() == Qt.RightButton:
            point = self.create_point(event)
            if point is False:
                return
            api_cf = ApiCF(self.iface, self.settings, self.controller,
                           self.controller.plugin_dir, self.tab_type)
            api_cf.hilight_feature(point, self.rubberband_list, self.tab_type)

    def reactivate_map_tool(self):
        """ Reactivate tool """

        self.block_signal = True
        info_action = self.iface.mainWindow().findChild(
            QAction, 'map_tool_api_info_data')
        info_action.trigger()

    def activate(self):

        # Check button
        self.action().setChecked(True)
        # Change map tool cursor
        self.cursor = QCursor()
        self.cursor.setShape(Qt.WhatsThisCursor)
        self.canvas.setCursor(self.cursor)
        self.rubberband_list = []
        if self.index_action == '37':
            self.tab_type = 'data'
        elif self.index_action == '199':
            self.tab_type = 'inp'

    def deactivate(self):

        for rb in self.rubberband_list:
            rb.reset()
        if hasattr(self, 'api_cf'):
            self.api_cf.resetRubberbands()
        ParentMapTool.deactivate(self)
class GwInfoButton(GwParentMapTool):
    def __init__(self, icon_path, text, toolbar, action_group):
        super().__init__(icon_path, text, toolbar, action_group)

        self.rubber_band = QgsRubberBand(global_vars.canvas)
        self.tab_type = None
        # Used when the signal 'signal_activate' is emitted from the info, do not open another form
        self.block_signal = False

    def create_point(self, event):

        x = event.pos().x()
        y = event.pos().y()
        try:
            point = QgsMapToPixel.toMapCoordinates(
                self.canvas.getCoordinateTransform(), x, y)
        except (TypeError, KeyError):
            self.iface.actionPan().trigger()
            return False

        return point

    """ QgsMapTools inherited event functions """

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Escape:
            for rb in self.rubberband_list:
                rb.reset()
            self.rubber_band.reset()
            self.action.trigger()
            return

    def canvasMoveEvent(self, event):
        pass

    def canvasReleaseEvent(self, event):

        for rb in self.rubberband_list:
            rb.reset()

        if self.block_signal:
            self.block_signal = False
            return

        self.controller.init_docker()

        if event.button() == Qt.LeftButton:
            point = self.create_point(event)
            if point is False:
                return
            self.api_cf.get_info_from_coordinates(point,
                                                  tab_type=self.tab_type)

        elif event.button() == Qt.RightButton:
            point = self.create_point(event)
            if point is False:
                return
            self.get_layers_from_coordinates(point, self.rubberband_list,
                                             self.tab_type)

    def reactivate_map_tool(self):
        """ Reactivate tool """

        self.block_signal = True
        info_action = self.iface.mainWindow().findChild(
            QAction, 'map_tool_api_info_data')
        info_action.trigger()

    def activate(self):

        # Check button
        self.action.setChecked(True)
        # Change map tool cursor
        self.cursor = QCursor()
        self.cursor.setShape(Qt.WhatsThisCursor)
        self.canvas.setCursor(self.cursor)
        self.rubberband_list = []
        # if self.index_action == '37':
        self.tab_type = 'data'
        # elif self.index_action == '199':
        # 	self.tab_type = 'inp'

        self.api_cf = GwInfo(self.tab_type)

        self.api_cf.signal_activate.connect(self.reactivate_map_tool)

    def deactivate(self):

        for rb in self.rubberband_list:
            rb.reset()
        if hasattr(self, 'api_cf'):
            self.rubber_band.reset()

        super().deactivate()

    def get_layers_from_coordinates(self, point, rb_list, tab_type=None):

        cursor = QCursor()
        x = cursor.pos().x()
        y = cursor.pos().y()
        click_point = QPoint(x + 5, y + 5)

        visible_layers = get_visible_layers(as_list=True)
        scale_zoom = self.iface.mapCanvas().scale()

        # Get layers under mouse clicked
        extras = f'"pointClickCoords":{{"xcoord":{point.x()}, "ycoord":{point.y()}}}, '
        extras += f'"visibleLayers":{visible_layers}, '
        extras += f'"zoomScale":{scale_zoom} '
        body = create_body(extras=extras)
        json_result = self.controller.get_json(
            'gw_fct_getlayersfromcoordinates',
            body,
            rubber_band=self.rubber_band)
        if not json_result:
            return False

        # hide QMenu identify if no feature under mouse
        len_layers = len(json_result['body']['data']['layersNames'])
        if len_layers == 0:
            return False

        self.icon_folder = self.plugin_dir + '/icons/'

        # Right click main QMenu
        main_menu = QMenu()

        # Create one menu for each layer
        for layer in json_result['body']['data']['layersNames']:
            layer_name = self.controller.get_layer_by_tablename(
                layer['layerName'])
            icon_path = self.icon_folder + layer['icon'] + '.png'
            if os.path.exists(str(icon_path)):
                icon = QIcon(icon_path)
                sub_menu = main_menu.addMenu(icon, layer_name.name())
            else:
                sub_menu = main_menu.addMenu(layer_name.name())
            # Create one QAction for each id
            for feature in layer['ids']:
                action = QAction(str(feature['id']), None)
                sub_menu.addAction(action)
                action.triggered.connect(
                    partial(self.get_info_from_selected_id, action, tab_type))
                action.hovered.connect(
                    partial(self.draw_by_action, feature, rb_list))

        main_menu.addSeparator()
        # Identify all
        cont = 0
        for layer in json_result['body']['data']['layersNames']:
            cont += len(layer['ids'])
        action = QAction(f'Identify all ({cont})', None)
        action.hovered.connect(partial(self.identify_all, json_result,
                                       rb_list))
        main_menu.addAction(action)
        main_menu.addSeparator()
        main_menu.exec_(click_point)

    def identify_all(self, complet_list, rb_list):

        self.rubber_band.reset()
        for rb in rb_list:
            rb.reset()
        for layer in complet_list['body']['data']['layersNames']:
            for feature in layer['ids']:
                points = []
                list_coord = re.search('\((.*)\)', str(feature['geometry']))
                coords = list_coord.group(1)
                polygon = coords.split(',')
                for i in range(0, len(polygon)):
                    x, y = polygon[i].split(' ')
                    point = QgsPointXY(float(x), float(y))
                    points.append(point)
                rb = QgsRubberBand(self.canvas)
                polyline = QgsGeometry.fromPolylineXY(points)
                rb.setToGeometry(polyline, None)
                rb.setColor(QColor(255, 0, 0, 100))
                rb.setWidth(5)
                rb.show()
                rb_list.append(rb)

    def draw_by_action(self, feature, rb_list, reset_rb=True):
        """ Draw lines based on geometry """

        for rb in rb_list:
            rb.reset()
        if feature['geometry'] is None:
            return

        list_coord = re.search('\((.*)\)', str(feature['geometry']))
        max_x, max_y, min_x, min_y = get_max_rectangle_from_coords(list_coord)
        if reset_rb is True:
            self.rubber_band.reset()
        if str(max_x) == str(min_x) and str(max_y) == str(min_y):
            point = QgsPointXY(float(max_x), float(max_y))
            draw_point(point, self.rubber_band)
        else:
            points = get_points(list_coord)
            draw_polyline(points, self.rubber_band)

    def get_info_from_selected_id(self, action, tab_type):
        """ Set active selected layer """
        self.rubber_band.reset()
        parent_menu = action.associatedWidgets()[0]
        layer = self.controller.get_layer_by_layername(parent_menu.title())
        if layer:
            layer_source = self.controller.get_layer_source(layer)
            self.iface.setActiveLayer(layer)
            complet_result, dialog = self.api_cf.get_info_from_id(
                table_name=layer_source['table'],
                feature_id=action.text(),
                tab_type=tab_type)
Beispiel #11
0
    def canvasMoveEvent(self, mouseEvent):
        item = self.selectedItem()
        if not item:
            return

        annotation = item.annotation()
        if not annotation:
            return

        pixelToMmScale = 25.4 / self.canvas.logicalDpiX()
        if self.currentMoveAction == QgsMapCanvasAnnotationItem.MoveFramePosition:
            # move the entire frame
            newCanvasPos = item.pos() + (mouseEvent.pos() -
                                         self.lastMousePosition)
            if annotation.hasFixedMapPosition():
                deltaX = pixelToMmScale * (mouseEvent.pos().x() -
                                           self.lastMousePosition.x())
                deltaY = pixelToMmScale * (mouseEvent.pos().y() -
                                           self.lastMousePosition.y())
                annotation.setFrameOffsetFromReferencePointMm(
                    QPointF(
                        annotation.frameOffsetFromReferencePointMm().x() +
                        deltaX,
                        annotation.frameOffsetFromReferencePointMm().y() +
                        deltaY))
                annotation.setRelativePosition(
                    QPointF(newCanvasPos.x() / self.canvas.width(),
                            newCanvasPos.y() / self.canvas.height()))
                item.update()
                QgsProject.instance().setDirty(True)

        elif self.currentMoveAction != QgsMapCanvasAnnotationItem.NoAction:
            # handle vertical frame resize actions only
            size = annotation.frameSizeMm()
            xmin = annotation.frameOffsetFromReferencePointMm().x()
            ymin = annotation.frameOffsetFromReferencePointMm().y()
            xmax = xmin + size.width()
            ymax = ymin + size.height()
            relPosX = annotation.relativePosition().x()
            relPosY = annotation.relativePosition().y()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightUp):
                ymin += pixelToMmScale * (mouseEvent.pos().y() -
                                          self.lastMousePosition.y())
                relPosY = (relPosY * self.canvas.height() +
                           mouseEvent.pos().y() -
                           self.lastMousePosition.y()) / self.canvas.height()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameDown
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftDown
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightDown):
                ymax += pixelToMmScale * (mouseEvent.pos().y() -
                                          self.lastMousePosition.y())

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeft
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftDown):
                xmin += pixelToMmScale * (mouseEvent.pos().x() -
                                          self.lastMousePosition.x())
                relPosX = (relPosX * self.canvas.width() +
                           mouseEvent.pos().x() -
                           self.lastMousePosition.x()) / self.canvas.width()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRight
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightDown):
                xmax += pixelToMmScale * (mouseEvent.pos().x() -
                                          self.lastMousePosition.x())

            # switch min / max if necessary
            if xmax < xmin:
                tmp = xmax
                xmax = xmin
                xmin = tmp
            if ymax < ymin:
                tmp = ymax
                ymax = ymin
                ymin = tmp
            annotation.setFrameOffsetFromReferencePointMm(QPointF(xmin, ymin))
            annotation.setFrameSizeMm(QSizeF(xmax - xmin, ymax - ymin))
            annotation.setRelativePosition(QPointF(relPosX, relPosY))
            item.update()
            QgsProject.instance().setDirty(True)

        moveAction = item.moveActionForPosition(mouseEvent.pos())
        cursor = QCursor()
        cursor.setShape(item.cursorShapeForAction(moveAction))
        self.setCursor(cursor)

        self.lastMousePosition = mouseEvent.pos()
class GwInfoButton(GwMaptool):
    """ Button 37: Info """
    def __init__(self, icon_path, action_name, text, toolbar, action_group):

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

        self.rubber_band = tools_gw.create_rubberband(global_vars.canvas)
        self.tab_type = None
        # Used when the signal 'signal_activate' is emitted from the info, do not open another form
        self.block_signal = False
        self.previous_info_feature = None
        self.action_name = action_name

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

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Escape:
            for rb in self.rubberband_list:
                tools_gw.reset_rubberband(rb)
            tools_gw.reset_rubberband(self.rubber_band)
            self.action.trigger()
            return

    def canvasMoveEvent(self, event):
        pass

    def canvasReleaseEvent(self, event):

        self._get_info(event)

    def activate(self):

        if info.is_inserting:
            msg = "You cannot insert more than one feature at the same time, finish editing the previous feature"
            tools_qgis.show_message(msg)
            super().deactivate()
            return

        # 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)
        # Change map tool cursor
        self.cursor = QCursor()
        self.cursor.setShape(Qt.WhatsThisCursor)
        self.canvas.setCursor(self.cursor)
        self.rubberband_list = []
        self.tab_type = 'data'

    def deactivate(self):

        if hasattr(self, 'rubberband_list'):
            for rb in self.rubberband_list:
                tools_gw.reset_rubberband(rb)
        if hasattr(self, 'dlg_info_feature'):
            tools_gw.reset_rubberband(self.rubber_band)

        super().deactivate()

    # endregion

    # region private functions

    def _create_point(self, event):

        x = event.pos().x()
        y = event.pos().y()
        try:
            point = QgsMapToPixel.toMapCoordinates(
                self.canvas.getCoordinateTransform(), x, y)
        except (TypeError, KeyError):
            self.iface.actionPan().trigger()
            return False

        return point

    def _reactivate_map_tool(self):
        """ Reactivate tool """

        self.block_signal = True
        info_action = self.iface.mainWindow().findChildren(
            QAction, self.action_name)[-1]
        info_action.trigger()

    def _get_layers_from_coordinates(self, point, rb_list, tab_type=None):

        cursor = QCursor()
        x = cursor.pos().x()
        y = cursor.pos().y()
        click_point = QPoint(x + 5, y + 5)

        visible_layers = tools_qgis.get_visible_layers(as_str_list=True)
        scale_zoom = self.iface.mapCanvas().scale()

        # Get layers under mouse clicked
        extras = f'"pointClickCoords":{{"xcoord":{point.x()}, "ycoord":{point.y()}}}, '
        extras += f'"visibleLayers":{visible_layers}, '
        extras += f'"zoomScale":{scale_zoom} '
        body = tools_gw.create_body(extras=extras)
        json_result = tools_gw.execute_procedure(
            'gw_fct_getlayersfromcoordinates',
            body,
            rubber_band=self.rubber_band)
        if not json_result or json_result['status'] == 'Failed':
            return False

        # hide QMenu identify if no feature under mouse
        len_layers = len(json_result['body']['data']['layersNames'])
        if len_layers == 0:
            return False

        self.icon_folder = self.plugin_dir + '/icons/'

        # Right click main QMenu
        main_menu = QMenu()

        # Create one menu for each layer
        for layer in json_result['body']['data']['layersNames']:
            layer_name = tools_qgis.get_layer_by_tablename(layer['layerName'])
            icon_path = self.icon_folder + layer['icon'] + '.png'
            if os.path.exists(str(icon_path)):
                icon = QIcon(icon_path)
                sub_menu = main_menu.addMenu(icon, layer_name.name())
            else:
                sub_menu = main_menu.addMenu(layer_name.name())
            # Create one QAction for each id
            for feature in layer['ids']:
                if 'label' in feature:
                    label = str(feature['label'])
                else:
                    label = str(feature['id'])
                action = QAction(label, None)
                action.setProperty('feature_id', str(feature['id']))
                sub_menu.addAction(action)
                action.triggered.connect(
                    partial(self._get_info_from_selected_id, action, tab_type))
                action.hovered.connect(
                    partial(self._draw_by_action, feature, rb_list))

        main_menu.addSeparator()
        # Identify all
        cont = 0
        for layer in json_result['body']['data']['layersNames']:
            cont += len(layer['ids'])
        action = QAction(f'Identify all ({cont})', None)
        action.hovered.connect(
            partial(self._identify_all, json_result, rb_list))
        main_menu.addAction(action)
        main_menu.addSeparator()
        main_menu.exec_(click_point)

    def _identify_all(self, complet_list, rb_list):

        tools_gw.reset_rubberband(self.rubber_band)
        for rb in rb_list:
            tools_gw.reset_rubberband(rb)
        for layer in complet_list['body']['data']['layersNames']:
            for feature in layer['ids']:
                points = []
                list_coord = re.search('\((.*)\)', str(feature['geometry']))
                coords = list_coord.group(1)
                polygon = coords.split(',')
                for i in range(0, len(polygon)):
                    x, y = polygon[i].split(' ')
                    point = QgsPointXY(float(x), float(y))
                    points.append(point)
                rb = tools_gw.create_rubberband(self.canvas)
                polyline = QgsGeometry.fromPolylineXY(points)
                rb.setToGeometry(polyline, None)
                rb.setColor(QColor(255, 0, 0, 100))
                rb.setWidth(5)
                rb.show()
                rb_list.append(rb)

    def _draw_by_action(self, feature, rb_list, reset_rb=True):
        """ Draw lines based on geometry """

        for rb in rb_list:
            tools_gw.reset_rubberband(rb)
        if feature['geometry'] is None:
            return

        list_coord = re.search('\((.*)\)', str(feature['geometry']))
        max_x, max_y, min_x, min_y = tools_qgis.get_max_rectangle_from_coords(
            list_coord)
        if reset_rb:
            tools_gw.reset_rubberband(self.rubber_band)
        if str(max_x) == str(min_x) and str(max_y) == str(min_y):
            point = QgsPointXY(float(max_x), float(max_y))
            tools_qgis.draw_point(point, self.rubber_band)
        else:
            points = tools_qgis.get_geometry_vertex(list_coord)
            tools_qgis.draw_polyline(points, self.rubber_band)

    def _get_info_from_selected_id(self, action, tab_type):
        """ Set active selected layer """

        tools_gw.reset_rubberband(self.rubber_band)
        parent_menu = action.associatedWidgets()[0]
        layer = tools_qgis.get_layer_by_layername(parent_menu.title())
        if layer:
            layer_source = tools_qgis.get_layer_source(layer)
            self.iface.setActiveLayer(layer)
            tools_gw.init_docker()
            info_feature = GwInfo(self.tab_type)
            info_feature.signal_activate.connect(self._reactivate_map_tool)
            info_feature.get_info_from_id(
                table_name=layer_source['table'],
                feature_id=action.property('feature_id'),
                tab_type=tab_type)
            # Remove previous rubberband when open new docker
            if isinstance(
                    self.previous_info_feature, GwInfo
            ) and global_vars.session_vars['dialog_docker'] is not None:
                tools_gw.reset_rubberband(
                    self.previous_info_feature.rubber_band)
            self.previous_info_feature = info_feature

    def _get_info(self, event):

        for rb in self.rubberband_list:
            tools_gw.reset_rubberband(rb)

        if self.block_signal:
            self.block_signal = False
            return

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

            point = self._create_point(event)
            if point is False:
                return
            tools_gw.init_docker()
            info_feature = GwInfo(self.tab_type)
            info_feature.signal_activate.connect(self._reactivate_map_tool)
            info_feature.get_info_from_coordinates(point,
                                                   tab_type=self.tab_type)
            # Remove previous rubberband when open new docker
            if isinstance(
                    self.previous_info_feature, GwInfo
            ) and global_vars.session_vars['dialog_docker'] is not None:
                tools_gw.reset_rubberband(
                    self.previous_info_feature.rubber_band)
            self.previous_info_feature = info_feature

        elif event.button() == Qt.RightButton:
            point = self._create_point(event)
            if point is False:
                return

            self._get_layers_from_coordinates(point, self.rubberband_list,
                                              self.tab_type)
Beispiel #13
0
class GwInfoButton(GwParentMapTool):
    def __init__(self, icon_path, text, toolbar, action_group, iface, settings,
                 controller, plugin_dir):
        super().__init__(icon_path, text, toolbar, action_group, iface,
                         settings, controller, plugin_dir)

        self.tab_type = None
        # Used when the signal 'signal_activate' is emitted from the info, do not open another form
        self.block_signal = False

    def create_point(self, event):

        x = event.pos().x()
        y = event.pos().y()
        try:
            point = QgsMapToPixel.toMapCoordinates(
                self.canvas.getCoordinateTransform(), x, y)
        except (TypeError, KeyError):
            self.iface.actionPan().trigger()
            return False

        return point

    """ QgsMapTools inherited event functions """

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Escape:
            for rb in self.rubberband_list:
                rb.reset()
            self.api_cf.resetRubberbands()
            self.action.trigger()
            return

    def canvasMoveEvent(self, event):
        pass

    def canvasReleaseEvent(self, event):

        for rb in self.rubberband_list:
            rb.reset()

        if self.block_signal:
            self.block_signal = False
            return

        self.controller.init_docker()

        if event.button() == Qt.LeftButton:
            point = self.create_point(event)
            if point is False:
                return
            self.api_cf.open_form(point, tab_type=self.tab_type)

        elif event.button() == Qt.RightButton:
            point = self.create_point(event)
            if point is False:
                return
            self.api_cf.hilight_feature(point, self.rubberband_list,
                                        self.tab_type)

    def reactivate_map_tool(self):
        """ Reactivate tool """

        self.block_signal = True
        info_action = self.iface.mainWindow().findChild(
            QAction, 'map_tool_api_info_data')
        info_action.trigger()

    def activate(self):

        # Check button
        self.action.setChecked(True)
        # Change map tool cursor
        self.cursor = QCursor()
        self.cursor.setShape(Qt.WhatsThisCursor)
        self.canvas.setCursor(self.cursor)
        self.rubberband_list = []
        # if self.index_action == '37':
        self.tab_type = 'data'
        # elif self.index_action == '199':
        # 	self.tab_type = 'inp'

        self.api_cf = GwInfo(self.iface, self.settings, self.controller,
                             self.controller.plugin_dir, self.tab_type)

        self.api_cf.signal_activate.connect(self.reactivate_map_tool)

    def deactivate(self):

        for rb in self.rubberband_list:
            rb.reset()
        if hasattr(self, 'api_cf'):
            self.api_cf.resetRubberbands()

        super().deactivate()
Beispiel #14
0
    def activate(self):

        self.layer_selft.clear()

        cursor = QCursor()
        cursor.setShape(Qt.ArrowCursor)
        self.iface.mapCanvas().setCursor(cursor)

        # Snapping
        # QgsProject.instance().setSnapSettingsForLayer(self.params.junctions_vlay.id(),
        #                                               False,
        #                                               QgsSnapper.SnapToVertex,
        #                                               QgsTolerance.MapUnits,
        #                                               self.params.snap_tolerance,
        #                                               True)
        #
        # QgsProject.instance().setSnapSettingsForLayer(self.params.reservoirs_vlay.id(),
        #                                               False,
        #                                               QgsSnapper.SnapToVertex,
        #                                               QgsTolerance.MapUnits,
        #                                               self.params.snap_tolerance,
        #                                               True)
        #
        # QgsProject.instance().setSnapSettingsForLayer(self.params.tanks_vlay.id(),
        #                                               False,
        #                                               QgsSnapper.SnapToVertex,
        #                                               QgsTolerance.MapUnits,
        #                                               self.params.snap_tolerance,
        #                                               True)
        #
        # QgsProject.instance().setSnapSettingsForLayer(self.params.pipes_vlay.id(),
        #                                               True,
        #                                               QgsSnapper.SnapToSegment,
        #                                               QgsTolerance.MapUnits,
        #                                               self.params.snap_tolerance,
        #                                               True)

        # snap_layer_junctions = NetworkUtils.set_up_snap_layer(self.params.junctions_vlay)
        # snap_layer_reservoirs = NetworkUtils.set_up_snap_layer(self.params.reservoirs_vlay)
        # snap_layer_tanks = NetworkUtils.set_up_snap_layer(self.params.tanks_vlay)
        # snap_layer_pipes = NetworkUtils.set_up_snap_layer(self.params.pipes_vlay, snapping_type=QgsSnapper.SnapToSegment)

        layers = {
            self.params.junctions_vlay: QgsSnappingConfig.Vertex,
            self.params.reservoirs_vlay: QgsSnappingConfig.Vertex,
            self.params.tanks_vlay: QgsSnappingConfig.Vertex,
            self.params.pipes_vlay: QgsSnappingConfig.VertexAndSegment
        }
        self.snapper = NetworkUtils.set_up_snapper(layers,
                                                   self.iface.mapCanvas(),
                                                   self.params.snap_tolerance)
        self.snapper.toggleEnabled()

        # Editing
        if not self.params.junctions_vlay.isEditable():
            self.params.junctions_vlay.startEditing()
        if not self.params.reservoirs_vlay.isEditable():
            self.params.reservoirs_vlay.startEditing()
        if not self.params.tanks_vlay.isEditable():
            self.params.tanks_vlay.startEditing()
        if not self.params.pipes_vlay.isEditable():
            self.params.pipes_vlay.startEditing()
        if not self.params.pumps_vlay.isEditable():
            self.params.pumps_vlay.startEditing()
        if not self.params.valves_vlay.isEditable():
            self.params.valves_vlay.startEditing()
Beispiel #15
0
class CreatePredictionAnnotationsTool(QgsMapToolIdentify):
    def __init__(self, canvas):
        super(QgsMapToolIdentify, self).__init__(canvas)
        self.canvas = canvas
        self.selectionMode = self.ActiveLayer  # TODO: maybe this can use all layers
        self.currentMoveAction = QgsMapCanvasAnnotationItem.NoAction
        self.cursor = QCursor()
        self.cursor.setShape(Qt.ArrowCursor)
        self.setCursor(self.cursor)

    def canvasPressEvent(self, mouseEvent):
        self.lastMousePosition = mouseEvent.pos()

        item = self.selectedItem()
        if item:
            self.currentMoveAction = item.moveActionForPosition(
                mouseEvent.pos())
            if self.currentMoveAction != QgsMapCanvasAnnotationItem.NoAction:
                return

        # select a new item if there is one at this position
        if (not item
            ) or self.currentMoveAction == QgsMapCanvasAnnotationItem.NoAction:
            self.canvas.scene().clearSelection()
            existingItem = self.itemAtPos(mouseEvent.pos())
            if existingItem:
                existingItem.setSelected(True)

    def canvasMoveEvent(self, mouseEvent):
        item = self.selectedItem()
        if not item:
            return

        annotation = item.annotation()
        if not annotation:
            return

        pixelToMmScale = 25.4 / self.canvas.logicalDpiX()
        if self.currentMoveAction == QgsMapCanvasAnnotationItem.MoveFramePosition:
            # move the entire frame
            newCanvasPos = item.pos() + (mouseEvent.pos() -
                                         self.lastMousePosition)
            if annotation.hasFixedMapPosition():
                deltaX = pixelToMmScale * (mouseEvent.pos().x() -
                                           self.lastMousePosition.x())
                deltaY = pixelToMmScale * (mouseEvent.pos().y() -
                                           self.lastMousePosition.y())
                annotation.setFrameOffsetFromReferencePointMm(
                    QPointF(
                        annotation.frameOffsetFromReferencePointMm().x() +
                        deltaX,
                        annotation.frameOffsetFromReferencePointMm().y() +
                        deltaY))
                annotation.setRelativePosition(
                    QPointF(newCanvasPos.x() / self.canvas.width(),
                            newCanvasPos.y() / self.canvas.height()))
                item.update()
                QgsProject.instance().setDirty(True)

        elif self.currentMoveAction != QgsMapCanvasAnnotationItem.NoAction:
            # handle vertical frame resize actions only
            size = annotation.frameSizeMm()
            xmin = annotation.frameOffsetFromReferencePointMm().x()
            ymin = annotation.frameOffsetFromReferencePointMm().y()
            xmax = xmin + size.width()
            ymax = ymin + size.height()
            relPosX = annotation.relativePosition().x()
            relPosY = annotation.relativePosition().y()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightUp):
                ymin += pixelToMmScale * (mouseEvent.pos().y() -
                                          self.lastMousePosition.y())
                relPosY = (relPosY * self.canvas.height() +
                           mouseEvent.pos().y() -
                           self.lastMousePosition.y()) / self.canvas.height()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameDown
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftDown
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightDown):
                ymax += pixelToMmScale * (mouseEvent.pos().y() -
                                          self.lastMousePosition.y())

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeft
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftDown):
                xmin += pixelToMmScale * (mouseEvent.pos().x() -
                                          self.lastMousePosition.x())
                relPosX = (relPosX * self.canvas.width() +
                           mouseEvent.pos().x() -
                           self.lastMousePosition.x()) / self.canvas.width()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRight
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightDown):
                xmax += pixelToMmScale * (mouseEvent.pos().x() -
                                          self.lastMousePosition.x())

            # switch min / max if necessary
            if xmax < xmin:
                tmp = xmax
                xmax = xmin
                xmin = tmp
            if ymax < ymin:
                tmp = ymax
                ymax = ymin
                ymin = tmp
            annotation.setFrameOffsetFromReferencePointMm(QPointF(xmin, ymin))
            annotation.setFrameSizeMm(QSizeF(xmax - xmin, ymax - ymin))
            annotation.setRelativePosition(QPointF(relPosX, relPosY))
            item.update()
            QgsProject.instance().setDirty(True)

        moveAction = item.moveActionForPosition(mouseEvent.pos())
        cursor = QCursor()
        cursor.setShape(item.cursorShapeForAction(moveAction))
        self.setCursor(cursor)

        self.lastMousePosition = mouseEvent.pos()

    def canvasReleaseEvent(self, mouseEvent):
        self.currentMoveAction = QgsMapCanvasAnnotationItem.NoAction
        self.setCursor(self.cursor)

        results = self.identify(mouseEvent.x(), mouseEvent.y(),
                                self.selectionMode, self.VectorLayer)
        for r in results:
            # TODO: filter out features in layers that aren't relevant
            if False:
                continue

            layer = r.mLayer
            feature = r.mFeature

            a = QgsHtmlAnnotation()
            a.setMapLayer(layer)
            html = os.path.join(os.path.dirname(__file__), 'html',
                                'current_predictions_annotation.html')
            a.setSourceFile(html)
            a.setAssociatedFeature(feature)

            # TODO: this size and offset are wack. Can we dynamically calculate from the content somehow?
            a.setFrameSize(QSizeF(270, 160))
            a.setFrameOffsetFromReferencePoint(QPointF(-300, -200))
            a.setMapPosition(feature.geometry().asPoint())
            a.setMapPositionCrs(QgsCoordinateReferenceSystem(layer.crs()))

            # disable its symbol
            for symbol in a.markerSymbol().symbolLayers():
                symbol.setEnabled(False)

            QgsProject.instance().annotationManager().addAnnotation(a)

            # select the just-created annotation to make it easy to move or resize
            item = self.itemForAnnotation(a)
            if item:
                self.canvas.scene().clearSelection()
                item.setSelected(True)
            break

    def keyPressEvent(self, keyEvent):
        item = self.selectedItem()
        if item:
            if keyEvent.key() == Qt.Key_Backspace or keyEvent.key(
            ) == Qt.Key_Delete:
                QgsProject.instance().annotationManager().removeAnnotation(
                    item.annotation())
                self.setCursor(self.cursor)
                keyEvent.ignore()

    def selectedItem(self):
        for item in self.canvas.annotationItems():
            if item.isSelected():
                return item
        return None

    def itemAtPos(self, point):
        for item in self.canvas.annotationItems():
            if item.moveActionForPosition(
                    point) == QgsMapCanvasAnnotationItem.MoveFramePosition:
                return item
        return None

    def itemForAnnotation(self, annotation):
        for item in self.canvas.annotationItems():
            if item.annotation() == annotation:
                return item
        return None
class GwParentMapTool(QgsMapTool):
	def __init__(self, icon_path, text, toolbar, action_group, iface, settings, controller, plugin_dir):
		
		self.iface = iface
		self.settings = settings
		self.controller = controller
		self.plugin_dir = plugin_dir
		
		self.show_help = bool(int(self.settings.value('status/show_help', 1)))
		self.layer_arc = None
		self.layer_connec = None
		self.layer_gully = None
		self.layer_node = None
		self.snapper_manager = SnappingConfigManager(self.iface)
		self.snapper_manager.controller = controller
		
		self.canvas = iface.mapCanvas()
		super().__init__(self.canvas)
		
		
		icon = None
		if os.path.exists(icon_path):
			icon = QIcon(icon_path)
		
		self.action = None
		if icon is None:
			self.action = QAction(text, action_group)
		else:
			self.action = QAction(icon, text, action_group)
			
		self.action.setObjectName(text)
		self.action.setCheckable(True)
		self.action.triggered.connect(self.clicked_event)
		
		# Change map tool cursor
		self.cursor = QCursor()
		self.cursor.setShape(Qt.CrossCursor)
		
		# Get default cursor
		# noinspection PyCallingNonCallable
		self.std_cursor = self.parent().cursor()
		
		# Set default vertex marker
		color = QColor(255, 100, 255)
		self.vertex_marker = QgsVertexMarker(self.canvas)
		self.vertex_marker.setIconType(QgsVertexMarker.ICON_CIRCLE)
		self.vertex_marker.setColor(color)
		self.vertex_marker.setIconSize(15)
		self.vertex_marker.setPenWidth(3)
		
		# Set default rubber band
		color_selection = QColor(254, 178, 76, 63)
		self.rubber_band = QgsRubberBand(self.canvas, 2)
		self.rubber_band.setColor(color)
		self.rubber_band.setFillColor(color_selection)
		self.rubber_band.setWidth(1)
		self.reset()
		
		self.force_active_layer = True
		
		toolbar.addAction(self.action)
		self.setAction(self.action)
	
	
	def clicked_event(self):
		self.controller.prev_maptool = self.iface.mapCanvas().mapTool()
		if not (self == self.iface.mapCanvas().mapTool()):
			self.iface.mapCanvas().setMapTool(self)
		else:
			self.iface.mapCanvas().unsetMapTool(self)
			
	
	def deactivate(self):
	
		# Uncheck button
		self.action.setChecked(False)
		
		# Restore previous snapping
		self.snapper_manager.recover_snapping_options()
		
		# Enable snapping
		self.snapper_manager.enable_snapping(True)
		
		# Recover cursor
		self.canvas.setCursor(self.std_cursor)
		
		# Remove highlight
		self.vertex_marker.hide()
	
	
	def canvasMoveEvent(self, event):
	
		# Make sure active layer is always 'v_edit_node'
		cur_layer = self.iface.activeLayer()
		if cur_layer != self.layer_node and self.force_active_layer:
			self.iface.setActiveLayer(self.layer_node)
		
		# Hide highlight and get coordinates
		self.vertex_marker.hide()
		event_point = self.snapper_manager.get_event_point(event)
		
		# Snapping
		result = self.snapper_manager.snap_to_current_layer(event_point)
		if self.snapper_manager.result_is_valid():
			self.snapper_manager.add_marker(result, self.vertex_marker)
	
	
	def recover_previus_maptool(self):
		if self.controller.prev_maptool:
			self.iface.mapCanvas().setMapTool(self.controller.prev_maptool)
			self.controller.prev_maptool = None
	
	
	def remove_vertex(self):
		""" Remove vertex_marker from canvas"""
		vertex_items = [i for i in self.iface.mapCanvas().scene().items() if issubclass(type(i), QgsVertexMarker)]
		
		for ver in vertex_items:
			if ver in self.iface.mapCanvas().scene().items():
				if self.vertex_marker == ver:
					self.iface.mapCanvas().scene().removeItem(ver)
	
	
	def set_action_pan(self):
		""" Set action 'Pan' """
		try:
			self.iface.actionPan().trigger()
		except Exception:
			pass
	
	
	def reset_rubber_band(self, geom_type="polygon"):
		
		try:
			if geom_type == "polygon":
				geom_type = QgsWkbTypes.PolygonGeometry
			elif geom_type == "line":
				geom_type = QgsWkbTypes.LineString
			self.rubber_band.reset(geom_type)
		except:
			pass
	
	
	def reset(self):
	
		self.reset_rubber_band()
		self.snapped_feat = None
	
	
	def cancel_map_tool(self):
		""" Executed if user press right button or escape key """
		
		# Reset rubber band
		self.reset()
		
		# Deactivate map tool
		self.deactivate()
		self.set_action_pan()
	
	
	def remove_markers(self):
		""" Remove previous markers """
		
		vertex_items = [i for i in list(self.canvas.scene().items()) if issubclass(type(i), QgsVertexMarker)]
		for ver in vertex_items:
			if ver in list(self.canvas.scene().items()):
				self.canvas.scene().removeItem(ver)
	
	
	def refresh_map_canvas(self):
		""" Refresh all layers present in map canvas """
		
		self.canvas.refreshAllLayers()
		for layer_refresh in self.canvas.layers():
			layer_refresh.triggerRepaint()
Beispiel #17
0
class GwMaptool(QgsMapTool):
    def __init__(self,
                 icon_path,
                 action_name,
                 text,
                 toolbar,
                 action_group,
                 icon_type=4):

        self.iface = global_vars.iface
        self.canvas = global_vars.canvas
        self.schema_name = global_vars.schema_name
        self.settings = global_vars.giswater_settings
        self.plugin_dir = global_vars.plugin_dir
        self.project_type = global_vars.project_type
        self.show_help = tools_gw.get_config_parser('system', 'show_help',
                                                    "project", "giswater")
        self.layer_arc = None
        self.layer_connec = None
        self.layer_gully = None
        self.layer_node = None

        self.snapper_manager = GwSnapManager(self.iface)
        self.previous_snapping = self.snapper_manager.get_snapping_options()

        super().__init__(self.canvas)

        # Change map tool cursor
        self.cursor = QCursor()
        self.cursor.setShape(Qt.CrossCursor)

        # Get default cursor
        # noinspection PyCallingNonCallable
        self.std_cursor = self.parent().cursor()

        # Set default vertex marker
        self.vertex_marker = self.snapper_manager.vertex_marker
        self.snapper_manager.set_vertex_marker(self.vertex_marker,
                                               icon_type=icon_type)

        # Set default rubber band
        color = QColor(255, 100, 255)
        color_selection = QColor(254, 178, 76, 63)
        self.rubber_band = tools_gw.create_rubberband(self.canvas, 2)
        self.rubber_band.setColor(color)
        self.rubber_band.setFillColor(color_selection)
        self.rubber_band.setWidth(1)
        self.reset()
        self.force_active_layer = True

        if toolbar is None:
            return

        self.action = None

        icon = None
        if os.path.exists(icon_path):
            icon = QIcon(icon_path)
        if icon is None:
            self.action = QAction(text, action_group)
        else:
            self.action = QAction(icon, text, action_group)

        self.action.setObjectName(action_name)
        self.action.setCheckable(True)
        self.action.triggered.connect(self.clicked_event)
        toolbar.addAction(self.action)
        self.setAction(self.action)

    def clicked_event(self):

        selected_maptool = self.iface.mapCanvas().mapTool()
        self.prev_maptool = selected_maptool
        if not self == selected_maptool:
            self.iface.mapCanvas().setMapTool(self)

    def deactivate(self):

        # Uncheck button
        if hasattr(
                self.action, "setChecked"
        ):  # If the maptool is activated through the giswater menu, it breaks
            self.action.setChecked(False)

        # Restore previous snapping
        self.snapper_manager.restore_snap_options(self.previous_snapping)

        # Enable snapping
        self.snapper_manager.set_snapping_status(True)

        # Recover cursor
        self.canvas.setCursor(self.std_cursor)

        # Remove highlight
        self.vertex_marker.hide()

    def canvasMoveEvent(self, event):

        # Make sure active layer is always 'v_edit_node'
        cur_layer = self.iface.activeLayer()
        if cur_layer != self.layer_node and self.force_active_layer:
            self.iface.setActiveLayer(self.layer_node)

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

        # Snapping
        result = self.snapper_manager.snap_to_current_layer(event_point)
        if result.isValid():
            self.snapper_manager.add_marker(result, self.vertex_marker)

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Escape:
            self.cancel_map_tool()
            return

    def canvasReleaseEvent(self, event):

        if event.button() == Qt.RightButton:
            self.cancel_map_tool()

    def recover_previus_maptool(self):

        if self.prev_maptool:
            self.iface.mapCanvas().setMapTool(self.prev_maptool)
            self.prev_maptool = None

    def set_action_pan(self):
        """ Set action 'Pan' """

        try:
            self.iface.actionPan().trigger()
        except Exception:
            pass

    def reset_rubber_band(self, geom_type="polygon"):

        if geom_type == "polygon":
            geom_type = QgsWkbTypes.PolygonGeometry
        elif geom_type == "line":
            geom_type = QgsWkbTypes.LineGeometry
        self.rubber_band.reset(geom_type)

    def reset(self):

        self.reset_rubber_band()
        self.snapped_feat = None

    def cancel_map_tool(self):
        """ Executed if user press right button or escape key """

        # Reset rubber band
        self.reset()

        # Deactivate map tool
        self.deactivate()

        # Set action pan
        self.set_action_pan()

    def refresh_map_canvas(self):
        """ Refresh all layers present in map canvas """

        self.canvas.refreshAllLayers()
        for layer_refresh in self.canvas.layers():
            layer_refresh.triggerRepaint()

    def manage_active_maptool(self):
        """ Check in init config file if user wants to keep map tool active or not """

        value = tools_gw.get_config_parser('user_edit_tricks',
                                           'keep_maptool_active',
                                           "user",
                                           "init",
                                           prefix=True)
        keep_maptool_active = tools_os.set_boolean(value, False)
        if not keep_maptool_active:
            self.cancel_map_tool()