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()
示例#2
0
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.geometryHandler = GeometryHandler(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):
        qgisSettings = QSettings()
        qgisSettings.beginGroup('qgis/digitizing')
        setting = qgisSettings.value('disable_enter_attribute_values_dialog')
        qgisSettings.endGroup()
        return setting

    def setRubberbandParameters(self):
        self.rubberBand = QgsRubberBand(self.canvas,
                                        QgsWkbTypes.PolygonGeometry)
        self.hoverRubberBand = QgsRubberBand(self.canvas,
                                             QgsWkbTypes.PolygonGeometry)
        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(QgsWkbTypes.PolygonGeometry)

    def canvasPressEvent(self, e):
        """
        Method used to build rectangle if shift is held, otherwise, feature select/deselect and identify is done.
        :param e: (QgsMouseEvent) mouse event.
        """
        if e.button() == QtCore.Qt.LeftButton:
            self.auxList = []
            if 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(QgsWkbTypes.PolygonGeometry)
        if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
            return
        point1 = QgsPointXY(startPoint.x(), startPoint.y())
        point2 = QgsPointXY(startPoint.x(), endPoint.y())
        point3 = QgsPointXY(endPoint.x(), endPoint.y())
        point4 = QgsPointXY(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.
        """
        # tool was planned to work on left click
        if e.button() == QtCore.Qt.LeftButton:
            layer = self.iface.mapCanvas().currentLayer()
            if 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.selectByIds([])  #portar para o feature handler
                layer.selectByRect(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:
                    value = pixelValueDict[idx]
                    if value:
                        self.auxList.append({
                            'featId': idx,
                            'feat': featDict[idx],
                            'value': value
                        })
            else:
                value, pointGeom = self.getPixelValue(self.rasterLayer)
                if value:
                    self.auxList.append({'geom': pointGeom, 'value': value})
            #create context menu to select attribute
            if self.auxList:
                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 = partial(self.handleFeatures, field, layer)
            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:
                self.geometryHandler.reprojectFeature(item['geom'],
                                                      layer.crs())
                feature = QgsVectorLayerUtils.createFeature(
                    layer, item['geom'])
                self.addFeature(feature, layer, selectedField, item['value'])
        self.auxList = []
        self.canvas.refresh()

    def addFeature(self, feature, layer, field, pointValue):
        fields = layer.fields()
        provider = layer.dataProvider()
        for i in range(fields.count()):
            value = provider.defaultValue(
                i) if fields[i].name() != field else pointValue
            if value is not None:
                feature.setAttribute(i, value)
        form = QgsAttributeDialog(layer, feature, False)
        form.setMode(int(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)
            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)

    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.
        """
        QApplication.restoreOverrideCursor()
        self.hoverRubberBand.reset(QgsWkbTypes.PolygonGeometry)
        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)
        layer = self.iface.mapCanvas().currentLayer()
        if not layer or not isinstance(layer, QgsVectorLayer):
            self.iface.messageBar().pushMessage(
                self.tr("Warning"),
                self.tr("Select a point vector layer as the active layer"),
                level=Qgis.Warning,
                duration=5)
            self.deactivate()

    def getPixelValue(self, rasterLayer):
        mousePos = self.qgsMapToolEmitPoint.toMapCoordinates(
            self.canvas.mouseLastXY())
        mousePosGeom = QgsGeometry.fromPointXY(mousePos)
        return self.getPixelValueFromPoint(mousePosGeom,
                                           rasterLayer), mousePosGeom

    def getPixelValueFromPoint(self,
                               mousePosGeom,
                               rasterLayer,
                               fromCanvas=True):
        """
        
        """
        rasterCrs = rasterLayer.crs()
        # if fromCanvas:
        #     self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs, QgsProject.instance().crs())
        # else:
        mousePosGeom = QgsGeometry(mousePosGeom)
        self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs,
                                              self.canvas.currentLayer().crs())
        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 = list(i.results().values())[0]
            if value:
                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.items()
        }  #no python3 eh items()
示例#3
0
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 )