def __init__(self, iface): self.iface = iface self.canvas = iface.mapCanvas() QgsMapToolEmitPoint.__init__(self, self.canvas) self.rasterShadow = RasterShadowMapCanvasItem(self.canvas) self.firstPoint = None self.rubberBandOrigin = QgsRubberBand( self.canvas, QgsWkbTypes.PointGeometry) self.rubberBandOrigin.setColor(Qt.red) self.rubberBandOrigin.setIcon(QgsRubberBand.ICON_CIRCLE) self.rubberBandOrigin.setIconSize(7) self.rubberBandOrigin.setWidth(2) self.rubberBandDisplacement = QgsRubberBand( self.canvas, QgsWkbTypes.LineGeometry) self.rubberBandDisplacement.setColor(Qt.red) self.rubberBandDisplacement.setWidth(1) self.rubberBandExtent = QgsRubberBand( self.canvas, QgsWkbTypes.LineGeometry) self.rubberBandExtent.setColor(Qt.red) self.rubberBandExtent.setWidth(2) self.isLayerVisible = True self.reset()
def __init__(self, canvas, layer, column, bindto, radius ): QgsMapToolEmitPoint.__init__(self, canvas) self.layer = layer self.column = column self.bindto = bindto self.canvas = canvas self.bindto = bindto self.searchradius = radius self.canvasClicked.connect(self.findFeature) self.canvas.setMapTool(self) self.band = QgsRubberBand(self.canvas) self.band.setColor(Qt.blue) self.band.setWidth(3) self.rect = QgsRectangle() self.cursor = QCursor(QPixmap(["16 16 3 1", " c None", ". c #32CD32", "+ c #32CD32", " ", " +.+ ", " ++.++ ", " +.....+ ", " +. .+ ", " +. . .+ ", " +. . .+ ", " ++. . .++", " ... ...+... ...", " ++. . .++", " +. . .+ ", " +. . .+ ", " ++. .+ ", " ++.....+ ", " ++.++ ", " +.+ "]))
def __init__(self, canvas): QgsMapToolEmitPoint.__init__(self, canvas) self.canvas = canvas self.action = None self.canvas.mapToolSet.connect(self._toolChanged)
def __init__(self, canvas): self.canvas = canvas QgsMapToolEmitPoint.__init__(self, self.canvas) self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon) self.rubberBand.setColor(QColor(255, 0, 0, 180)) self.rubberBand.setWidth(1) self.reset()
def __init__(self, iface, couleur): self.canvas = iface.mapCanvas() QgsMapToolEmitPoint.__init__(self, self.canvas) self.iface = iface self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rb.setColor(couleur) self.reset() return None
def __init__(self, canvas): self.canvas = canvas QgsMapToolEmitPoint.__init__(self, self.canvas) self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rubberBand.setColor(QColor(255, 0, 0, 100)) self.rubberBand.setWidth(2) self.reset()
def __init__(self, settings, iface): QgsMapToolEmitPoint.__init__(self, iface.mapCanvas()) self.iface = iface self.canvas = iface.mapCanvas() self.settings = settings self.latlon = LatLon() self.capture4326 = False self.canvasClicked.connect(self.clicked) self.marker = None
def __init__(self, canvas, iface, dockwidget, currentMapTool): self.canvas = canvas self.iface = iface self.currentMapTool = currentMapTool self.dockwidget = dockwidget QgsMapToolEmitPoint.__init__(self, self.canvas) self.rubberBand = QgsRubberBand(self.canvas, QGis.Point) self.rubberBand.setColor(QColor(255,5,5)) self.rubberBand.setWidth(1) self.reset()
def __init__(self, iface): self.iface = iface self.canvas = iface.mapCanvas() QgsMapToolEmitPoint.__init__(self, self.canvas) self.rasterShadow = RasterShadowMapCanvasItem(self.canvas) self.rubberBandExtent = QgsRubberBand( self.canvas, QgsWkbTypes.LineGeometry) self.rubberBandExtent.setColor(Qt.red) self.rubberBandExtent.setWidth(1) self.reset()
def __init__(self, canvas): # call the parent constructor QgsMapToolEmitPoint.__init__(self, canvas) # store the passed canvas self.canvas = canvas # flag to know whether the tool is performing a drawing operation self.isDrawing = False # create and setup the rubber band to display the line self.rubberBand = QgsRubberBand( self.canvas, False ) # False = not a polygon = a line self.rubberBand.setColor( Qt.red ) self.rubberBand.setWidth( 1 )
def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface super(EarthMineQGIS, self).__init__() self.movingfeature = None self.iface = iface self.viewer = None self.canvas = self.iface.mapCanvas() self.settings = QSettings() # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] locale_path = os.path.join(self.plugin_dir, "i18n", "EarthMineQGIS_{}.qm".format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > "4.3.3": QCoreApplication.installTranslator(self.translator) self.pointtool = QgsMapToolEmitPoint(self.canvas) self.pointtool.canvasClicked.connect(self.set_viewer_location) self.settingsdialog = SettingsDialog(self.iface.mainWindow()) self.actions = [] self.menu = self.tr(u"&Earthmine") self.toolbar = self.iface.addToolBar(u"EarthMineQGIS") self.toolbar.setObjectName(u"EarthMineQGIS") self.legend = self.iface.legendInterface() emcolor = QColor(1, 150, 51) self.tempband = QgsRubberBand(self.canvas, QGis.Line) self.tempband.setWidth(5) self.tempband.setColor(emcolor) self.tempbandpoints = QgsRubberBand(self.canvas, QGis.Point) self.tempbandpoints.setWidth(7) self.tempbandpoints.setColor(emcolor) self.movingband = QgsRubberBand(self.canvas, QGis.Point) self.movingband.setWidth(5) self.movingband.setColor(emcolor) self.layersignals = [] self.marker = None
def __init__(self, canvas): """Constructor for the map tool. :param canvas: Canvas that tool will interact with. :type canvas: QgsMapCanvas """ self.canvas = canvas self.start_point = None self.end_point = None self.is_emitting_point = False QgsMapToolEmitPoint.__init__(self, self.canvas) self.rubber_band = QgsRubberBand(self.canvas, geometryType=QGis.Line) self.rubber_band.setColor(QColor(0, 0, 240, 100)) # Needs QGIS 2.6 # self.rubber_band.setFillColor(QColor(0, 0, 240, 0)) self.rubber_band.setWidth(1) self.reset()
def __init__(self, canvas): self.canvas = canvas s = QSettings() s.beginGroup('Qgis') color = QColor( int(s.value('default_measure_color_red')), int(s.value('default_measure_color_green')), int(s.value('default_measure_color_blue')) ) s.endGroup() QgsMapToolEmitPoint.__init__(self, self.canvas) self.rubberBand = QgsRubberBand(self.canvas, QGis.Line) self.rubberBandDraw = QgsRubberBand(self.canvas, QGis.Line) self.rubberBandDraw.setColor(color) self.rubberBandDraw.setWidth(1) self.rubberBand.setColor(color) self.rubberBand.setWidth(1) # self.rubberBand.setLineStyle(Qt.DashLine) self.points = [] self.reset()
def __init__(self, iface): self.iface = iface self.canvas = iface.mapCanvas() QgsMapToolEmitPoint.__init__(self, self.canvas) self.rasterShadow = RasterShadowMapCanvasItem(self.canvas) self.rubberBandExtent = QgsRubberBand( self.canvas, QgsWkbTypes.LineGeometry) self.rubberBandExtent.setColor(Qt.red) self.rubberBandExtent.setWidth(1) # In case of rotation around pressed point (ctrl) # Use rubberBand for displaying an horizontal line. self.rubberBandDisplacement = QgsRubberBand( self.canvas, QgsWkbTypes.LineGeometry) self.rubberBandDisplacement.setColor(Qt.red) self.rubberBandDisplacement.setWidth(1) self.reset()
def on_adj_btnStartB_pressed(self): try: self.canvas.scene().removeItem(self.vm_sb) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify start point for Layer B', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.adj_clicked_start_b) self.hide()
def on_opp_btnEndA_pressed(self): try: self.canvas.scene().removeItem(self.vm_ea) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify end point for Layer A', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.clicked_end_a) self.hide()
def __init__(self, iface, parent): """ Class constructor. """ # super(QgsRasterLayer, self).__init__() self.canvas = iface.mapCanvas() super(BandValueTool, self).__init__(self.canvas) self.parent = parent self.iface = iface self.toolAction = None self.QgsMapToolEmitPoint = QgsMapToolEmitPoint(self.canvas) self.DsgGeometryHandler = DsgGeometryHandler(iface) self.timerMapTips = QTimer( self.canvas ) self.timerMapTips.timeout.connect( self.showToolTip ) self.activated = False
def init_toolbar(self): """ Creates and populates the toolbar for plugin """ # MapTool button self.action = QAction(QIcon(':/plugins/tstools/tstools_click.png'), 'Time Series Tools', self.iface.mainWindow()) self.action.triggered.connect(self.set_tool) self.iface.addToolBarIcon(self.action) # Configuration menu button self.action_cfg = QAction(QIcon(':/plugins/tstools/tstools_config.png'), 'Configure', self.iface.mainWindow()) self.action_cfg.triggered.connect(self.handle_config) self.iface.addToolBarIcon(self.action_cfg) # Map tool self.tool_ts = QgsMapToolEmitPoint(self.canvas) self.tool_ts.setAction(self.action) self.tool_ts.canvasClicked.connect(self.plot_request)
def __init__(self, iface): QgsMapToolEmitPoint.__init__(self, iface.mapCanvas()) self.iface = iface self.canvas = iface.mapCanvas() self.canvasClicked.connect(self.clicked)
def getClickedCoor(self, pnt): self.dlg.showMinimized() global pointTool pointTool = QgsMapToolEmitPoint(self.canvas) pointTool.canvasClicked.connect(lambda x: self.display_point(x, pnt)) self.canvas.setMapTool(pointTool)
class EqDistantDialog(QtGui.QDialog, FORM_CLASS): def __init__(self, iface, parent=None): # <---- pass iface """Constructor.""" super(EqDistantDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.hdlg = EqDistantDialogHelp() self.iface = iface # <---- pass iface self.canvas = iface.mapCanvas() self.closeEvnt = QtGui.QCloseEvent def on_btnHelp_pressed(self): self.hdlg.show() def on_btnClose_pressed(self): self.close() def closeEvent(self, QCloseEvent): try: self.canvas.scene().removeItem(self.vm_sa) self.canvas.scene().removeItem(self.vm_sb) self.canvas.scene().removeItem(self.vm_ea) self.canvas.scene().removeItem(self.vm_eb) except AttributeError: pass self.close() reloadPlugin('EqDistant') # --- Daerah berhadapan # fungsi titik awal A def on_opp_btnStartA_pressed(self): try: self.canvas.scene().removeItem(self.vm_sa) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify start point for Layer A', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.clicked_start_a) self.hide() def clicked_start_a(self, point): self.start_a = self.clickTool.toMapCoordinates(self.clickTool.toCanvasCoordinates(point)) self.vm_sa = QgsVertexMarker(self.canvas) self.vm_sa.setCenter(point) self.lineEdit_sa.setText("%s, %s" % (str(round(self.start_a.x(), 3)), str(round(self.start_a.y(), 3)))) self.clickTool.deactivate() self.show() # fungsi titik akhir A def on_opp_btnEndA_pressed(self): try: self.canvas.scene().removeItem(self.vm_ea) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify end point for Layer A', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.clicked_end_a) self.hide() def clicked_end_a(self, point): self.end_a = self.clickTool.toMapCoordinates(self.clickTool.toCanvasCoordinates(point)) self.vm_ea = QgsVertexMarker(self.canvas) self.vm_ea.setCenter(point) self.lineEdit_ea.setText("%s, %s" % (str(round(self.end_a.x(), 3)), str(round(self.end_a.y(), 3)))) self.clickTool.deactivate() self.show() # fungsi titik awal B def on_opp_btnStartB_pressed(self): try: self.canvas.scene().removeItem(self.vm_sb) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify start point for Layer B', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.clicked_start_b) self.hide() def clicked_start_b(self, point): self.start_b = self.clickTool.toMapCoordinates(self.clickTool.toCanvasCoordinates(point)) self.vm_sb = QgsVertexMarker(self.canvas) self.vm_sb.setCenter(point) self.lineEdit_sb.setText("%s, %s" % (str(round(self.start_b.x(), 3)), str(round(self.start_b.y(), 3)))) self.clickTool.deactivate() self.show() # fungsi titik akhir B def on_opp_btnEndB_pressed(self): try: self.canvas.scene().removeItem(self.vm_eb) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify end point for Layer B', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.clicked_end_b) self.hide() def clicked_end_b(self, point): self.end_b = self.clickTool.toMapCoordinates(self.clickTool.toCanvasCoordinates(point)) self.vm_eb = QgsVertexMarker(self.canvas) self.vm_eb.setCenter(point) self.lineEdit_eb.setText("%s, %s" % (str(round(self.end_b.x(), 3)), str(round(self.end_b.y(), 3)))) self.clickTool.deactivate() self.show() # --- Daerah bersebelahan # fungsi titik awal A def on_adj_btnStartA_pressed(self): try: self.canvas.scene().removeItem(self.vm_sa) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify start point for Layer A', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.adj_clicked_start_a) self.hide() def adj_clicked_start_a(self, point): self.adj_start_a = self.clickTool.toMapCoordinates(self.clickTool.toCanvasCoordinates(point)) self.adj_lineEditA.setText("%s, %s" % (str(round(self.adj_start_a.x(), 3)), str(round(self.adj_start_a.y(), 3)))) self.vm_sa = QgsVertexMarker(self.canvas) self.vm_sa.setCenter(point) self.clickTool.deactivate() self.show() # fungsi titik awal B def on_adj_btnStartB_pressed(self): try: self.canvas.scene().removeItem(self.vm_sb) except AttributeError: pass self.clickTool = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.iface.messageBar().pushMessage('Info', 'Specify start point for Layer B', level=QgsMessageBar.INFO, duration=1) self.iface.mapCanvas().setMapTool(self.clickTool) self.clickTool.canvasClicked.connect(self.adj_clicked_start_b) self.hide() def adj_clicked_start_b(self, point): self.adj_start_b = self.clickTool.toMapCoordinates(self.clickTool.toCanvasCoordinates(point)) self.adj_lineEditB.setText("%s, %s" % (str(round(self.adj_start_b.x(), 3)), str(round(self.adj_start_b.y(), 3)))) self.vm_sb = QgsVertexMarker(self.canvas) self.vm_sb.setCenter(point) self.clickTool.deactivate() self.show()
class TSTools(QObject): def __init__(self, iface): super(TSTools, self).__init__() # Save reference to the QGIS interface self.iface = iface self.canvas = self.iface.mapCanvas() # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'tstools_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Location info - define these elsewhere #TODO self.location = os.getcwd() # Toolbar self.init_toolbar() # Map tool on/off self.tool_enabled = True print 'DEBUG {f}: found {i} TS data models'.format( f=__file__, i=len(tsm.ts_drivers)) def init_toolbar(self): """ Creates and populates the toolbar for plugin """ # MapTool button self.action = QAction(QIcon(':/plugins/tstools/tstools_click.png'), 'Time Series Tools', self.iface.mainWindow()) self.action.triggered.connect(self.set_tool) self.iface.addToolBarIcon(self.action) # Configuration menu button self.action_cfg = QAction(QIcon(':/plugins/tstools/tstools_config.png'), 'Configure', self.iface.mainWindow()) self.action_cfg.triggered.connect(self.handle_config) self.iface.addToolBarIcon(self.action_cfg) # Map tool self.tool_ts = QgsMapToolEmitPoint(self.canvas) self.tool_ts.setAction(self.action) self.tool_ts.canvasClicked.connect(self.plot_request) @pyqtSlot() def set_tool(self): """ Sets the time series tool as current map tool """ self.tool_enabled = True self.canvas.setMapTool(self.tool_ts) @pyqtSlot() def unset_tool(self): """ Unsets the time series tool as current map tool """ self.tool_enabled = False self.canvas.setMapTool(None) def handle_config(self): """ Handles configuration menu for initializing the time series """ print 'DEBUG %s : show/hide config' % __file__ # Init the dialog self.config = Config(self, self.location) # Connect signals self.config.accepted.connect(self.config_accepted) self.config.canceled.connect(self.config_closed) # Execute & show dialog self.config.exec_() def config_accepted(self): """ Handles 'OK' button from Config dialog and tries to add time series """ # Try new values location = str(self.config.location) model_index = int(self.config.model_index) custom_options = self.config.custom_options # Set data model for controller from user pick try: self.controller.get_time_series( tsm.ts_drivers[model_index], location, custom_options) # Accept values self.location = location # Close config self.config_closed() # Send message self.iface.messageBar().pushMessage('Info', 'Loaded time series', level=QgsMessageBar.INFO, duration=3) except: # Send error message self.iface.messageBar().pushMessage('Error', 'Failed to find time series.', level=QgsMessageBar.CRITICAL, duration=3) raise def config_closed(self): """ Close and disconnect the configuration dialog """ self.config.accepted.disconnect() self.config.canceled.disconnect() self.config.close() def init_controls(self): """ Initialize and add signals to the left side control widget """ print 'DEBUG %s : init_controls' % __file__ # Create widget self.ctrl = ControlPanel(self.iface) # Create dock & add control widget self.ctrl_dock = QDockWidget('TS Tools Controls', self.iface.mainWindow()) self.ctrl_dock.setObjectName('TS Tools Controls') self.ctrl_dock.setWidget(self.ctrl) # Add to iface self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.ctrl_dock) def init_plots(self): """ Initialize and add signals to plots within bottom dock """ # Create time series plot self.ts_plot = TSPlot(self.iface) # TODO more plots, tabs self.doy_plot = DOYPlot(self.iface) # Create dock and add self.plot_dock = QDockWidget('Plots', self.iface.mainWindow()) self.plot_dock.setObjectName('Plots') # Create tab container self.plot_tabs = QTabWidget(self.plot_dock) self.plot_tabs.addTab(self.ts_plot, self.ts_plot.__str__()) self.plot_tabs.addTab(self.doy_plot, self.doy_plot.__str__()) # Add to dock widget self.plot_dock.setWidget(self.plot_tabs) # Add to iface self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.plot_dock) def initGui(self): """ Required method for Qt to load components. Load controls, plot, and init the signal controller """ self.init_controls() self.init_plots() self.controller = Controller(self.iface, self.ctrl, self.ts_plot, self.doy_plot, parent=self) self.controller.enable_tool.connect(self.set_tool) self.controller.disable_tool.connect(self.unset_tool) self.plot_tabs.currentChanged.connect(self.controller.changed_tab) def plot_request(self, pos, button=None): """ Request handler for QgsMapToolEmitPoint. Gets position and sends signal to controller to grab data & plot """ if self.tool_enabled is False: print 'NO PLOT FOR YOU' return # Check if user has a layer added if self.canvas.layerCount() == 0 or pos is None: self.iface.messageBar().pushMessage('Error', 'Please add a layer before clicking...', level=QgsMessageBar.WARNING, duration=3) # Check currently selected layer #TODO remove? layer = self.canvas.currentLayer() if (layer is None or not layer.isValid() or layer.type() != QgsMapLayer.RasterLayer or layer not in setting.image_layers): self.iface.messageBar().pushMessage('Info', 'Please select a layer from time series before clicking', level=QgsMessageBar.WARNING, duration=2) return # Check if position needs to be reprojected to layer CRS layer_crs = layer.crs() map_crs = self.canvas.mapRenderer().destinationCrs() if not map_crs == layer_crs: if self.canvas.hasCrsTransformEnabled(): crs_transform = QgsCoordinateTransform(map_crs, layer_crs) try: pos = crs_transform.transform(pos) except: self.iface.messageBar().pushMessage('Error', 'Could not convert map CRS to layer CRS', level=QgsMessageBar.WARNING, duration=5) return else: self.iface.messageBar().pushMessage('Error', 'Could not convert map CRS to layer CRS', level=QgsMessageBar.WARNING, duration=5) return # Fetch data if inside raster if layer and layer.extent().contains(pos): # Fetch data self.controller.fetch_data(pos) if setting.canvas['show_click']: self.controller.show_click(pos) else: self.iface.messageBar().pushMessage('Warning', 'Please select a point within the time series image', level=QgsMessageBar.WARNING, duration=5) def unload(self): """ Shutdown and disconnect """ # Remove toolbar icons self.iface.removeToolBarIcon(self.action) self.iface.removeToolBarIcon(self.action_cfg) # Remove panels self.iface.removeDockWidget(self.plot_dock) self.iface.removeDockWidget(self.ctrl_dock) # Disconnect signals self.controller.disconnect()
def __init__(self, canvas): QgsMapToolEmitPoint.__init__(self, canvas)
def __init__(self, canvas): self.canvas = canvas QgsMapToolEmitPoint.__init__(self, self.canvas) self.point = None
def __init__(self, iface): self.iface = iface self.canvas = self.iface.mapCanvas() QgsMapToolEmitPoint.__init__(self, self.canvas) self.timerMapTips = QTimer(self.canvas) self.timerMapTips.timeout.connect(self.showMapTip)
def init_config_form(self): """ Custom form initial configuration """ # Get last point clicked on canvas last_click = self.canvas.mouseLastXY() self.last_point = QgsMapToPixel.toMapCoordinates( self.canvas.getCoordinateTransform(), last_click.x(), last_click.y()) # Define class variables self.filter = self.field_id + " = '" + str(self.id) + "'" emit_point = QgsMapToolEmitPoint(self.canvas) # Get user permisions role_basic = self.controller.check_role_user("role_basic") # Get widget controls self.tab_main = self.dialog.findChild(QTabWidget, "tab_main") self.tbl_element = self.dialog.findChild(QTableView, "tbl_element") self.tbl_document = self.dialog.findChild(QTableView, "tbl_document") self.tbl_event_element = self.dialog.findChild(QTableView, "tbl_event_element") self.tbl_event = self.dialog.findChild(QTableView, "tbl_event_node") self.tbl_scada = self.dialog.findChild(QTableView, "tbl_scada") self.tbl_scada_value = self.dialog.findChild(QTableView, "tbl_scada_value") self.tbl_costs = self.dialog.findChild(QTableView, "tbl_masterplan") self.nodecat_id = self.dialog.findChild(QLineEdit, 'nodecat_id') state_type = self.dialog.findChild(QComboBox, 'state_type') dma_id = self.dialog.findChild(QComboBox, 'dma_id') # Tables self.tbl_upstream = self.dialog.findChild(QTableView, "tbl_upstream") self.tbl_upstream.setSelectionBehavior(QAbstractItemView.SelectRows) self.tbl_downstream = self.dialog.findChild(QTableView, "tbl_downstream") self.tbl_downstream.setSelectionBehavior(QAbstractItemView.SelectRows) self.dialog.findChild(QPushButton, "btn_catalog").clicked.connect( partial(self.catalog, self.dialog, 'ud', 'node')) # New Workcat # self.dialog.findChild(QPushButton, "btn_new_workcat").clicked.connect(partial(self.cf_new_workcat, self.dialog)) self.tbl_upstream.doubleClicked.connect( partial(self.open_up_down_stream, self.tbl_upstream)) self.tbl_downstream.doubleClicked.connect( partial(self.open_up_down_stream, self.tbl_downstream)) feature = self.feature layer = self.iface.activeLayer() action_copypaste = self.dialog.findChild(QAction, "actionCopyPaste") layer.editingStarted.connect( partial(self.enabled_actions, action_copypaste, True)) layer.editingStopped.connect( partial(self.enabled_actions, action_copypaste, False)) action_rotation = self.dialog.findChild(QAction, "actionRotation") layer.editingStarted.connect( partial(self.enabled_actions, action_rotation, True)) layer.editingStopped.connect( partial(self.enabled_actions, action_rotation, False)) action_interpolate = self.dialog.findChild(QAction, "actionInterpolate") layer.editingStarted.connect( partial(self.enabled_actions, action_interpolate, True)) layer.editingStopped.connect( partial(self.enabled_actions, action_interpolate, False)) self.dialog.destroyed.connect(partial(self.dlg_destroyed, layer=layer)) # Toolbar actions action = self.dialog.findChild(QAction, "actionEnabled") self.dialog.findChild(QAction, "actionCopyPaste").setEnabled(layer.isEditable()) self.dialog.findChild(QAction, "actionRotation").setEnabled(layer.isEditable()) self.dialog.findChild(QAction, "actionInterpolate").setEnabled( layer.isEditable()) self.dialog.findChild(QAction, "actionZoom").triggered.connect( partial(self.action_zoom_in, self.feature, self.canvas, self.layer)) self.dialog.findChild(QAction, "actionCentered").triggered.connect( partial(self.action_centered, self.feature, self.canvas, self.layer)) if not role_basic: action.setChecked(layer.isEditable()) layer.editingStarted.connect( partial(self.check_actions, action, True)) layer.editingStopped.connect( partial(self.check_actions, action, False)) self.dialog.findChild(QAction, "actionEnabled").triggered.connect( partial(self.action_enabled, action, self.layer)) else: action.setEnabled(False) self.dialog.findChild(QAction, "actionZoomOut").triggered.connect( partial(self.action_zoom_out, self.feature, self.canvas, self.layer)) self.dialog.findChild(QAction, "actionRotation").triggered.connect( self.action_rotation) self.dialog.findChild(QAction, "actionCopyPaste").triggered.connect( partial(self.action_copy_paste, self.geom_type)) self.dialog.findChild(QAction, "actionLink").triggered.connect( partial(self.check_link, self.dialog, True)) self.dialog.findChild(QAction, "actionHelp").triggered.connect( partial(self.action_help, 'ud', 'node')) self.dialog.findChild(QAction, "actionInterpolate").triggered.connect( partial(self.activate_snapping, emit_point)) widget_ymax = self.dialog.findChild(QLineEdit, 'ymax') if widget_ymax is not None: widget_ymax.textChanged.connect( partial(self.compare_depth, widget_ymax, False)) widget_ymax.lostFocus.connect( partial(self.compare_depth, widget_ymax, True)) # Manage tab 'Scada' self.manage_tab_scada() # Check if exist URL from field 'link' in main tab self.check_link(self.dialog) # Check topology for new features continue_insert = True node_over_node = True check_topology_node = self.controller.plugin_settings_value( "check_topology_node", "0") check_topology_arc = self.controller.plugin_settings_value( "check_topology_arc", "0") # Check if feature has geometry object geometry = self.feature.geometry() if geometry: if self.id.upper() == 'NULL' and check_topology_node == "0": self.get_topology_parameters() (continue_insert, node_over_node) = self.check_topology_node() if continue_insert and not node_over_node: if self.id.upper() == 'NULL' and check_topology_arc == "0": self.check_topology_arc() # Create thread thread1 = Thread(self, self.controller, 3) thread1.start() self.filter = "node_id = '" + str(self.id) + "'" table_name = self.controller.schema_name + ".v_ui_node_x_connection_upstream" self.fill_table(self.tbl_upstream, table_name, self.filter) self.set_configuration(self.tbl_upstream, "v_ui_node_x_connection_upstream") table_name = self.controller.schema_name + ".v_ui_node_x_connection_downstream" self.fill_table(self.tbl_downstream, table_name, self.filter) self.set_configuration(self.tbl_downstream, "v_ui_node_x_connection_downstream") # Manage tab signal self.tab_connections_loaded = False self.tab_element_loaded = False self.tab_document_loaded = False self.tab_om_loaded = False self.tab_scada_loaded = False self.tab_cost_loaded = False self.tab_custom_fields_loaded = False self.tab_main.currentChanged.connect(self.tab_activation) # Load default settings widget_id = self.dialog.findChild(QLineEdit, 'node_id') if utils_giswater.getWidgetText(self.dialog, widget_id).lower() == 'null': self.load_default(self.dialog, "node") self.load_type_default(self.dialog, "nodecat_id", "nodecat_vdefault") self.load_state_type(self.dialog, state_type, self.geom_type) self.load_dma(self.dialog, dma_id, self.geom_type)
def initVariables(self): self.canvas = self.iface.mapCanvas() self.myTool = QgsMapToolEmitPoint(self.canvas) self.currentTool = self.canvas.mapTool() self.filePathGpkg = Auxiliar().pathGpkg()
class BandValueTool(QgsMapTool): """ This class is supposed to help revision operators. It shows, on mouse hovering raster layer's band values. For a MDS product, altimetry is, then, given. Tool Behaviour: 1- On hoverring a pixel: expose band value(s) 2- On mouse click: create a new instance of desired layer (filled on config). * behaviour 2 is an extrapolation of first conception """ def __init__(self, iface, parent): """ Class constructor. """ # super(QgsRasterLayer, self).__init__() self.canvas = iface.mapCanvas() super(BandValueTool, self).__init__(self.canvas) self.parent = parent self.iface = iface self.toolAction = None self.QgsMapToolEmitPoint = QgsMapToolEmitPoint(self.canvas) self.DsgGeometryHandler = DsgGeometryHandler(iface) self.timerMapTips = QTimer( self.canvas ) self.timerMapTips.timeout.connect( self.showToolTip ) self.activated = False def setAction(self, action): """ """ self.toolAction = action def activate(self): """ Activates tool. """ if self.toolAction: self.activated = True QgsMapTool.activate(self) self.canvas.setMapTool(self) def deactivate(self): """ Deactivates tool. """ self.timerMapTips.stop() try: if self.toolAction: self.activated = False self.toolAction.setChecked(False) if self is not None: QgsMapTool.deactivate(self) except: pass def canvasMoveEvent(self, e): QToolTip.hideText() self.timerMapTips.start( 500 ) # time in milliseconds self.showToolTip() def getPixelValue(self, rasterLayer): """ """ rasterCrs = rasterLayer.crs() mousePos = self.QgsMapToolEmitPoint.toMapCoordinates(self.canvas.mouseLastXY()) mousePosGeom = QgsGeometry.fromPoint(mousePos) self.DsgGeometryHandler.reprojectFeature(mousePosGeom, rasterCrs, self.canvas.mapRenderer().destinationCrs()) mousePos = mousePosGeom.asPoint() # identify pixel(s) information i = rasterLayer.dataProvider().identify( mousePos, QgsRaster.IdentifyFormatValue ) if i.isValid(): text = ", ".join(['{0:g}'.format(r) for r in i.results().values() if r is not None] ) else: text = "" return text def showToolTip(self): """ """ self.timerMapTips.stop() if self.canvas.underMouse(): raster = self.parent.rasterComboBox.currentLayer() if raster: text = self.getPixelValue(raster) p = self.canvas.mapToGlobal( self.canvas.mouseLastXY() ) QToolTip.showText( p, text, self.canvas )
def __init__(self, iface): QgsMapToolEmitPoint.__init__(self, iface.mapCanvas()) self.iface = iface self.canvas = iface.mapCanvas() self.canvasClicked.connect(self.clicked) self.marker = None
class AssignBandValueTool(QgsMapTool): def __init__(self, iface, rasterLayer): """ Tool Behaviours: (all behaviours start edition, except for rectangle one) 1- Left Click: Creates a new point feature with the value from raster, according to selected attribute. 5- Shift + drag and drop: draws a rectangle, then features that intersect this rectangle are selected and their value is set according to raster value and selected attribute. """ self.iface = iface self.canvas = self.iface.mapCanvas() QgsMapTool.__init__(self, self.canvas) self.toolAction = None self.qgsMapToolEmitPoint = QgsMapToolEmitPoint(self.canvas) self.dsgGeometryHandler = DsgGeometryHandler(iface) self.rasterLayer = rasterLayer self.setRubberbandParameters() self.reset() self.auxList = [] self.decimals = self.getDecimals() def getDecimals(self): settings = QSettings() settings.beginGroup('PythonPlugins/DsgTools/Options') decimals = settings.value('decimals') if decimals: return int(decimals) else: return 0 def getSuppressOptions(self): qgisSettigns = QSettings() qgisSettigns.beginGroup('Qgis/digitizing') setting = qgisSettigns.value('disable_enter_attribute_values_dialog') qgisSettigns.endGroup() if not setting: return False if setting.lower() == u'false': return False else: return True def setRubberbandParameters(self): self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon) self.hoverRubberBand = QgsRubberBand(self.canvas, QGis.Polygon) mFillColor = QColor(254, 178, 76, 63) self.rubberBand.setColor(mFillColor) self.hoverRubberBand.setColor(QColor(255, 0, 0, 90)) self.rubberBand.setWidth(1) def reset(self): """ Resets rubber band. """ self.startPoint = self.endPoint = None self.isEmittingPoint = False self.rubberBand.reset(QGis.Polygon) def canvasPressEvent(self, e): """ Method used to build rectangle if shift is held, otherwise, feature select/deselect and identify is done. """ if QtGui.QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier: self.isEmittingPoint = True self.startPoint = self.toMapCoordinates(e.pos()) self.endPoint = self.startPoint self.isEmittingPoint = True self.showRect(self.startPoint, self.endPoint) def canvasMoveEvent(self, e): """ Used only on rectangle select. """ if not self.isEmittingPoint: return self.endPoint = self.toMapCoordinates(e.pos()) self.showRect(self.startPoint, self.endPoint) def showRect(self, startPoint, endPoint): """ Builds rubberband rect. """ self.rubberBand.reset(QGis.Polygon) if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y(): return point1 = QgsPoint(startPoint.x(), startPoint.y()) point2 = QgsPoint(startPoint.x(), endPoint.y()) point3 = QgsPoint(endPoint.x(), endPoint.y()) point4 = QgsPoint(endPoint.x(), startPoint.y()) self.rubberBand.addPoint(point1, False) self.rubberBand.addPoint(point2, False) self.rubberBand.addPoint(point3, False) self.rubberBand.addPoint(point4, True) # true to update canvas self.rubberBand.show() def rectangle(self): """ Builds rectangle from self.startPoint and self.endPoint """ if self.startPoint is None or self.endPoint is None: return None elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y( ) == self.endPoint.y(): return None return QgsRectangle(self.startPoint, self.endPoint) def setAction(self, action): self.toolAction = action self.toolAction.setCheckable(True) def canvasReleaseEvent(self, e): """ After the rectangle is built, here features are selected. """ layer = self.iface.mapCanvas().currentLayer() if QtGui.QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier: self.isEmittingPoint = False r = self.rectangle() if r is None: return bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, r) self.rubberBand.hide() #select all stuff layer.setSelectedFeatures([]) #portar para o feature handler layer.select(bbRect, True) #mudar depois para o dsgmothafucka featDict = dict() pointDict = dict() for feat in layer.selectedFeatures(): featDict[feat.id()] = feat pointDict[feat.id()] = feat.geometry() pixelValueDict = self.getPixelValueFromPointDict( pointDict, self.rasterLayer) for idx in pointDict: self.auxList.append({ 'featId': idx, 'feat': featDict[idx], 'value': pixelValueDict[idx] }) else: value, pointGeom = self.getPixelValue(self.rasterLayer) self.auxList.append({'geom': pointGeom, 'value': value}) #create context menu to select attribute self.createContextMenuOnPosition(e, layer) def createContextMenuOnPosition(self, e, layer): menu = QMenu() callbackDict = dict() fieldList = [ field.name() for field in layer.fields() if field.isNumeric() ] for field in fieldList: action = menu.addAction(field) callback = lambda t=[field, layer]: self.handleFeatures(t[0], t[1]) action.triggered[()].connect(callback) menu.exec_(self.canvas.viewport().mapToGlobal(e.pos())) def handleFeatures(self, selectedField, layer): layer.startEditing() for item in self.auxList: if 'featId' in item: feat = item['feat'] idx = feat.fieldNameIndex(selectedField) feat.setAttribute(idx, item['value']) layer.updateFeature(feat) else: feature = QgsFeature(layer.fields()) self.dsgGeometryHandler.reprojectFeature( item['geom'], layer.crs()) feature.setGeometry(item['geom']) self.addFeature(feature, layer, selectedField, item['value']) self.auxList = [] self.canvas.refresh() def addFeature(self, feature, layer, field, pointValue): fields = layer.fields() feature.initAttributes(fields.count()) provider = layer.dataProvider() for i in range(fields.count()): value = provider.defaultValue( i) if fields[i].name() != field else pointValue if value: feature.setAttribute(i, value) form = QgsAttributeDialog(layer, feature, False) form.setMode(QgsAttributeForm.AddFeatureMode) formSuppress = layer.editFormConfig().suppress() if formSuppress == QgsEditFormConfig.SuppressDefault: if self.getSuppressOptions( ): #this is calculated every time because user can switch options while using tool layer.addFeature(feature, True) else: if not form.exec_(): feature.setAttributes(form.feature().attributes()) elif formSuppress == QgsEditFormConfig.SuppressOff: if not form.exec_(): feature.setAttributes(form.feature().attributes()) else: layer.addFeature(feature, True) def getCursorRect(self, e): """ Calculates small cursor rectangle around mouse position. Used to facilitate operations """ p = self.toMapCoordinates(e.pos()) w = self.canvas.mapUnitsPerPixel() * 10 return QgsRectangle(p.x() - w, p.y() - w, p.x() + w, p.y() + w) def deactivate(self): """ Deactivate tool. """ QtGui.QApplication.restoreOverrideCursor() self.hoverRubberBand.reset(QGis.Polygon) try: if self.toolAction: self.toolAction.setChecked(False) if self is not None: QgsMapTool.deactivate(self) self.canvas.unsetMapTool(self) except: pass def activate(self): """ Activate tool. """ if self.toolAction: self.toolAction.setChecked(True) QgsMapTool.activate(self) self.iface.mapCanvas().setMapTool(self) if not isinstance(self.iface.mapCanvas().currentLayer(), QgsVectorLayer): self.iface.messageBar().pushMessage( self.tr("Warning"), self.tr("Select a point vector layer as the active layer"), level=QgsMessageBar.INFO, duration=10) self.deactivate() def reprojectSearchArea(self, layer, geom): """ Reprojects search area if necessary, according to what is being searched. :param layer: (QgsVectorLayer) layer which target rectangle has to have same SRC. :param geom: (QgsRectangle) rectangle representing search area. """ #geom always have canvas coordinates epsg = self.canvas.mapSettings().destinationCrs().authid() #getting srid from something like 'EPSG:31983' srid = layer.crs().authid() if epsg == srid: return geom crsSrc = QgsCoordinateReferenceSystem(epsg) crsDest = QgsCoordinateReferenceSystem(srid) # Creating a transformer coordinateTransformer = QgsCoordinateTransform( crsSrc, crsDest) # here we have to put authid, not srid auxGeom = QgsGeometry.fromRect(geom) auxGeom.transform(coordinateTransformer) return auxGeom.boundingBox() def getPixelValue(self, rasterLayer): mousePos = self.qgsMapToolEmitPoint.toMapCoordinates( self.canvas.mouseLastXY()) mousePosGeom = QgsGeometry.fromPoint(mousePos) return self.getPixelValueFromPoint(mousePosGeom, rasterLayer), mousePosGeom def getPixelValueFromPoint(self, mousePosGeom, rasterLayer, fromCanvas=True): """ """ rasterCrs = rasterLayer.crs() if fromCanvas: self.dsgGeometryHandler.reprojectFeature( mousePosGeom, rasterCrs, self.canvas.mapRenderer().destinationCrs()) else: mousePosGeom = QgsGeometry(mousePosGeom) self.dsgGeometryHandler.reprojectFeature( mousePosGeom, rasterCrs, self.canvas.currentLayer().crs()) # isMulti = QgsWKBTypes.isMultiType(int(layer.wkbType())) # tem que ver se serve pra QgsGeometry mousePos = mousePosGeom.asMultiPoint()[0] if mousePosGeom.isMultipart( ) else mousePosGeom.asPoint() # identify pixel(s) information i = rasterLayer.dataProvider().identify(mousePos, QgsRaster.IdentifyFormatValue) if i.isValid(): value = i.results().values()[0] value = int(value) if self.decimals == 0 else round( value, self.decimals) return value else: return None def getPixelValueFromPointDict(self, pointDict, rasterLayer): """ pointDict = {'pointId':QgsGeometry} returns {'pointId': value} """ return { key: self.getPixelValueFromPoint(value, rasterLayer, fromCanvas=False) for key, value in pointDict.iteritems() } #no python3 eh items()
class EarthMineQGIS(QObject): """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface super(EarthMineQGIS, self).__init__() self.movingfeature = None self.iface = iface self.viewer = None self.canvas = self.iface.mapCanvas() self.settings = QSettings() # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] locale_path = os.path.join(self.plugin_dir, "i18n", "EarthMineQGIS_{}.qm".format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > "4.3.3": QCoreApplication.installTranslator(self.translator) self.pointtool = QgsMapToolEmitPoint(self.canvas) self.pointtool.canvasClicked.connect(self.set_viewer_location) self.settingsdialog = SettingsDialog(self.iface.mainWindow()) self.actions = [] self.menu = self.tr(u"&Earthmine") self.toolbar = self.iface.addToolBar(u"EarthMineQGIS") self.toolbar.setObjectName(u"EarthMineQGIS") self.legend = self.iface.legendInterface() emcolor = QColor(1, 150, 51) self.tempband = QgsRubberBand(self.canvas, QGis.Line) self.tempband.setWidth(5) self.tempband.setColor(emcolor) self.tempbandpoints = QgsRubberBand(self.canvas, QGis.Point) self.tempbandpoints.setWidth(7) self.tempbandpoints.setColor(emcolor) self.movingband = QgsRubberBand(self.canvas, QGis.Point) self.movingband.setWidth(5) self.movingband.setColor(emcolor) self.layersignals = [] self.marker = None def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ":/icons/settings" self.add_action( icon_path, text=self.tr(u"Show Settings"), callback=self.show_settings, parent=self.iface.mainWindow() ) icon_path = ":/icons/viewer" self.add_action( icon_path, text=self.tr(u"Earthmine Viewer"), callback=self.open_viewer, parent=self.iface.mainWindow() ) self.marker = PostionMarker(self.canvas) self.marker.hide() self.viewer = Viewer(callbackobject=self) self.viewer.trackingChanged.connect(self.marker.setTracking) self.viewer.setLocationTriggered.connect(partial(self.canvas.setMapTool, self.pointtool)) self.viewer.updateFeatures.connect(self.update_earthmine_features) self.viewer.layerChanged.connect(self.iface.setActiveLayer) self.viewer.clearLine.connect(self.clear_bands) self.viewer.closed.connect(self.remove_items) self.iface.currentLayerChanged.connect(self.viewer.update_current_layer) cursor = QCursor(QPixmap(":/icons/location")) self.pointtool.setCursor(cursor) self.pointtool.setAction(self.viewer.setlocationaction) def remove_items(self): self.marker.setTracking(False) self.disconnect_projectsignals() self.iface.actionPan().trigger() def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" self.canvas.scene().removeItem(self.marker) del self.marker self.disconnect_projectsignals() for action in self.actions: self.iface.removePluginMenu(self.tr(u"&Earthmine"), action) self.iface.removeToolBarIcon(action) del self.toolbar self.iface.removeDockWidget(self.viewer) self.viewer.deleteLater() def disconnect_projectsignals(self): safe_disconnect(QgsMapLayerRegistry.instance().layerWasAdded, self.connect_layer_signals) safe_disconnect(QgsMapLayerRegistry.instance().layersRemoved, self.layers_removed) safe_disconnect(self.canvas.layersChanged, self.layers_changed) safe_disconnect(self.iface.projectRead, self.connect_signals) safe_disconnect(self.canvas.selectionChanged, self.selection_changed) safe_disconnect(self.canvas.selectionChanged, self.viewer.selection_changed) def clear_bands(self): self.tempband.reset(QGis.Line) self.tempbandpoints.reset(QGis.Point) def visible_layers(self): """ Return the visible layers shown in the map canvas :return: """ return (layer for layer, visible in self.layers_with_states() if visible) def layers_with_states(self): for layer in maplayers(): if not layer.type() == QgsMapLayer.VectorLayer: continue if not layer.geometryType() in [QGis.Point, QGis.Line]: continue yield layer, self.legend.isLayerVisible(layer) def _layer_feature_added(self, featureid): layer = self.sender() if not layer: return self.layer_feature_added(layer, featureid) def layer_feature_added(self, layer, featureid): if not self.viewer: return feature = layer.getFeatures(QgsFeatureRequest(featureid)).next() renderer = layer.rendererV2() transform = self.coordinatetransform(layer) featuredata = to_feature_data(layer.id(), feature, renderer, transform) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, featuredata) def _layer_feature_delete(self, featureid): layer = self.sender() if not layer: return self.layer_feature_delete(layer, featureid) def layer_feature_delete(self, layer, featureid): if not self.viewer: return self.viewer.remove_feature(layer.id(), featureid) def _layer_geometry_changed(self, featureid, geometry): layer = self.sender() if not layer: return self.layer_geometry_changed(layer, featureid, geometry) def layer_geometry_changed(self, layer, featureid, geometry): if not self.viewer: return geomtype = layer.geometryType() if geomtype == QGis.Point: geom = geometry.asPoint() transform = self.coordinatetransform(layer) point = transform.transform(geom, QgsCoordinateTransform.ReverseTransform) location = dict(lat=point.y(), lng=point.x()) self.viewer.edit_feature(layer.id(), featureid, [location]) elif geomtype == QGis.Line: self.layer_feature_delete(layer, featureid) self.layer_feature_added(layer, featureid) def connect_layer_signals(self, layer): if not layer.type() == QgsMapLayer.VectorLayer: return layer.featureAdded.connect(self._layer_feature_added) layer.featureDeleted.connect(self._layer_feature_delete) layer.editingStarted.connect(self.layer_editstate_changed) layer.editingStopped.connect(self.layer_editstate_changed) # HACK The new style doesn't work here # http://hub.qgis.org/issues/6573 signal = SIGNAL("geometryChanged(QgsFeatureId, QgsGeometry&)") self.connect(layer, signal, self._layer_geometry_changed) self.load_layer_features(layers=[layer]) def layer_editstate_changed(self): layer = self.sender() if layer == self.iface.activeLayer(): self.viewer.layer_changed(layer) def disconnect_signals(self): self.disconnect_projectsignals() for layer in maplayers(): if not layer.type() == QgsMapLayer.VectorLayer: return safe_disconnect(layer.featureAdded, self._layer_feature_added) safe_disconnect(layer.featureDeleted, self._layer_feature_delete) safe_disconnect(layer.editingStarted, self.layer_editstate_changed) safe_disconnect(layer.editingStopped, self.layer_editstate_changed) # HACK The new style doesn't work here # http://hub.qgis.org/issues/6573 signal = SIGNAL("geometryChanged(QgsFeatureId, QgsGeometry&)") self.disconnect(layer, signal, self._layer_geometry_changed) def connect_signals(self): for layer in maplayers(): self.connect_layer_signals(layer) self.center_on_canvas() def set_viewer_location(self, point, mousebutton): transform = self.coordinatetransform() point = transform.transform(point, QgsCoordinateTransform.ReverseTransform) self.viewer.set_location(point) def distancearea(self): area = QgsDistanceArea() dest = self.canvas.mapRenderer().destinationCrs() area.setSourceCrs(dest) return area, dest.mapUnits() def coordinatetransform(self, layer=None): """ Return the transform for WGS84 -> QGIS projection. """ source = QgsCoordinateReferenceSystem() source.createFromWkt( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]' ) if not layer: dest = self.canvas.mapRenderer().destinationCrs() else: dest = layer.crs() transform = QgsCoordinateTransform(source, dest) return transform def earthmine_settings(self): settings = {} with settinggroup(self.settings, "plugins/Earthmine"): for key in ["serviceUrl", "baseDataUrl", "apiKey", "secretKey", "viewerUrl"]: if not self.settings.contains(key): raise EarthmineSettingsError("{} not set".format(key)) value = self.settings.value(key, type=str) if value is None: raise EarthmineSettingsError("{} not set".format(key)) settings[key] = value return settings @pyqtSlot() def ready(self): """ Called when the viewer is ready to be started. At this point the viewer hasn't been loaded so no other methods apart from startViewer will be handled. """ settings = self.earthmine_settings() self.viewer.startViewer(settings) @pyqtSlot() def viewerReady(self): """ Called once the viewer is loaded and ready to get location events. """ self.disconnect_signals() self.connect_signals() self.iface.projectRead.connect(self.connect_signals) self.canvas.layersChanged.connect(self.layers_changed) self.canvas.selectionChanged.connect(self.selection_changed) self.canvas.selectionChanged.connect(self.viewer.selection_changed) QgsMapLayerRegistry.instance().layersRemoved.connect(self.layers_removed) QgsMapLayerRegistry.instance().layerWasAdded.connect(self.connect_layer_signals) self.center_on_canvas() self.viewer.activelayercombo.setLayer(self.iface.activeLayer()) def center_on_canvas(self): point = self.canvas.extent().center() transform = self.coordinatetransform() point = transform.transform(point, QgsCoordinateTransform.ReverseTransform) self.viewer.set_location(point) self.viewer.infoaction.toggle() def selection_changed(self, layer): ids = [feature.id() for feature in layer.selectedFeatures()] if not ids: self.viewer.clear_selection(layer.id()) else: self.viewer.set_selection(layer.id(), ids) def layers_changed(self): layerstates = self.layers_with_states() for layer, visible in layerstates: layerid = layer.id() viewerloaded = self.viewer.layer_loaded(layerid) QgsMessageLog.instance().logMessage(layerid, "Earthmine") QgsMessageLog.instance().logMessage("Viewer State:" + str(viewerloaded), "Earthmine") QgsMessageLog.instance().logMessage("QGIS State:" + str(visible), "Earthmine") if (viewerloaded and visible) or (not viewerloaded and not visible): QgsMessageLog.instance().logMessage("Ignoring as states match", "Earthmine") continue if viewerloaded and not visible: QgsMessageLog.instance().logMessage( "Clearing layer because viewer loaded and disabled in QGIS", "Earthmine" ) self.viewer.clear_layer_features(layerid) continue if not viewerloaded and visible: QgsMessageLog.instance().logMessage("Loading layer", "Earthmine") self.load_layer_features(layers=[layer]) continue def layers_removed(self, layers): for layerid in layers: self.viewer.clear_layer_features(layerid) @pyqtSlot(str, float, float) def viewChanged(self, event, yaw, angle): self.marker.setAngle(angle) self.marker.setYaw(yaw) @pyqtSlot(str, str) def getInfo(self, layerid, featureid): featureid = int(featureid) activelayer = self.iface.activeLayer() if not activelayer: return activetool = self.viewer.active_tool() if not activetool in ["Info", "Select"]: return # Only show information for the active layer if not layerid == activelayer.id(): return layer = layer_by_id(layerid) if activetool == "Select": layer.setSelectedFeatures([featureid]) elif activetool == "Info": rq = QgsFeatureRequest(featureid) feature = layer.getFeatures(rq).next() dlg = get_feature_form(layer, feature) if dlg.dialog().exec_(): self.canvas.refresh() @pyqtSlot(str, str, float, float, bool) def featureMoved(self, layerid, featureid, lat, lng, end): layer = layer_by_id(layerid) transform = self.coordinatetransform(layer) point = transform.transform(lng, lat) if not end: self.movingband.show() self.movingband.setToGeometry(QgsGeometry.fromPoint(point), layer) self.movingband.updatePosition() self.movingband.update() else: self.movingband.hide() feature = feature_by_id(layer, featureid) startpoint = feature.geometry().asPoint() dx = point.x() - startpoint.x() dy = point.y() - startpoint.y() layer.beginEditCommand("Feature Moved") # Block signals for this move as the geometry changed signal will re add the geometry on use. layer.blockSignals(True) layer.translateFeature(feature.id(), dx, dy) layer.blockSignals(False) self.canvas.refresh() layer.endEditCommand() @pyqtSlot(str, str) def onError(self, message, stacktrace=None): self.iface.messageBar().pushMessage("Earthmine", message, QgsMessageBar.WARNING) QgsMessageLog.logMessage(stacktrace, "Earthmine") @pyqtSlot(float, float, float) def addPoint(self, lat, lng, z): layer = self.viewer.active_layer if not layer.isEditable(): self.iface.messageBar().pushMessage( "Earthmine", "Selected layer isn't editable. Please enable edit mode to add features", duration=3, level=QgsMessageBar.WARNING, ) return transform = self.coordinatetransform(layer) point = transform.transform(lng, lat) geom = QgsGeometry.fromPoint(point) self.add_feature(layer, geom, z) def add_feature(self, layer, geom, z=None): feature = QgsFeature(layer.pendingFields()) if z and self.viewer.copyZvalue: try: feature["Z"] = z except KeyError: QgsMessageLog.log("No Z found on layer {}".format(layer.name())) pass feature.setGeometry(geom) dlg = get_feature_form(layer, feature, isadd=True) if dlg.dialog().exec_(): self.canvas.refresh() @pyqtSlot(str, bool, str) def drawLine(self, points, end, stats): points = json.loads(points) stats = json.loads(stats) QgsMessageLog.logMessage(str(stats), "Earthmine") self.tempband.reset(QGis.Line) self.tempbandpoints.reset(QGis.Point) color = QColor(self.viewer.current_action_color) self.tempband.setColor(color) self.tempbandpoints.setColor(color) layer = self.viewer.active_layer transform = self.coordinatetransform(layer) earthminepoints = [] for point in points: newpoint = transform.transform(point["lng"], point["lat"]) self.tempband.addPoint(newpoint) self.tempbandpoints.addPoint(newpoint) empoint = EarthminePoint(newpoint, point) earthminepoints.append(empoint) if end and not self.viewer.mode == "Vertical": geom = self.tempband.asGeometry() self.add_feature(layer, geom) self.clear_bands() self.viewer.geom = EarthmineLine(earthminepoints, stats) self.tempband.show() self.tempbandpoints.show() @pyqtSlot(str, str, str, float) def locationChanged(self, lat, lng, yaw, angle): transform = self.coordinatetransform() point = transform.transform(float(lng), float(lat)) self.marker.setCenter(point) yaw = float(yaw) self.marker.setAngle(angle) self.marker.setYaw(yaw) self.marker.setTracking(self.viewer.tracking) if self.marker.tracking: rect = QgsRectangle(point, point) extentlimt = QgsRectangle(self.canvas.extent()) extentlimt.scale(0.95) if not extentlimt.contains(point): self.canvas.setExtent(rect) self.canvas.refresh() # Clear old features self.viewer.clear_features() self.load_layer_features(point) def update_earthmine_features(self, viewfeatures): self.viewer.clear_features() if viewfeatures: self.load_layer_features() def load_layer_features(self, point=None, layers=None): # TODO Move this logic into the viewer and let it track it's position if point is None and self.marker.map_pos is None: return if point is None: point = self.marker.map_pos area, units = self.distancearea() rect = search_area(units, area, point) if layers is None: layers = self.visible_layers() for layer in layers: transform = self.coordinatetransform(layer) # Transform the rect source = self.canvas.mapRenderer().destinationCrs() dest = layer.crs() recttransform = QgsCoordinateTransform(source, dest) rect = recttransform.transformBoundingBox(rect) features = list(get_features_in_area(layer, rect, transform, self.canvas.mapSettings())) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, features) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate("EarthMineQGIS", message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None, ): """Add a toolbar icon to the InaSAFE toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to s, "Earhtmine"how in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def open_viewer(self): """Run method that performs all the real work""" try: settings = self.earthmine_settings() except EarthmineSettingsError as ex: self.onError(ex.message) self.show_settings() return url = settings["viewerUrl"] if not url.startswith("http"): url = url.replace("\\\\", "\\") url = QUrl.fromLocalFile(url) else: url = QUrl(url) if not self.viewer.isVisible(): self.iface.addDockWidget(Qt.RightDockWidgetArea, self.viewer) self.viewer.loadviewer(url) def show_settings(self): self.settingsdialog.show()
def deleteLater(self, *args): self.canvas.mapToolSet.disconnect(self._toolChanged) return QgsMapToolEmitPoint.deleteLater(self, *args)
class WaysCalc: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'WaysCalc_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&WaysCalc') # TODO: We are going to let the user set this up in a future iteration # self.toolbar = self.iface.addToolBar(u'WaysCalc') # self.toolbar.setObjectName(u'WaysCalc') #print "** INITIALIZING WaysCalc" self.pluginIsActive = False self.dockwidget_inters_ways = None self.dockwidget_inters_allways = None # self.settings = None self.IW = None #IntersectionWays self.IAW = None #IntersectionAllWays # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('WaysCalc', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" # выпадающая кнопка для пересекающихся маршрутов self.toolButton = QToolButton() self.toolButton.setMenu(QMenu()) # setPopupMode: DelayedPopup, MenuButtonPopup, InstantPopup self.toolButton.setPopupMode(QToolButton.InstantPopup) self.toolButton.setAutoRaise(True) self.toolButton_action = self.iface.addToolBarWidget(self.toolButton) self.action_intersection = QAction( QIcon(":/plugins/_Ways_calc/icon.png"), u'Поиск пересечений для линейного объекта', self.iface.mainWindow()) self.action_initLayerWays = QAction( u"Выбор слоя для поиска пересечений", self.iface.mainWindow()) self.action_allintersection = QAction( QIcon(":/plugins/_Ways_calc/icon.png"), u'Поиск пересечений всех линейных объектов', self.iface.mainWindow()) self.iface.addPluginToMenu(u"WaysCalc", self.action_intersection) self.iface.addPluginToMenu(u"WaysCalc", self.action_initLayerWays) self.iface.addPluginToMenu(u"WaysCalc", self.action_allintersection) # self.iface.addToolBarIcon(self.action_intersection) m = self.toolButton.menu() m.addAction(self.action_intersection) m.addAction(self.action_initLayerWays) m.addSeparator() m.addAction(self.action_allintersection) self.toolButton.setDefaultAction(self.action_intersection) self.action_intersection.triggered.connect(self.run_intersection) # пересекающиеся маршруты self.action_allintersection.triggered.connect(self.run_allintersection) # пересекающиеся все маршруты self.action_initLayerWays.triggered.connect(self.run_initLayerWays) # выбор слоя сравнения self.pointEmitterIntersection = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.pointEmitterIntersection.setAction(self.action_intersection) self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked) self.iface.mapCanvas().currentLayerChanged.connect(self.onCurrentLayerChanged) #-------------------------------------------------------------------------- def onClosePlugin(self): """Cleanup necessary items here when plugin dockwidget is closed""" # disconnects try: self.dockwidget_inters_ways.closingPlugin.disconnect(self.onClosePlugin) except: pass try: self.dockwidget_inters_allways.closingPlugin.disconnect(self.onClosePlugin) except: pass self.pluginIsActive = False def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" self.iface.removePluginMenu(u"WaysCalc", self.action_intersection) self.iface.removePluginMenu(u"WaysCalc", self.action_allintersection) self.iface.removePluginMenu(u"WaysCalc", self.action_initLayerWays) self.iface.removeToolBarIcon(self.action_intersection) self.iface.removeToolBarIcon(self.action_intersection) self.iface.removeToolBarIcon(self.toolButton_action) self.action_intersection.triggered.disconnect(self.run_intersection) # пересекающиеся маршруты self.action_allintersection.triggered.disconnect(self.run_allintersection) # пересекающиеся все маршруты self.action_initLayerWays.triggered.disconnect(self.run_initLayerWays) # выбор слоя сравнения self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked) self.iface.mapCanvas().currentLayerChanged.disconnect(self.onCurrentLayerChanged) if self.IW is not None: self.IW.onUnLoadModule() def init_dock_inters_ways(self, dock): """Run method that loads and starts the plugin""" # if not self.pluginIsActive: self.pluginIsActive = True if self.dockwidget_inters_ways == None: self.dockwidget_inters_ways = WaysCalcDockWidget() self.dockwidget_inters_ways.closingPlugin.connect(self.onClosePlugin) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_ways) self.dockwidget_inters_ways.hide() self.dockwidget_inters_ways.setWindowTitle(u'WaysCalc: Поиск пересечений для линейного объекта') def init_dock_inters_allways(self, dock): """Run method that loads and starts the plugin""" # if not self.pluginIsActive: self.pluginIsActive = True if self.dockwidget_inters_allways == None: self.dockwidget_inters_allways = WaysCalcDockWidget() self.dockwidget_inters_allways.closingPlugin.connect(self.onClosePlugin) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_allways) self.dockwidget_inters_allways.hide() self.dockwidget_inters_allways.setWindowTitle(u'WaysCalc: Поиск пересечений всех линейных объектов') def onCurrentLayerChanged(self): self.iface.mapCanvas().unsetMapTool(self.pointEmitterIntersection) #-------------------------------------------------------------------------- # def loadSettings(self): # with open(os.path.join(self.plugin_dir, "settings.json"), "r") as read_file: # self.settings = json.load(read_file) #--------INTERSECTION WAYS------------------------------------------------- def run_initLayerWays(self): if self.IW is None: self.init_IW() self.IW.initLayerWays() def run_intersection(self): self.toolButton.setDefaultAction(self.action_intersection) self.init_dock_inters_ways(self.dockwidget_inters_ways) if self.IW is None: self.init_IW() if self.IW.checkLayers(): self.iface.mapCanvas().setMapTool(self.pointEmitterIntersection) def pointEmitterIntersectioncanvasClicked(self, point, button): self.IW.insersection_take_way(point) def init_IW(self): self.IW = IntersectionWays(self.iface, self.dockwidget_inters_ways) #-------- END INTERSECTION WAYS--------------------------------------------- def init_IAW(self): self.IAW = IntersectionAllWays(self.iface, self.dockwidget_inters_allways) def run_allintersection(self): self.init_dock_inters_allways(self.dockwidget_inters_allways) if self.IAW is None: self.init_IAW() self.IAW.showClickedFeaturesList()
def __init__(self, canvas): self.canvas = canvas QgsMapToolEmitPoint.__init__(self, self.canvas) self.point = None
def setupUi(self, _): """ Add to the UI the following elements: 1) the selection editor 2) the tabs with the dynamic forms 3) the map 4) the toolbar with the map tools """ super(MainWindow, self).setupUi(self) self.selection_editor = SelectionDialog(self) self.actionUndo.setDisabled(True) # setup dynamic forms self.tabs = ( Tab("declustering", self.declusteringFormLayout, DECLUSTERER_METHODS, [self.declusterButton, self.declusteringPurgeButton]), Tab("completeness", self.completenessFormLayout, COMPLETENESS_METHODS, [self.completenessButton, self.completenessPurgeButton]), Tab("recurrence_model", self.recurrenceModelFormLayout, OCCURRENCE_METHODS, [self.recurrenceModelButton]), Tab("max_magnitude", self.maxMagnitudeFormLayout, MAX_MAGNITUDE_METHODS, [self.maxMagnitudeButton]), Tab("smoothed_seismicity", self.smoothedSeismicityFormLayout, SMOOTHED_SEISMICITY_METHODS, [self.smoothedSeismicityButton]), Tab("histogram", self.catalogueAnalysisFormLayout, CATALOGUE_ANALYSIS_METHODS, [self.catalogueAnalysisButton])) for tab in self.tabs: tab.setup_form(self.on_algorithm_select) self.stackedFormWidget.currentChanged.connect(self.change_tab) # setup Map self.mapWidget.setCanvasColor(Qt.white) self.mapWidget.enableAntiAliasing(True) self.mapWidget.show() #self.message_bar = QgsMessageBar(self.centralWidget) #self.outputVerticalLayout.insertWidget(0, self.message_bar) # setup toolbar group = QtGui.QActionGroup(self) group.addAction(self.actionZoomIn) group.addAction(self.actionZoomOut) group.addAction(self.actionPan) group.addAction(self.actionIdentify) # create the map tools toolPan = QgsMapToolPan(self.mapWidget) toolPan.setAction(self.actionPan) # false = in toolZoomIn = QgsMapToolZoom(self.mapWidget, False) toolZoomIn.setAction(self.actionZoomIn) # true = out toolZoomOut = QgsMapToolZoom(self.mapWidget, True) toolZoomOut.setAction(self.actionZoomOut) toolIdentify = QgsMapToolEmitPoint(self.mapWidget) toolIdentify.setAction(self.actionIdentify) toolIdentify.canvasClicked.connect( lambda point, button: self.catalogue_map.show_tip(point)) self.actionZoomIn.triggered.connect( lambda: self.mapWidget.setMapTool(toolZoomIn)) self.actionZoomOut.triggered.connect( lambda: self.mapWidget.setMapTool(toolZoomOut)) self.actionPan.triggered.connect( lambda: self.mapWidget.setMapTool(toolPan)) self.actionIdentify.triggered.connect( lambda: self.mapWidget.setMapTool(toolIdentify)) self.mapWidget.setMapTool(toolPan) self.stackedFormWidget.setCurrentIndex(0)
def deactivate(self): QgsMapToolEmitPoint.deactivate(self) self.reset()
def __init__(self, iface): QgsMapToolEmitPoint.__init__(self, iface.mapCanvas()) self.iface = iface self.canvas = iface.mapCanvas() self.canvasClicked.connect(self.clicked) self.lineDigitizerDialog = None
class Serval(object): LINE_SELECTION = "line" POLYGON_SELECTION = "polygon" RGB = "RGB" SINGLE_BAND = "Single band" def __init__(self, iface): self.iface = iface self.canvas = self.iface.mapCanvas() self.plugin_dir = os.path.dirname(__file__) self.uc = UserCommunication(iface, 'Serval') self.load_settings() self.raster = None self.handler = None self.spin_boxes = None self.exp_dlg = None self.exp_builder = None self.block_pts_layer = None self.px, self.py = [0, 0] self.last_point = QgsPointXY(0, 0) self.rbounds = None self.changes = dict() # dict with rasters changes {raster_id: RasterChanges instance} self.project = QgsProject.instance() self.crs_transform = None self.all_touched = None self.selection_mode = None self.spatial_index_time = dict() # {layer_id: creation time} self.spatial_index = dict() # {layer_id: spatial index} self.selection_layers_count = 1 self.debug = DEBUG self.logger = get_logger() if self.debug else None self.menu = u'Serval' self.actions = [] self.actions_always_on = [] self.toolbar = self.iface.addToolBar(u'Serval Main Toolbar') self.toolbar.setObjectName(u'Serval Main Toolbar') self.toolbar.setToolTip(u'Serval Main Toolbar') self.sel_toolbar = self.iface.addToolBar(u'Serval Selection Toolbar') self.sel_toolbar.setObjectName(u'Serval Selection Toolbar') self.sel_toolbar.setToolTip(u'Serval Selection Toolbar') # Map tools self.probe_tool = QgsMapToolEmitPoint(self.canvas) self.probe_tool.setObjectName('ServalProbeTool') self.probe_tool.setCursor(QCursor(QPixmap(icon_path('probe_tool.svg')), hotX=2, hotY=22)) self.probe_tool.canvasClicked.connect(self.point_clicked) self.draw_tool = QgsMapToolEmitPoint(self.canvas) self.draw_tool.setObjectName('ServalDrawTool') self.draw_tool.setCursor(QCursor(QPixmap(icon_path('draw_tool.svg')), hotX=2, hotY=22)) self.draw_tool.canvasClicked.connect(self.point_clicked) self.selection_tool = RasterCellSelectionMapTool(self.iface, self.uc, self.raster, debug=self.debug) self.selection_tool.setObjectName('RasterSelectionTool') self.map_tool_btn = dict() # {map tool: button activating the tool} self.iface.currentLayerChanged.connect(self.set_active_raster) self.project.layersAdded.connect(self.set_active_raster) self.canvas.mapToolSet.connect(self.check_active_tool) self.register_exp_functions() def load_settings(self): """Return plugin settings dict - default values are overriden by user prefered values from QSettings.""" self.default_settings = { "undo_steps": {"value": 3, "vtype": int}, } self.settings = dict() s = QSettings() s.beginGroup("serval") for k, v in self.default_settings.items(): user_val = s.value(k, v["value"], v["vtype"]) self.settings[k] = user_val def edit_settings(self): """Open dialog with plugin settings.""" s = QSettings() s.beginGroup("serval") k = "undo_steps" cur_val = self.settings[k] val_type = self.default_settings[k]["vtype"] cur_steps = s.value(k, cur_val, val_type) label = 'Nr of Undo/Redo steps:' steps, ok = QInputDialog.getInt(None, "Serval Settings", label, cur_steps) if not ok: return if steps >= 0: s.setValue("undo_steps", steps) self.load_settings() self.uc.show_info("Some new settings may require QGIS restart.") def initGui(self): _ = self.add_action( 'serval_icon.svg', text=u'Show Serval Toolbars', add_to_menu=True, callback=self.show_toolbar, always_on=True, ) _ = self.add_action( 'serval_icon.svg', text=u'Hide Serval Toolbars', add_to_menu=True, callback=self.hide_toolbar, always_on=True, ) self.probe_btn = self.add_action( 'probe.svg', text="Probe raster", callback=self.activate_probing, add_to_toolbar=self.toolbar, checkable=True, ) self.map_tool_btn[self.probe_tool] = self.probe_btn self.color_btn = QgsColorButton() self.color_btn.setColor(Qt.gray) self.color_btn.setMinimumSize(QSize(40, 24)) self.color_btn.setMaximumSize(QSize(40, 24)) self.toolbar.addWidget(self.color_btn) self.color_picker_connection(connect=True) self.color_btn.setDisabled(True) self.toolbar.addWidget(QLabel("Band:")) self.bands_cbo = QComboBox() self.bands_cbo.addItem("1", 1) self.toolbar.addWidget(self.bands_cbo) self.bands_cbo.currentIndexChanged.connect(self.update_active_bands) self.bands_cbo.setDisabled(True) self.spin_boxes = BandBoxes() self.toolbar.addWidget(self.spin_boxes) self.spin_boxes.enter_hit.connect(self.apply_spin_box_values) self.draw_btn = self.add_action( 'draw.svg', text="Apply Value(s) To Single Cell", callback=self.activate_drawing, add_to_toolbar=self.toolbar, checkable=True, ) self.map_tool_btn[self.draw_tool] = self.draw_btn self.apply_spin_box_values_btn = self.add_action( 'apply_const_value.svg', text="Apply Value(s) to Selection", callback=self.apply_spin_box_values, add_to_toolbar=self.toolbar, ) self.gom_btn = self.add_action( 'apply_nodata_value.svg', text="Apply NoData to Selection", callback=self.apply_nodata_value, add_to_toolbar=self.toolbar, ) self.exp_dlg_btn = self.add_action( 'apply_expression_value.svg', text="Apply Expression Value To Selection", callback=self.define_expression, add_to_toolbar=self.toolbar, checkable=False, ) self.low_pass_filter_btn = self.add_action( 'apply_low_pass_filter.svg', text="Apply Low-Pass 3x3 Filter To Selection", callback=self.apply_low_pass_filter, add_to_toolbar=self.toolbar, checkable=False, ) self.undo_btn = self.add_action( 'undo.svg', text="Undo", callback=self.undo, add_to_toolbar=self.toolbar, ) self.redo_btn = self.add_action( 'redo.svg', text="Redo", callback=self.redo, add_to_toolbar=self.toolbar, ) self.set_nodata_btn = self.add_action( 'set_nodata.svg', text="Edit Raster NoData Values", callback=self.set_nodata, add_to_toolbar=self.toolbar, ) self.settings_btn = self.add_action( 'edit_settings.svg', text="Serval Settings", callback=self.edit_settings, add_to_toolbar=self.toolbar, always_on=True, ) self.show_help = self.add_action( 'help.svg', text="Help", add_to_menu=True, callback=self.show_website, add_to_toolbar=self.toolbar, always_on=True, ) # Selection Toolbar line_width_icon = QIcon(icon_path("line_width.svg")) line_width_lab = QLabel() line_width_lab.setPixmap(line_width_icon.pixmap(22, 12)) self.sel_toolbar.addWidget(line_width_lab) self.line_width_sbox = QgsDoubleSpinBox() self.line_width_sbox.setMinimumSize(QSize(50, 24)) self.line_width_sbox.setMaximumSize(QSize(50, 24)) # self.line_width_sbox.setButtonSymbols(QAbstractSpinBox.NoButtons) self.line_width_sbox.setValue(1) self.line_width_sbox.setMinimum(0.01) self.line_width_sbox.setShowClearButton(False) self.line_width_sbox.setToolTip("Selection Line Width") self.line_width_sbox.valueChanged.connect(self.update_selection_tool) self.width_unit_cbo = QComboBox() self.width_units = ("map units", "pixel width", "pixel height", "hairline",) for u in self.width_units: self.width_unit_cbo.addItem(u) self.width_unit_cbo.setToolTip("Selection Line Width Unit") self.sel_toolbar.addWidget(self.line_width_sbox) self.sel_toolbar.addWidget(self.width_unit_cbo) self.width_unit_cbo.currentIndexChanged.connect(self.update_selection_tool) self.line_select_btn = self.add_action( 'select_line.svg', text="Select Raster Cells by Line", callback=self.activate_line_selection, add_to_toolbar=self.sel_toolbar, checkable=True, ) self.polygon_select_btn = self.add_action( 'select_polygon.svg', text="Select Raster Cells by Polygon", callback=self.activate_polygon_selection, add_to_toolbar=self.sel_toolbar, checkable=True, ) self.selection_from_layer_btn = self.add_action( 'select_from_layer.svg', text="Create Selection From Layer", callback=self.selection_from_layer, add_to_toolbar=self.sel_toolbar, ) self.selection_to_layer_btn = self.add_action( 'selection_to_layer.svg', text="Create Memory Layer From Selection", callback=self.selection_to_layer, add_to_toolbar=self.sel_toolbar, ) self.clear_selection_btn = self.add_action( 'clear_selection.svg', text="Clear selection", callback=self.clear_selection, add_to_toolbar=self.sel_toolbar, ) self.toggle_all_touched_btn = self.add_action( 'all_touched.svg', text="Toggle All Touched Get Selected", callback=self.toggle_all_touched, checkable=True, checked=True, add_to_toolbar=self.sel_toolbar, ) self.all_touched = True self.enable_toolbar_actions(enable=False) self.check_undo_redo_btns() def add_action(self, icon_name, callback=None, text="", enabled_flag=True, add_to_menu=False, add_to_toolbar=None, status_tip=None, whats_this=None, checkable=False, checked=False, always_on=False): icon = QIcon(icon_path(icon_name)) action = QAction(icon, text, self.iface.mainWindow()) action.triggered.connect(callback) action.setEnabled(enabled_flag) action.setCheckable(checkable) action.setChecked(checked) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar is not None: add_to_toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) if always_on: self.actions_always_on.append(action) return action def unload(self): self.changes = None if self.selection_tool: self.selection_tool.reset() if self.spin_boxes is not None: self.spin_boxes.remove_spinboxes() for action in self.actions: self.iface.removePluginMenu('Serval', action) self.iface.removeToolBarIcon(action) del self.toolbar del self.sel_toolbar self.iface.actionPan().trigger() self.unregister_exp_functions() def show_toolbar(self): if self.toolbar: self.toolbar.show() self.sel_toolbar.show() def hide_toolbar(self): if self.toolbar: self.toolbar.hide() self.sel_toolbar.hide() @staticmethod def register_exp_functions(): QgsExpression.registerFunction(nearest_feature_attr_value) QgsExpression.registerFunction(nearest_pt_on_line_interpolate_z) QgsExpression.registerFunction(intersecting_features_attr_average) QgsExpression.registerFunction(interpolate_from_mesh) @staticmethod def unregister_exp_functions(): QgsExpression.unregisterFunction('nearest_feature_attr_value') QgsExpression.unregisterFunction('nearest_pt_on_line_interpolate_z') QgsExpression.unregisterFunction('intersecting_features_attr_average') QgsExpression.unregisterFunction('interpolate_from_mesh') def uncheck_all_btns(self): self.probe_btn.setChecked(False) self.draw_btn.setChecked(False) self.gom_btn.setChecked(False) self.line_select_btn.setChecked(False) self.polygon_select_btn.setChecked(False) def check_active_tool(self, cur_tool): self.uncheck_all_btns() if cur_tool in self.map_tool_btn: self.map_tool_btn[cur_tool].setChecked(True) if cur_tool == self.selection_tool: if self.selection_mode == self.LINE_SELECTION: self.line_select_btn.setChecked(True) else: self.polygon_select_btn.setChecked(True) def activate_probing(self): self.mode = 'probe' self.canvas.setMapTool(self.probe_tool) def define_expression(self): if not self.selection_tool.selected_geometries: self.uc.bar_warn("No selection for raster layer. Select some cells and retry...") return self.handler.select(self.selection_tool.selected_geometries, all_touched_cells=self.all_touched) self.handler.create_cell_pts_layer() if self.handler.cell_pts_layer.featureCount() == 0: self.uc.bar_warn("No selection for raster layer. Select some cells and retry...") return self.exp_dlg = QgsExpressionBuilderDialog(self.handler.cell_pts_layer) self.exp_builder = self.exp_dlg.expressionBuilder() self.exp_dlg.accepted.connect(self.apply_exp_value) self.exp_dlg.show() def apply_exp_value(self): if not self.exp_dlg.expressionText() or not self.exp_builder.isExpressionValid(): return QApplication.setOverrideCursor(Qt.WaitCursor) exp = self.exp_dlg.expressionText() idx = self.handler.cell_pts_layer.addExpressionField(exp, QgsField('exp_val', QVariant.Double)) self.handler.exp_field_idx = idx self.handler.write_block() QApplication.restoreOverrideCursor() self.raster.triggerRepaint() def activate_drawing(self): self.mode = 'draw' self.canvas.setMapTool(self.draw_tool) def get_cur_line_width(self): width_coef = { "map units": 1., "pixel width": self.raster.rasterUnitsPerPixelX(), "pixel height": self.raster.rasterUnitsPerPixelY(), "hairline": 0.000001, } return self.line_width_sbox.value() * width_coef[self.width_unit_cbo.currentText()] def set_selection_tool(self, mode): if self.raster is None: self.uc.bar_warn("Select a raster layer") return self.selection_mode = mode self.selection_tool.init_tool(self.raster, mode=self.selection_mode, line_width=self.get_cur_line_width()) self.selection_tool.set_prev_tool(self.canvas.mapTool()) self.canvas.setMapTool(self.selection_tool) def activate_line_selection(self): self.set_selection_tool(self.LINE_SELECTION) def activate_polygon_selection(self): self.set_selection_tool(self.POLYGON_SELECTION) def update_selection_tool(self): """Reactivate the selection tool with updated line width and units.""" if self.selection_mode == self.LINE_SELECTION: self.activate_line_selection() elif self.selection_mode == self.POLYGON_SELECTION: self.activate_polygon_selection() else: pass def apply_values(self, new_values): QApplication.setOverrideCursor(Qt.WaitCursor) self.handler.select(self.selection_tool.selected_geometries, all_touched_cells=self.all_touched) self.handler.write_block(new_values) QApplication.restoreOverrideCursor() self.raster.triggerRepaint() def apply_values_single_cell(self, new_vals): """Create single cell selection and apply the new values.""" cp = self.last_point if self.logger: self.logger.debug(f"Changing single cell for pt {cp}") col, row = self.handler.point_to_index([cp.x(), cp.y()]) px, py = self.handler.index_to_point(row, col, upper_left=False) d = 0.001 bbox = QgsRectangle(px - d, py - d, px + d, py + d) if self.logger: self.logger.debug(f"Changing single cell in {bbox}") QApplication.setOverrideCursor(Qt.WaitCursor) self.handler.select([QgsGeometry.fromRect(bbox)], all_touched_cells=False, transform=False) self.handler.write_block(new_vals) QApplication.restoreOverrideCursor() self.raster.triggerRepaint() def apply_spin_box_values(self): if not self.selection_tool.selected_geometries: return self.apply_values(self.spin_boxes.get_values()) def apply_nodata_value(self): if not self.selection_tool.selected_geometries: return self.apply_values(self.handler.nodata_values) def apply_low_pass_filter(self): QApplication.setOverrideCursor(Qt.WaitCursor) self.handler.select(self.selection_tool.selected_geometries, all_touched_cells=self.all_touched) self.handler.write_block(low_pass_filter=True) QApplication.restoreOverrideCursor() self.raster.triggerRepaint() def clear_selection(self): if self.selection_tool: self.selection_tool.clear_all_selections() def selection_from_layer(self): """Create a new selection from layer.""" self.selection_tool.init_tool(self.raster, mode=self.POLYGON_SELECTION, line_width=self.get_cur_line_width()) dlg = LayerSelectDialog() if not dlg.exec_(): return cur_layer = dlg.cbo.currentLayer() if not cur_layer.type() == QgsMapLayerType.VectorLayer: return self.selection_tool.selection_from_layer(cur_layer) def selection_to_layer(self): """Create a memory layer from current selection""" geoms = self.selection_tool.selected_geometries if geoms is None or not self.raster: return crs_str = self.raster.crs().toProj() nr = self.selection_layers_count self.selection_layers_count += 1 mlayer = QgsVectorLayer(f"Polygon?crs={crs_str}&field=fid:int", f"Raster selection {nr}", "memory") fields = mlayer.dataProvider().fields() features = [] for i, geom in enumerate(geoms): feat = QgsFeature(fields) feat["fid"] = i + 1 feat.setGeometry(geom) features.append(feat) mlayer.dataProvider().addFeatures(features) self.project.addMapLayer(mlayer) def toggle_all_touched(self): """Toggle selection mode.""" # button is toggled automatically when clicked, just update the attribute self.all_touched = self.toggle_all_touched_btn.isChecked() def point_clicked(self, point=None, button=None): if self.raster is None: self.uc.bar_warn("Choose a raster to work with...", dur=3) return if self.logger: self.logger.debug(f"Clicked point in canvas CRS: {point if point else self.last_point}") if point is None: ptxy_in_src_crs = self.last_point else: if self.crs_transform: if self.logger: self.logger.debug(f"Transforming clicked point {point}") try: ptxy_in_src_crs = self.crs_transform.transform(point) except QgsCsException as err: self.uc.show_warn( "Point coordinates transformation failed! Check the raster projection:\n\n{}".format(repr(err))) return else: ptxy_in_src_crs = QgsPointXY(point.x(), point.y()) if self.logger: self.logger.debug(f"Clicked point in raster CRS: {ptxy_in_src_crs}") self.last_point = ptxy_in_src_crs ident_vals = self.handler.provider.identify(ptxy_in_src_crs, QgsRaster.IdentifyFormatValue).results() cur_vals = list(ident_vals.values()) # check if the point is within active raster extent if not self.rbounds[0] <= ptxy_in_src_crs.x() <= self.rbounds[2]: self.uc.bar_info("Out of x bounds", dur=3) return if not self.rbounds[1] <= ptxy_in_src_crs.y() <= self.rbounds[3]: self.uc.bar_info("Out of y bounds", dur=3) return if self.mode == 'draw': new_vals = self.spin_boxes.get_values() if self.logger: self.logger.debug(f"Applying const value {new_vals}") self.apply_values_single_cell(new_vals) else: self.spin_boxes.set_values(cur_vals) if 2 < self.handler.bands_nr < 5: self.color_picker_connection(connect=False) self.color_btn.setColor(QColor(*self.spin_boxes.get_values()[:4])) self.color_picker_connection(connect=True) def set_values_from_picker(self, c): """Set bands spinboxes values after color change in the color picker""" values = None if self.handler.bands_nr > 2: values = [c.red(), c.green(), c.blue()] if self.handler.bands_nr == 4: values.append(c.alpha()) if values: self.spin_boxes.set_values(values) def set_nodata(self): """Set NoData value(s) for each band of current raster.""" if not self.raster: self.uc.bar_warn('Select a raster layer to define/change NoData value!') return if self.handler.provider.userNoDataValues(1): note = '\nNote: there is a user defined NODATA value.\nCheck the raster properties (Transparency).' else: note = '' dt = self.handler.provider.dataType(1) # current NODATA value if self.handler.provider.sourceHasNoDataValue(1): cur_nodata = self.handler.provider.sourceNoDataValue(1) if dt < 6: cur_nodata = '{0:d}'.format(int(float(cur_nodata))) else: cur_nodata = '' label = 'Define/change raster NODATA value.\n\n' label += 'Raster src_data type: {}.{}'.format(dtypes[dt]['name'], note) nd, ok = QInputDialog.getText(None, "Define NODATA Value", label, QLineEdit.Normal, str(cur_nodata)) if not ok: return if not is_number(nd): self.uc.show_warn('Wrong NODATA value!') return new_nodata = int(nd) if dt < 6 else float(nd) # set the NODATA value for each band res = [] for nr in self.handler.bands_range: res.append(self.handler.provider.setNoDataValue(nr, new_nodata)) self.handler.provider.sourceHasNoDataValue(nr) if False in res: self.uc.show_warn('Setting new NODATA value failed!') else: self.uc.bar_info('Successful setting new NODATA values!', dur=2) self.set_active_raster() self.raster.triggerRepaint() def check_undo_redo_btns(self): """Enable/Disable undo and redo buttons based on availability of undo/redo for current raster.""" self.undo_btn.setDisabled(True) self.redo_btn.setDisabled(True) if self.raster is None or self.raster.id() not in self.changes: return changes = self.changes[self.raster.id()] if changes.nr_undos() > 0: self.undo_btn.setEnabled(True) if changes.nr_redos() > 0: self.redo_btn.setEnabled(True) def enable_toolbar_actions(self, enable=True): """Enable / disable all toolbar actions but Help (for vectors and unsupported rasters)""" for widget in self.actions + [self.width_unit_cbo, self.line_width_sbox]: widget.setEnabled(enable) if widget in self.actions_always_on: widget.setEnabled(True) self.spin_boxes.enable(enable) @staticmethod def check_layer(layer): """Check if we can work with the raster""" if layer is None: return False if layer.type() != QgsMapLayerType.RasterLayer: return False if layer.providerType() != 'gdal': return False if all([ layer.isValid(), layer.crs() is not None, check_gdal_driver_create_option(layer), # GDAL driver has CREATE option os.path.isfile(layer.dataProvider().dataSourceUri()), # is it a local file? ]): return True else: return False def set_bands_cbo(self): self.bands_cbo.currentIndexChanged.disconnect(self.update_active_bands) self.bands_cbo.clear() for band in self.handler.bands_range: self.bands_cbo.addItem(f"{band}", [band]) if self.handler.bands_nr > 1: self.bands_cbo.addItem(self.RGB, [1, 2, 3]) self.bands_cbo.setCurrentIndex(0) self.bands_cbo.currentIndexChanged.connect(self.update_active_bands) def update_active_bands(self, idx): bands = self.bands_cbo.currentData() self.handler.active_bands = bands self.spin_boxes.create_spinboxes(bands, self.handler.data_types, self.handler.nodata_values) self.color_btn.setEnabled(len(bands) > 1) self.exp_dlg_btn.setEnabled(len(bands) == 1) def set_active_raster(self): """Active layer has changed - check if it is a raster layer and prepare it for the plugin""" old_spin_boxes_values = self.spin_boxes.get_values() self.crs_transform = None layer = self.iface.activeLayer() if self.check_layer(layer): self.raster = layer self.crs_transform = None if self.project.crs() == self.raster.crs() else \ QgsCoordinateTransform(self.project.crs(), self.raster.crs(), self.project) self.handler = RasterHandler(self.raster, self.uc, self.debug) supported, unsupported_type = self.handler.write_supported() if supported: self.enable_toolbar_actions() self.set_bands_cbo() self.spin_boxes.create_spinboxes(self.handler.active_bands, self.handler.data_types, self.handler.nodata_values) if self.handler.bands_nr == len(old_spin_boxes_values): self.spin_boxes.set_values(old_spin_boxes_values) self.bands_cbo.setEnabled(self.handler.bands_nr > 1) self.color_btn.setEnabled(len(self.handler.active_bands) > 1) self.rbounds = self.raster.extent().toRectF().getCoords() self.handler.raster_changed.connect(self.add_to_undo) if self.raster.id() not in self.changes: self.changes[self.raster.id()] = RasterChanges(nr_to_keep=self.settings["undo_steps"]) else: msg = f"The raster has unsupported src_data type: {unsupported_type}" msg += "\nServal can't work with it, sorry..." self.uc.show_warn(msg) self.enable_toolbar_actions(enable=False) self.reset_raster() else: # unsupported raster self.enable_toolbar_actions(enable=False) self.reset_raster() self.check_undo_redo_btns() def add_to_undo(self, change): """Add the old and new blocks to undo stack.""" self.changes[self.raster.id()].add_change(change) self.check_undo_redo_btns() if self.logger: self.logger.debug(self.get_undo_redo_values()) def get_undo_redo_values(self): changes = self.changes[self.raster.id()] return f"nr undos: {changes.nr_undos()}, redos: {changes.nr_redos()}" def undo(self): undo_data = self.changes[self.raster.id()].undo() self.handler.write_block_undo(undo_data) self.raster.triggerRepaint() self.check_undo_redo_btns() def redo(self): redo_data = self.changes[self.raster.id()].redo() self.handler.write_block_undo(redo_data) self.raster.triggerRepaint() self.check_undo_redo_btns() def reset_raster(self): self.raster = None self.color_btn.setDisabled(True) def color_picker_connection(self, connect=True): if connect: self.color_btn.colorChanged.connect(self.set_values_from_picker) else: self.color_btn.colorChanged.disconnect(self.set_values_from_picker) @staticmethod def show_website(): QDesktopServices.openUrl(QUrl("https://github.com/lutraconsulting/serval/blob/master/Serval/docs/user_manual.md")) def recreate_spatial_index(self, layer): """Check if spatial index exists for the layer and if it is relatively old and eventually recreate it.""" ctime = self.spatial_index_time[layer.id()] if layer.id() in self.spatial_index_time else None if ctime is None or datetime.now() - ctime > timedelta(seconds=30): self.spatial_index = QgsSpatialIndex(layer.getFeatures(), None, QgsSpatialIndex.FlagStoreFeatureGeometries) self.spatial_index_time[layer.id()] = datetime.now() def get_nearest_feature(self, pt_feat, vlayer_id): """Given the point feature, return nearest feature from vlayer.""" vlayer = self.project.mapLayer(vlayer_id) self.recreate_spatial_index(vlayer) ptxy = pt_feat.geometry().asPoint() near_fid = self.spatial_index.nearestNeighbor(ptxy)[0] return vlayer.getFeature(near_fid) def nearest_feature_attr_value(self, pt_feat, vlayer_id, attr_name): """Find nearest feature to pt_feat and return its attr_name attribute value.""" near_feat = self.get_nearest_feature(pt_feat, vlayer_id) return near_feat[attr_name] def nearest_pt_on_line_interpolate_z(self, pt_feat, vlayer_id): """Find nearest line feature to pt_feat and interpolate z value from vertices.""" near_feat = self.get_nearest_feature(pt_feat, vlayer_id) near_geom = near_feat.geometry() closest_pt_dist = near_geom.lineLocatePoint(pt_feat.geometry()) closest_pt = near_geom.interpolate(closest_pt_dist) return closest_pt.get().z() def intersecting_features_attr_average(self, pt_feat, vlayer_id, attr_name, only_center): """ Find all features intersecting current feature (cell center, or raster cell polygon) and calculate average value of their attr_name attribute. """ vlayer = self.project.mapLayer(vlayer_id) self.recreate_spatial_index(vlayer) ptxy = pt_feat.geometry().asPoint() pt_x, pt_y = ptxy.x(), ptxy.y() dxy = 0.001 half_pix_x = self.handler.pixel_size_x / 2. half_pix_y = self.handler.pixel_size_y / 2. if only_center: cell = QgsRectangle(pt_x, pt_y, pt_x + dxy, pt_y + dxy) else: cell = QgsRectangle(pt_x - half_pix_x, pt_y - half_pix_y, pt_x + half_pix_x, pt_y + half_pix_y) inter_fids = self.spatial_index.intersects(cell) values = [] for fid in inter_fids: feat = vlayer.getFeature(fid) if not feat.geometry().intersects(cell): continue val = feat[attr_name] if not is_number(val): continue values.append(val) if len(values) == 0: return None return sum(values) / float(len(values)) def interpolate_from_mesh(self, pt_feat, mesh_layer_id, group, dataset, above_existing): """Interpolate from mesh.""" mesh_layer = self.project.mapLayer(mesh_layer_id) ptxy = pt_feat.geometry().asPoint() dataset_val = mesh_layer.datasetValue(QgsMeshDatasetIndex(group, dataset), ptxy) val = dataset_val.scalar() if math.isnan(val): return val if above_existing: ident_vals = self.handler.provider.identify(ptxy, QgsRaster.IdentifyFormatValue).results() org_val = list(ident_vals.values())[0] if org_val == self.handler.nodata_values[0]: return val return max(org_val, val) else: return val
def __init__(self, canvas): QgsMapToolEmitPoint.__init__(self, canvas) self.canvas = canvas self.cursor = Qt.CrossCursor
def __init__(self, canvas): QgsMapToolEmitPoint.__init__(self, canvas) self.canvas = canvas self.cursor = Qt.ArrowCursor
# import the map tool to use from qgis.gui import QgsMapToolZoom # get previous map tool and print it oldMapTool = iface.mapCanvas().mapTool() print("Previous map tool is a", oldMapTool) # create a zoom map tool pointing to the current canvas # the boolean parameter is False to zoom in and True to zoom out newMapTool = QgsMapToolZoom( iface.mapCanvas(), False) # set the current map tool and print it iface.mapCanvas().setMapTool( newMapTool ) print("Current map tool is a", iface.mapCanvas().mapTool()) # # here is your code # # set the previous map tool and print it iface.mapCanvas().setMapTool( oldMapTool ) print("Current map tool is a ", iface.mapCanvas().mapTool()) previousMapTool = iface.mapCanvas().mapTool() from qgis.gui import QgsMapToolEmitPoint myMapTool = QgsMapToolEmitPoint(iface.mapCanvas()) def showCoordinates(currentPos): print("move coordinate %d - %d" % (currentPos.x(), currentPos.y())) iface.mapCanvas().xyCoordinates.connect( showCoordinates )
def __init__(self, iface): self.iface = iface self.canvas = self.iface.mapCanvas() QgsMapToolEmitPoint.__init__(self, self.canvas)