class Start: def __init__(self, iface): self.name = "OPEN_FTTH" self.iface = iface self.autosave_enabled = False self.route_segment_layer = None self.route_node_layer = None self.websocket = BridgeWebsocket(self.iface) self.identifyHighlight = None self.last_identified_feature_mrid = None self.last_identified_feature_type = None self.event_handler = EventHandler(self.iface, self.websocket.websocket, self) self.websocket.messageReceived.connect(self.event_handler.handle) self.identifyNetworkElementHandler = IdentifyNetworkElementHandler( self.websocket) self.retrieve_selected_handler = RetrieveSelectedHandler( self.iface, self.websocket) self.application_settings = ApplicationSettings() self.layers_loaded = False def initGui(self): self.setupActions() self.iface.layerTreeView().currentLayerChanged.connect( self.layersLoaded) self.iface.layerTreeView().currentLayerChanged.connect( self.layerSelectionChange) def setupActions(self): self.actions = [] icon_auto_save = ":/plugins/open_ftth/auto_save.svg" self.autosave_action = QAction(QtGui.QIcon(icon_auto_save), "Autosave", self.iface.mainWindow()) self.autosave_action.setCheckable(True) self.autosave_action.triggered.connect(self.setupAutoSave) auto_identify = ":/plugins/open_ftth/auto_identify.svg" self.select_action = QAction(QtGui.QIcon(auto_identify), "Select", self.iface.mainWindow()) self.select_action.setCheckable(True) self.select_action.triggered.connect(self.setupSelectTool) web_browser = ":/plugins/open_ftth/browser_icon.svg" self.web_browser_action = QAction(QtGui.QIcon(web_browser), "Web-browser", self.iface.mainWindow()) self.web_browser_action.setCheckable(False) self.web_browser_action.triggered.connect(self.connectWebBrowser) paste_geometry = ":/plugins/open_ftth/paste_geometry.svg" self.paste_geometry_action = QAction(QtGui.QIcon(paste_geometry), "Paste geometry", self.iface.mainWindow()) self.paste_geometry_action.setCheckable(False) self.paste_geometry_action.triggered.connect(self.pasteGeometry) self.iface.addPluginToMenu("&OPEN FTTH", self.select_action) self.iface.addToolBarIcon(self.autosave_action) self.iface.addToolBarIcon(self.select_action) self.iface.addToolBarIcon(self.web_browser_action) self.iface.addToolBarIcon(self.paste_geometry_action) self.identify_tool = IdentifySelect(self.iface.mapCanvas()) self.identify_tool.identified.connect(self.onIdentified) self.identify_tool.identifiedNone.connect(self.onIdentifiedNone) self.buildActionListIdentifyTool() def buildActionListIdentifyTool(self): actionList = self.iface.mapNavToolToolBar().actions() # Add actions from QGIS attributes toolbar (handling QWidgetActions) tmpActionList = self.iface.attributesToolBar().actions() for action in tmpActionList: if isinstance(action, QWidgetAction): actionList.extend(action.defaultWidget().actions()) else: actionList.append(action) tmpActionList = self.iface.digitizeToolBar().actions() for action in tmpActionList: if isinstance(action, QWidgetAction): actionList.extend(action.defaultWidget().actions()) else: actionList.append(action) tmpActionList = self.iface.selectionToolBar().actions() for action in tmpActionList: if isinstance(action, QWidgetAction): actionList.extend(action.defaultWidget().actions()) else: actionList.append(action) # Build a group with actions from actionList and add your own action group = QActionGroup(self.iface.mainWindow()) group.setExclusive(True) for action in actionList: group.addAction(action) group.addAction(self.select_action) def unload(self): for action in self.actions: self.iface.removeToolBarIcon(action) self.autosave_action.setChecked(False) self.select_action.setChecked(False) self.autosave_enabled = False self.select_tool_enabled = False try: self.disconnectSelectedFeatures() self.disconnectSelectTool() self.websocket.close() self.route_segment_layer.beforeCommitChanges.disconnect( self.preCommitDeleteHandlerRouteSegment) self.route_node_layer.beforeCommitChanges.disconnect( self.preCommitDeleteHandlerRouteNode) self.route_node_layer.featuresDeleted.disconnect( self.checkFeaturesDeleted) self.route_segment_layer.featuresDeleted.disconnect( self.checkFeaturesDeleted) except Exception: pass def setupSelectTool(self): self.iface.mapCanvas().setMapTool(self.identify_tool) def sendSelectedFeatures(self): self.getSelectedFeaturesHandler.handle() def setupAutoSave(self): if self.autosave_enabled is False: self.connectAutosave() self.saveActiveLayerEdits() else: self.disconnectAutosave() def layersLoaded(self): if not self.hasCorrectLayers(): self.onIdentifiedNone() return if self.layers_loaded is False: self.websocket.start() self.layers_loaded = True self.route_segment_layer = QgsProject.instance().mapLayersByName( ApplicationSettings().get_layers_route_segment_name())[0] self.route_node_layer = QgsProject.instance().mapLayersByName( ApplicationSettings().get_layers_route_node_name())[0] try: self.route_node_layer.featuresDeleted.connect( self.checkFeaturesDeleted) self.route_segment_layer.featuresDeleted.connect( self.checkFeaturesDeleted) except TypeError: pass try: self.route_segment_layer.beforeCommitChanges.connect( self.preCommitDeleteHandlerRouteSegment) self.route_node_layer.beforeCommitChanges.connect( self.preCommitDeleteHandlerRouteNode) except TypeError: pass def layerSelectionChange(self): if not self.hasCorrectLayers(): self.onIdentifiedNone() return self.route_segment_layer = QgsProject.instance().mapLayersByName( ApplicationSettings().get_layers_route_segment_name())[0] try: self.route_segment_layer.selectionChanged.disconnect( self.onSelectedSegment) except TypeError: pass self.route_segment_layer.selectionChanged.connect( self.onSelectedSegment) def hasCorrectLayers(self): route_segment_layers = QgsProject.instance().mapLayersByName( ApplicationSettings().get_layers_route_segment_name()) route_node_layers = QgsProject.instance().mapLayersByName( ApplicationSettings().get_layers_route_node_name()) return len(route_segment_layers) > 0 and len(route_node_layers) > 0 def connectAutosave(self): # We do this to avoid plugin crash in case that connects come in an invalid state. try: self.route_segment_layer = QgsProject.instance().mapLayersByName( ApplicationSettings().get_layers_route_segment_name())[0] self.route_segment_layer.layerModified.connect( self.saveActiveLayerEdits) except TypeError: pass # We do this to avoid plugin crash in case that connects come in an invalid state. try: self.route_node_layer = QgsProject.instance().mapLayersByName( ApplicationSettings().get_layers_route_node_name())[0] self.route_node_layer.layerModified.connect( self.saveActiveLayerEdits) except TypeError: pass self.autosave_enabled = True def disconnectAutosave(self): # We do this to avoid plugin crash in case that connects come in an invalid state. try: self.route_segment_layer.layerModified.disconnect( self.saveActiveLayerEdits) except TypeError: pass # We do this to avoid plugin crash in case that connects come in an invalid state. try: self.route_node_layer.layerModified.disconnect( self.saveActiveLayerEdits) except TypeError: pass self.autosave_action.setChecked(False) self.autosave_enabled = False def connectWebBrowser(self): webbrowser.open(self.application_settings.get_website_url(), new=2) def saveActiveLayerEdits(self): self.iface.actionSaveActiveLayerEdits().trigger() def onSelectedSegment(self): message = type( 'Expando', (object, ), {'username': self.application_settings.get_user_name_prefix()})() self.retrieve_selected_handler.handle(message) def checkFeaturesDeleted(self, fids): if self.last_identified_feature_mrid is None: return features = None filterExpression = f'"mrid" = \'{self.last_identified_feature_mrid}\'' if self.last_identified_feature_type == self.application_settings.get_types_route_node( ): features = self.route_node_layer.getFeatures( QgsFeatureRequest().setFilterExpression(filterExpression)) elif self.last_identified_feature_type == self.application_settings.get_types_route_segment( ): features = self.route_segment_layer.getFeatures( QgsFeatureRequest().setFilterExpression(filterExpression)) else: return # hack because the deleted signal is triggered on both create and delete stillExists = False for feature in features: stillExists = True if not stillExists: self.onIdentifiedNone() self.identifyNetworkElementHandler.handle(None, None) # end of hack def onIdentified(self, selected_layer, selected_feature): selected_type = "" if self.application_settings.get_layers_route_node_name( ) == selected_layer.sourceName(): selected_type = self.application_settings.get_types_route_node() elif self.application_settings.get_layers_route_segment_name( ) == selected_layer.sourceName(): selected_type = self.application_settings.get_types_route_segment() else: self.identifyHighlight.hide() return if self.identifyHighlight is not None: self.identifyHighlight.hide() color = QColor(0, 255, 0) self.identifyHighlight = QgsHighlight(self.iface.mapCanvas(), selected_feature.geometry(), selected_layer) self.identifyHighlight.setWidth(3) self.identifyHighlight.setColor(color) self.identifyHighlight.show() mrid = selected_feature.attribute("mrid") self.last_identified_feature_mrid = mrid self.last_identified_feature_type = selected_type if selected_type != "": self.identifyNetworkElementHandler.handle(mrid, selected_type) def onIdentifiedNone(self): if self.identifyHighlight is not None: self.last_identified_feature_mrid = None self.last_identified_feature_type = None self.identifyHighlight.hide() def preCommitDeleteHandlerRouteSegment(self): self.undoDeleteSetMarkedToBeDeleted( ApplicationSettings().get_layers_route_segment_name()) def preCommitDeleteHandlerRouteNode(self): self.undoDeleteSetMarkedToBeDeleted( ApplicationSettings().get_layers_route_node_name()) def undoDeleteSetMarkedToBeDeleted(self, layerName): layers = QgsProject.instance().mapLayersByName(layerName) if len(layers) != 1: return layer = layers[0] deleted_features_ids = layer.editBuffer().deletedFeatureIds() for feature_id in deleted_features_ids: QgsVectorLayerUndoCommandDeleteFeature(layer.editBuffer(), feature_id).undo() marked_to_be_deleted_idx = layer.fields().indexOf( 'marked_to_be_deleted') user_name_idx = layer.fields().indexOf('user_name') user_name = self.application_settings.get_user_name() for feature in layer.dataProvider().getFeatures( QgsFeatureRequest().setFilterFids(deleted_features_ids)): layer.changeAttributeValue(feature.id(), marked_to_be_deleted_idx, True) layer.changeAttributeValue(feature.id(), user_name_idx, user_name) def pasteGeometry(self): layer = self.iface.activeLayer() route_segment_layer_name = self.application_settings.get_layers_route_segment_name( ) if layer.sourceName() != route_segment_layer_name: self.showBarMessage( "You can only paste a geometry when layer %s is selected." % route_segment_layer_name, Qgis.Warning) return if not layer.isEditable(): self.showBarMessage( "You need to be in edit mode to paste the geometry.", Qgis.Warning) return geoms = self.tryGetFeaturesGeomsFromClipBoard() if len(geoms) > 1: self.showBarMessage( "Can't paste geometry multiple features in clipboard.", Qgis.Warning) return if len(geoms) == 0: self.showBarMessage( "Can't paste geometry. No features in clipboard.", Qgis.Warning) return selected_features_iter = layer.getSelectedFeatures() selected_features = [] for selected_feature in selected_features_iter: selected_features.append(selected_feature) if len(selected_features) == 0: self.showBarMessage("Can't paste. No target feature to paste to.", Qgis.Warning) return # Paste is the comment we want to paste to paste_feature = selected_features[0] paste_geom = paste_feature.geometry() # Copy is the geom from the clipboard that we want "paste" to resemble. copy_geom = geoms[0] if paste_geom.type() != copy_geom.type(): self.showBarMessage( "Not the same geometry type. From %s to %s" % (copy_geom.type(), paste_geom.type()), Qgis.Warning) return paste_geom_start = paste_geom.asPolyline()[0] paste_geom_end = paste_geom.asPolyline()[len(paste_geom.asPolyline()) - 1] copy_geom_start = copy_geom.asPolyline()[0] copy_geom_end = copy_geom.asPolyline()[len(copy_geom.asPolyline()) - 1] start_to_start_distance = paste_geom_start.distance(copy_geom_start) start_to_end_distance = paste_geom_start.distance(copy_geom_end) new_copy_polyline = copy_geom.asPolyline() if start_to_start_distance > start_to_end_distance: QgsMessageLog.logMessage( "The geometries are flipped, we reverse them for the copy.", self.name, Qgis.Info) new_copy_polyline.reverse() # Its important that we do this after, in case that the geometry is reversed. new_copy_geom_start = new_copy_polyline[0] new_copy_geom_end = new_copy_polyline[len(new_copy_polyline) - 1] new_start_to_start_distance = paste_geom_start.distance( new_copy_geom_start) if self.application_settings.get_tolerance( ) < new_start_to_start_distance: self.showBarMessage( "Start point distance is bigger than tolerance.", Qgis.Critical) return new_start_to_end_distance = paste_geom_end.distance(new_copy_geom_end) if self.application_settings.get_tolerance( ) < new_start_to_end_distance: self.showBarMessage( "End points distance is bigger than tolerance.", Qgis.Critical) return # We update the geometry. result = layer.changeGeometry( paste_feature.id(), QgsGeometry.fromPolylineXY(new_copy_polyline)) # We change the mapping method to LandSurveying to identify that the polyline now matches the landsurvey polyline. mapping_method_idx = layer.fields().indexOf('mapping_method') layer.changeAttributeValue(paste_feature.id(), mapping_method_idx, "LandSurveying") if not result: self.showBarMessage("Can't paste geometry, something went wrong.", Qgis.Critical) return self.iface.mapCanvas().refresh() def tryGetFeaturesGeomsFromClipBoard(self): cb = QApplication.clipboard() clipboard_text = cb.text() if sys.version_info[0] == 2: clipboard_text = clipboard_text.encode('utf-8') reader = csv.DictReader(StringIO(clipboard_text), delimiter='\t') geoms = [] for row in reader: wkt_geom = row.get('wkt_geom') geom = QgsGeometry.fromWkt(wkt_geom) if not geom: self.showBarMessage( 'Can\'t create geometry from wkt: %s' % wkt_geom, Qgis.Critical) return [] geoms.append(geom) return geoms def showBarMessage(self, message, level=Qgis.Info, duration=-1): self.iface.messageBar().pushMessage("Error", message, level=level, duration=duration)
class FeatureSelectorWidget(QWidget): feature_identified = pyqtSignal(QgsFeature) def __init__(self, parent): QWidget.__init__(self, parent) edit_layout = QHBoxLayout() edit_layout.setContentsMargins(0, 0, 0, 0) edit_layout.setSpacing(2) self.setLayout(edit_layout) self.line_edit = QLineEdit(self) self.line_edit.setReadOnly(True) edit_layout.addWidget(self.line_edit) self.highlight_feature_button = QToolButton(self) self.highlight_feature_button.setPopupMode(QToolButton.MenuButtonPopup) self.highlight_feature_action = QAction( QgsApplication.getThemeIcon("/mActionHighlightFeature.svg"), "Highlight feature", self) self.scale_highlight_feature_action = QAction( QgsApplication.getThemeIcon("/mActionScaleHighlightFeature.svg"), "Scale and highlight feature", self) self.pan_highlight_feature_action = QAction( QgsApplication.getThemeIcon("/mActionPanHighlightFeature.svg"), "Pan and highlight feature", self) self.highlight_feature_button.addAction(self.highlight_feature_action) self.highlight_feature_button.addAction( self.scale_highlight_feature_action) self.highlight_feature_button.addAction( self.pan_highlight_feature_action) self.highlight_feature_button.setDefaultAction( self.highlight_feature_action) edit_layout.addWidget(self.highlight_feature_button) self.map_identification_button = QToolButton(self) self.map_identification_button.setIcon( QgsApplication.getThemeIcon("/mActionMapIdentification.svg")) self.map_identification_button.setText("Select on map") self.map_identification_button.setCheckable(True) edit_layout.addWidget(self.map_identification_button) self.map_identification_button.clicked.connect(self.map_identification) self.highlight_feature_button.triggered.connect( self.highlight_action_triggered) self.layer = None self.map_tool = None self.canvas = None self.window_widget = None self.highlight = None self.feature = QgsFeature() def set_canvas(self, map_canvas): self.map_tool = QgsMapToolIdentifyFeature(map_canvas) self.map_tool.setButton(self.map_identification_button) self.canvas = map_canvas def set_layer(self, layer): self.layer = layer def set_feature(self, feature, canvas_extent=CanvasExtent.Fixed): self.line_edit.clear() self.feature = feature if self.feature is None or not self.feature.isValid( ) or self.layer is None: return expression = QgsExpression(self.layer.displayExpression()) context = QgsExpressionContext() scope = QgsExpressionContextScope() context.appendScope(scope) scope.setFeature(feature) feature_title = expression.evaluate(context) if feature_title == "": feature_title = feature.id() self.line_edit.setText(str(feature_title)) self.highlight_feature(canvas_extent) def clear(self): self.feature = QgsFeature() self.line_edit.clear() @pyqtSlot() def map_identification(self): if self.layer is None or self.map_tool is None or self.canvas is None: return self.map_tool.setLayer(self.layer) self.canvas.setMapTool(self.map_tool) self.window_widget = QWidget.window(self) self.canvas.window().raise_() self.canvas.activateWindow() self.canvas.setFocus() self.map_tool.featureIdentified.connect( self.map_tool_feature_identified) self.map_tool.deactivated.connect(self.map_tool_deactivated) def map_tool_feature_identified(self, feature): feature = QgsFeature(feature) self.feature_identified.emit(feature) self.unset_map_tool() self.set_feature(feature) def map_tool_deactivated(self): if self.window_widget is not None: self.window_widget.raise_() self.window_widget.activateWindow() def highlight_feature(self, canvas_extent=CanvasExtent.Fixed): if self.canvas is None or not self.feature.isValid(): return geom = self.feature.geometry() if geom is None: return if canvas_extent == CanvasExtent.Scale: feature_bounding_box = geom.boundingBox() feature_bounding_box = self.canvas.mapSettings( ).layerToMapCoordinates(self.layer, feature_bounding_box) extent = self.canvas.extent() if not extent.contains(feature_bounding_box): extent.combineExtentWith(feature_bounding_box) extent.scale(1.1) self.canvas.setExtent(extent) self.canvas.refresh() elif canvas_extent == CanvasExtent.Pan: centroid = geom.centroid() center = centroid.asPoint() center = self.canvas.mapSettings().layerToMapCoordinates( self.layer, center) self.canvas.zoomByFactor(1.0, center) # refresh is done in this method # highlight self.delete_highlight() self.highlight = QgsHighlight(self.canvas, geom, self.layer) settings = QSettings() color = QColor( settings.value("/Map/highlight/color", Qgis.DEFAULT_HIGHLIGHT_COLOR.name())) alpha = int( settings.value("/Map/highlight/colorAlpha", Qgis.DEFAULT_HIGHLIGHT_COLOR.alpha())) buffer = 2 * float( settings.value("/Map/highlight/buffer", Qgis.DEFAULT_HIGHLIGHT_BUFFER_MM)) min_width = 2 * float( settings.value("/Map/highlight/min_width", Qgis.DEFAULT_HIGHLIGHT_MIN_WIDTH_MM)) self.highlight.setColor(color) # sets also fill with default alpha color.setAlpha(alpha) self.highlight.setFillColor(color) # sets fill with alpha self.highlight.setBuffer(buffer) self.highlight.setMinWidth(min_width) self.highlight.setWidth(4.0) self.highlight.show() self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.timeout.connect(self.delete_highlight) self.timer.start(3000) def delete_highlight(self): if self.highlight is not None: self.highlight.hide() del self.highlight self.highlight = None def unset_map_tool(self): if self.canvas is not None and self.map_tool is not None: # this will call mapTool.deactivated self.canvas.unsetMapTool(self.map_tool) def highlight_action_triggered(self, action): self.highlight_feature_button.setDefaultAction(action) if action == self.highlight_feature_action: self.highlight_feature() elif action == self.scale_highlight_feature_action: self.highlight_feature(CanvasExtent.Scale) elif action == self.pan_highlight_feature_action: self.highlight_feature(CanvasExtent.Pan)
class FeatureSelectorWidget(QWidget): featureIdentified = pyqtSignal(QgsFeature) def __init__(self, parent): QWidget.__init__(self, parent) editLayout = QHBoxLayout() editLayout.setContentsMargins(0, 0, 0, 0) editLayout.setSpacing(2) self.setLayout(editLayout) self.lineEdit = QLineEdit(self) self.lineEdit.setReadOnly(True) editLayout.addWidget(self.lineEdit) self.highlightFeatureButton = QToolButton(self) self.highlightFeatureButton.setPopupMode(QToolButton.MenuButtonPopup) self.highlightFeatureAction = QAction(QgsApplication.getThemeIcon("/mActionHighlightFeature.svg"), "Highlight feature", self) self.scaleHighlightFeatureAction = QAction(QgsApplication.getThemeIcon("/mActionScaleHighlightFeature.svg"), "Scale and highlight feature", self) self.panHighlightFeatureAction = QAction(QgsApplication.getThemeIcon("/mActionPanHighlightFeature.svg"), "Pan and highlight feature", self) self.highlightFeatureButton.addAction(self.highlightFeatureAction) self.highlightFeatureButton.addAction(self.scaleHighlightFeatureAction) self.highlightFeatureButton.addAction(self.panHighlightFeatureAction) self.highlightFeatureButton.setDefaultAction(self.highlightFeatureAction) editLayout.addWidget(self.highlightFeatureButton) self.mapIdentificationButton = QToolButton(self) self.mapIdentificationButton.setIcon(QgsApplication.getThemeIcon("/mActionMapIdentification.svg")) self.mapIdentificationButton.setText("Select on map") self.mapIdentificationButton.setCheckable(True) editLayout.addWidget(self.mapIdentificationButton) self.mapIdentificationButton.clicked.connect(self.mapIdentification) self.highlightFeatureButton.triggered.connect(self.highlightActionTriggered) self.layer = None self.mapTool = None self.canvas = None self.windowWidget = None self.highlight = None self.feature = QgsFeature() def setCanvas(self, mapCanvas): self.mapTool = QgsMapToolIdentifyFeature(mapCanvas) self.mapTool.setButton(self.mapIdentificationButton) self.canvas = mapCanvas def setLayer(self, layer): self.layer = layer def setFeature(self, feature, canvasExtent = CanvasExtent.Fixed): self.lineEdit.clear() self.feature = feature if not self.feature.isValid() or self.layer is None: return featureTitle = feature.attribute(self.layer.displayField()) if featureTitle == '': featureTitle = feature.id() self.lineEdit.setText(str(featureTitle)) self.highlightFeature(canvasExtent) def clear(self): self.feature = QgsFeature() self.lineEdit.clear() def mapIdentification(self): if self.layer is None or self.mapTool is None or self.canvas is None: return self.mapTool.setLayer(self.layer) self.canvas.setMapTool(self.mapTool) self.windowWidget = QWidget.window(self) self.canvas.window().raise_() self.canvas.activateWindow() self.canvas.setFocus() self.mapTool.featureIdentified.connect(self.mapToolFeatureIdentified) self.mapTool.deactivated.connect(self.mapToolDeactivated) def mapToolFeatureIdentified(self, feature): feature = QgsFeature(feature) self.featureIdentified.emit(feature) self.unsetMapTool() self.setFeature(feature) def mapToolDeactivated(self): if self.windowWidget is not None: self.windowWidget.raise_() self.windowWidget.activateWindow() def highlightFeature(self, canvasExtent = CanvasExtent.Fixed): if self.canvas is None or not self.feature.isValid(): return geom = self.feature.geometry() if geom is None: return if canvasExtent == CanvasExtent.Scale: featBBox = geom.boundingBox() featBBox = self.canvas.mapSettings().layerToMapCoordinates(self.layer, featBBox) extent = self.canvas.extent() if not extent.contains(featBBox): extent.combineExtentWith(featBBox) extent.scale(1.1) self.canvas.setExtent(extent) self.canvas.refresh() elif canvasExtent == CanvasExtent.Pan: centroid = geom.centroid() center = centroid.asPoint() center = self.canvas.mapSettings().layerToMapCoordinates(self.layer, center) self.canvas.zoomByFactor(1.0, center) # refresh is done in this method # highlight self.delete_highlight() self.highlight = QgsHighlight(self.canvas, geom, self.layer) settings = QSettings() color = QColor(settings.value("/Map/highlight/color", QGis.DEFAULT_HIGHLIGHT_COLOR.name())) alpha = int(settings.value("/Map/highlight/colorAlpha", QGis.DEFAULT_HIGHLIGHT_COLOR.alpha())) buffer = 2*float(settings.value("/Map/highlight/buffer", QGis.DEFAULT_HIGHLIGHT_BUFFER_MM)) min_width = 2*float(settings.value("/Map/highlight/min_width", QGis.DEFAULT_HIGHLIGHT_MIN_WIDTH_MM)) self.highlight.setColor(color) # sets also fill with default alpha color.setAlpha(alpha) self.highlight.setFillColor(color) # sets fill with alpha self.highlight.setBuffer(buffer) self.highlight.setMinWidth(min_width) self.highlight.setWidth(4.0) self.highlight.show() self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.timeout.connect(self.delete_highlight) self.timer.start(3000) def delete_highlight(self): if self.highlight is not None: self.highlight.hide() del self.highlight self.highlight = None def unsetMapTool(self): if self.canvas is not None and self.mapTool is not None: # this will call mapToolDeactivated self.canvas.unsetMapTool(self.mapTool) def highlightActionTriggered(self, action): self.highlightFeatureButton.setDefaultAction(action) if action == self.highlightFeatureAction: self.highlightFeature() elif action == self.scaleHighlightFeatureAction: self.highlightFeature(CanvasExtent.Scale) elif action == self.panHighlightFeatureAction: self.highlightFeature(CanvasExtent.Pan)