Exemplo n.º 1
0
    def popup(self, pos=None, searchText=""):
        """
        Popup the menu at `pos` (in screen coordinates). 'Search' text field
        is initialized with `searchText` if provided.

        """
        if pos is None:
            pos = QPoint()

        self.__clearCurrentItems()

        self.__search.setText(searchText)
        patt = QRegExp("(^|\W)"+searchText)
        patt.setCaseSensitivity(False)
        self.__suggestPage.setFilterRegExp(patt)

        self.ensurePolished()

        if self.testAttribute(Qt.WA_Resized) and self.sizeGripEnabled():
            size = self.size()
        else:
            size = self.sizeHint()

        desktop = QApplication.desktop()
        screen_geom = desktop.availableGeometry(pos)

        # Adjust the size to fit inside the screen.
        if size.height() > screen_geom.height():
            size.setHeight(screen_geom.height())
        if size.width() > screen_geom.width():
            size.setWidth(screen_geom.width())

        geom = QRect(pos, size)

        if geom.top() < screen_geom.top():
            geom.setTop(screen_geom.top())

        if geom.left() < screen_geom.left():
            geom.setLeft(screen_geom.left())

        bottom_margin = screen_geom.bottom() - geom.bottom()
        right_margin = screen_geom.right() - geom.right()
        if bottom_margin < 0:
            # Falls over the bottom of the screen, move it up.
            geom.translate(0, bottom_margin)

        # TODO: right to left locale
        if right_margin < 0:
            # Falls over the right screen edge, move the menu to the
            # other side of pos.
            geom.translate(-size.width(), 0)

        self.setGeometry(geom)

        self.show()

        if searchText:
            self.setFocusProxy(self.__search)
        else:
            self.setFocusProxy(None)
Exemplo n.º 2
0
    def popup(self, pos=None, searchText=""):
        """
        Popup the menu at `pos` (in screen coordinates). 'Search' text field
        is initialized with `searchText` if provided.

        """
        if pos is None:
            pos = QPoint()

        self.__clearCurrentItems()

        self.__search.setText(searchText)
        patt = QRegExp("(^|\W)" + searchText)
        patt.setCaseSensitivity(False)
        self.__suggestPage.setFilterRegExp(patt)

        self.ensurePolished()

        if self.testAttribute(Qt.WA_Resized) and self.sizeGripEnabled():
            size = self.size()
        else:
            size = self.sizeHint()

        desktop = QApplication.desktop()
        screen_geom = desktop.availableGeometry(pos)

        # Adjust the size to fit inside the screen.
        if size.height() > screen_geom.height():
            size.setHeight(screen_geom.height())
        if size.width() > screen_geom.width():
            size.setWidth(screen_geom.width())

        geom = QRect(pos, size)

        if geom.top() < screen_geom.top():
            geom.setTop(screen_geom.top())

        if geom.left() < screen_geom.left():
            geom.setLeft(screen_geom.left())

        bottom_margin = screen_geom.bottom() - geom.bottom()
        right_margin = screen_geom.right() - geom.right()
        if bottom_margin < 0:
            # Falls over the bottom of the screen, move it up.
            geom.translate(0, bottom_margin)

        # TODO: right to left locale
        if right_margin < 0:
            # Falls over the right screen edge, move the menu to the
            # other side of pos.
            geom.translate(-size.width(), 0)

        self.setGeometry(geom)

        self.show()

        if searchText:
            self.setFocusProxy(self.__search)
        else:
            self.setFocusProxy(None)
Exemplo n.º 3
0
def applyMargin(rect, margin):
    result = QRect(rect)
    result.setLeft(result.left()+margin)
    result.setRight(result.right()-margin)
    result.setTop(result.top()+margin)
    result.setBottom(result.bottom()-margin)
    return result
Exemplo n.º 4
0
 def calculateLogicalRect(self, physicalRect):
     gridX = self.parent().width() / 40
     gridY = self.parent().height() / 30
     logicalRect = QRect()
     logicalRect.setTop(round(physicalRect.top() / gridY))
     logicalRect.setLeft(round(physicalRect.left() / gridX))
     logicalRect.setWidth(round(physicalRect.width() / gridX))
     logicalRect.setHeight(round(physicalRect.height() / gridY))
     return logicalRect
Exemplo n.º 5
0
 def paint(self, painter, option, index):
     painter.setFont(option.font)
     painter.setBrush(QBrush(Qt.black))
     if option.state & QStyle.State_Selected:
         painter.setPen(QPen(Qt.white))
     rect = QRect(option.rect)
     rect.setLeft(rect.left() + 4)
     rect.setTop(rect.top() + 4)
     rect.setWidth(rect.width() - 8)
     rect.setHeight(rect.height() - 8)
     painter.drawText(rect, Qt.Horizontal | Qt.TextWordWrap,
                      forceString(index.data()))
Exemplo n.º 6
0
 def paint(self, painter, option, index):
     self.initStyleOption(option, index)
     # No idea why, but this cast is required if we want to have access to the V4 valuess
     option = QStyleOptionViewItemV4(option)
     if (index.column() == 1) and (option.state & QStyle.State_Selected):
         cboption = QStyleOptionComboBox()
         cboption.rect = option.rect
         # On OS X (with Qt4.6.0), adding State_Enabled to the flags causes the whole drawing to
         # fail (draw nothing), but it's an OS X only glitch. On Windows, it works alright.
         cboption.state |= QStyle.State_Enabled
         QApplication.style().drawComplexControl(QStyle.CC_ComboBox, cboption, painter)
         painter.setBrush(option.palette.text())
         rect = QRect(option.rect)
         rect.setLeft(rect.left()+4)
         painter.drawText(rect, Qt.AlignLeft, option.text)
     else:
         QStyledItemDelegate.paint(self, painter, option, index)
Exemplo n.º 7
0
 def paint(self, painter, option, index):
     self.initStyleOption(option, index)
     # No idea why, but this cast is required if we want to have access to the V4 valuess
     option = QStyleOptionViewItemV4(option)
     if (index.column() == 1) and (option.state & QStyle.State_Selected):
         cboption = QStyleOptionComboBox()
         cboption.rect = option.rect
         # On OS X (with Qt4.6.0), adding State_Enabled to the flags causes the whole drawing to
         # fail (draw nothing), but it's an OS X only glitch. On Windows, it works alright.
         cboption.state |= QStyle.State_Enabled
         QApplication.style().drawComplexControl(QStyle.CC_ComboBox,
                                                 cboption, painter)
         painter.setBrush(option.palette.text())
         rect = QRect(option.rect)
         rect.setLeft(rect.left() + 4)
         painter.drawText(rect, Qt.AlignLeft, option.text)
     else:
         QStyledItemDelegate.paint(self, painter, option, index)
Exemplo n.º 8
0
 def renderSplit(self, painter, rowStats, splitsRect):
     painter.setFont(self.ds.splitFont())
     splitValues = [self.ds.splitValues(rowStats.index, i) for i in range(rowStats.splitCount)]
     colWidths = [0, 0, 0]
     for sv in splitValues:
         colWidths[0] = max(colWidths[0], self.stats.splitFM.width(sv.account))
         colWidths[1] = max(colWidths[1], self.stats.splitFM.width(sv.memo))
         colWidths[2] = max(colWidths[2], self.stats.splitFM.width(sv.amount))
     top = splitsRect.top()
     for sv in splitValues:
         rect = QRect(splitsRect.left(), top, colWidths[0], self.stats.splitHeight)
         painter.drawText(rect, Qt.AlignLeft, sv.account)
         rect.setLeft(rect.right() + SPLIT_XPADDING)
         rect.setWidth(colWidths[1])
         painter.drawText(rect, Qt.AlignLeft, sv.memo)
         rect.setLeft(rect.right() + SPLIT_XPADDING)
         rect.setWidth(colWidths[2])
         painter.drawText(rect, Qt.AlignRight, sv.amount)
         top += self.stats.splitHeight
Exemplo n.º 9
0
def widget_popup_geometry(pos, widget):
    widget.ensurePolished()

    if widget.testAttribute(Qt.WA_Resized):
        size = widget.size()
    else:
        size = widget.sizeHint()

    desktop = QApplication.desktop()
    screen_geom = desktop.availableGeometry(pos)

    # Adjust the size to fit inside the screen.
    if size.height() > screen_geom.height():
        size.setHeight(screen_geom.height())
    if size.width() > screen_geom.width():
        size.setWidth(screen_geom.width())

    geom = QRect(pos, size)

    if geom.top() < screen_geom.top():
        geom.setTop(screen_geom.top())

    if geom.left() < screen_geom.left():
        geom.setLeft(screen_geom.left())

    bottom_margin = screen_geom.bottom() - geom.bottom()
    right_margin = screen_geom.right() - geom.right()
    if bottom_margin < 0:
        # Falls over the bottom of the screen, move it up.
        geom.translate(0, bottom_margin)

    # TODO: right to left locale
    if right_margin < 0:
        # Falls over the right screen edge, move the menu to the
        # other side of pos.
        geom.translate(-size.width(), 0)

    return geom
Exemplo n.º 10
0
def widget_popup_geometry(pos, widget):
    widget.ensurePolished()

    if widget.testAttribute(Qt.WA_Resized):
        size = widget.size()
    else:
        size = widget.sizeHint()

    desktop = QApplication.desktop()
    screen_geom = desktop.availableGeometry(pos)

    # Adjust the size to fit inside the screen.
    if size.height() > screen_geom.height():
        size.setHeight(screen_geom.height())
    if size.width() > screen_geom.width():
        size.setWidth(screen_geom.width())

    geom = QRect(pos, size)

    if geom.top() < screen_geom.top():
        geom.setTop(screen_geom.top())

    if geom.left() < screen_geom.left():
        geom.setLeft(screen_geom.left())

    bottom_margin = screen_geom.bottom() - geom.bottom()
    right_margin = screen_geom.right() - geom.right()
    if bottom_margin < 0:
        # Falls over the bottom of the screen, move it up.
        geom.translate(0, bottom_margin)

    # TODO: right to left locale
    if right_margin < 0:
        # Falls over the right screen edge, move the menu to the
        # other side of pos.
        geom.translate(-size.width(), 0)

    return geom
class MincutConnec(QgsMapTool):

    canvasClicked = pyqtSignal()

    def __init__(self, iface, controller):
        """ Class constructor """

        self.iface = iface
        self.canvas = self.iface.mapCanvas()
        self.controller = controller
        # Call superclass constructor and set current action
        QgsMapTool.__init__(self, self.canvas)

        self.dragging = False

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

        # Rubber band
        self.rubber_band = QgsRubberBand(self.canvas, QGis.Line)
        self.rubber_band.setColor(color)
        self.rubber_band.setWidth(1)

        # Select rectangle
        self.select_rect = QRect()

        # TODO: Parametrize
        self.connec_group = ["Wjoin", "Tap", "Fountain", "Greentap"]
        #self.snapperManager = SnappingConfigManager(self.iface)
        self.snapper = QgsMapCanvasSnapper(self.canvas)

    def activate(self):
        pass

    def canvasPressEvent(self, event):  #@UnusedVariable
        self.select_rect.setRect(0, 0, 0, 0)
        self.rubber_band.reset()

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

        if event.buttons() == Qt.LeftButton:
            if not self.dragging:
                self.dragging = True
                self.select_rect.setTopLeft(event.pos())
            self.select_rect.setBottomRight(event.pos())
            self.set_rubber_band()

        else:
            # Hide highlight
            self.vertex_marker.hide()

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            event_point = QPoint(x, y)

            # Snapping
            (retval, result) = self.snapper.snapToBackgroundLayers(
                event_point)  # @UnusedVariable

            # That's the snapped point
            if result:
                # Check feature
                for snap_point in result:
                    element_type = snap_point.layer.name()
                    if element_type in self.connec_group:
                        # Get the point
                        point = QgsPoint(snap_point.snappedVertex)
                        # Add marker
                        self.vertex_marker.setCenter(point)
                        self.vertex_marker.show()
                        break

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

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

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            event_point = QPoint(x, y)

            # Not dragging, just simple selection
            if not self.dragging:

                # Snap to node
                (retval, result) = self.snapper.snapToBackgroundLayers(
                    event_point)  # @UnusedVariable

                # That's the snapped point
                if result:
                    # Check feature
                    for snapped_point in result:
                        element_type = snapped_point.layer.name()
                        if element_type in self.connec_group:
                            feat_type = 'connec'
                        else:
                            continue

                        point = QgsPoint(
                            snapped_point.snappedVertex)  # @UnusedVariable
                        # layer.removeSelection()
                        # layer.select([result[0].snappedAtGeometry])

                        #snapped_point.layer.removeSelection()
                        snapped_point.layer.select(
                            [snapped_point.snappedAtGeometry])

            else:

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

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

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

            # Refresh map canvas
            self.rubber_band.reset()
            self.refresh_map_canvas()

    def set_rubber_band(self):

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

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

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

        self.selected_rectangle = QgsRectangle(ll, ur)

    def select_multiple_features(self, rectangle):

        if self.connec_group is None:
            return

        if QGis.QGIS_VERSION_INT >= 21600:

            # Selection for all connec group layers
            for layer_name in self.connec_group:
                # Get layer by his name
                layer = self.controller.get_layer_by_layername(layer_name,
                                                               log_info=True)
                if layer:
                    self.group_pointers_connec.append(layer)
                    layer.selectByRect(rectangle)

        else:
            for layer_name in self.connec_group:
                self.iface.setActiveLayer(layer)
                layer.removeSelection()
                layer.select(rectangle, True)
Exemplo n.º 12
0
class BrushingModel(QObject):
    brushSizeChanged     = pyqtSignal(int)
    brushColorChanged    = pyqtSignal(QColor)
    brushStrokeAvailable = pyqtSignal(QPointF, object)
    drawnNumberChanged   = pyqtSignal(int)
    
    minBrushSize       = 1
    maxBrushSize       = 61
    defaultBrushSize   = 3
    defaultDrawnNumber = 1
    defaultColor       = Qt.white
    erasingColor       = Qt.black
    erasingNumber      = 100
    
    def __init__(self):
        QObject.__init__(self)
        self.sliceRect = None
        self.bb    = QRect() #bounding box enclosing the drawing
        self.brushSize = self.defaultBrushSize
        self.drawColor = self.defaultColor
        self._temp_color = None
        self._temp_number = None
        self.drawnNumber = self.defaultDrawnNumber

        self.pos = None
        self.erasing = False
        
        self.drawOnto = None
        
        #an empty scene, where we add all drawn line segments
        #a QGraphicsLineItem, and which we can use to then
        #render to an image
        self.scene = QGraphicsScene()

    def toggleErase(self):
        self.erasing = not(self.erasing)
        if self.erasing:
            self.setErasing()
        else:
            self.disableErasing()

    def setErasing(self):
        self.erasing = True
        self._temp_color = self.drawColor
        self._temp_number = self.drawnNumber
        self.setBrushColor(self.erasingColor)
        self.brushColorChanged.emit(self.erasingColor)
        self.setDrawnNumber(self.erasingNumber)
    
    def disableErasing(self):
        self.erasing = False
        self.setBrushColor(self._temp_color)
        self.brushColorChanged.emit(self.drawColor)
        self.setDrawnNumber(self._temp_number)

    def setBrushSize(self, size):
        self.brushSize = size
        self.brushSizeChanged.emit(self.brushSize)
    
    def setDrawnNumber(self, num):
        print "Setting Drawnnumer", num
        self.drawnNumber = num
        self.drawnNumberChanged.emit(num)
        
    def getBrushSize(self):
        return self.brushSize
    
    def brushSmaller(self):
        b = self.brushSize
        if b > self.minBrushSize:
            self.setBrushSize(b-1)
        
    def brushBigger(self):
        b = self.brushSize
        if self.brushSize < self.maxBrushSize:
            self.setBrushSize(b+1)
        
    def setBrushColor(self, color):
        self.drawColor = color
        self.brushColorChanged.emit(self.drawColor)
    
    def beginDrawing(self, pos, sliceRect):
        self.sliceRect = sliceRect
        self.scene.clear()
        self.bb = QRect()
        self.pos = QPointF(pos.x()+0.0001, pos.y()+0.0001)
        line = self.moveTo(pos)
        return line

    def endDrawing(self, pos):
        self.moveTo(pos)

        tempi = QImage(QSize(self.bb.width(), self.bb.height()), QImage.Format_ARGB32_Premultiplied) #TODO: format
        tempi.fill(0)
        painter = QPainter(tempi)
        self.scene.render(painter, target=QRectF(), source=QRectF(QPointF(self.bb.x(), self.bb.y()), QSizeF(self.bb.width(), self.bb.height())))
        painter.end()
        
        ndarr = qimage2ndarray.rgb_view(tempi)[:,:,0]
        labels = numpy.where(ndarr>0,numpy.uint8(self.drawnNumber),numpy.uint8(0))
        labels = labels.swapaxes(0,1)
        assert labels.shape[0] == self.bb.width()
        assert labels.shape[1] == self.bb.height()

        self.brushStrokeAvailable.emit(QPointF(self.bb.x(), self.bb.y()), labels)

    def dumpDraw(self, pos):
        res = self.endDrawing(pos)
        self.beginDrawing(pos, self.sliceRect)
        return res

    def moveTo(self, pos):
        oldX, oldY = self.pos.x(), self.pos.y()
        x,y = pos.x(), pos.y()
        
        #print "BrushingModel.moveTo(pos=%r)" % (pos) 
        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(QPen( QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.scene.addItem(line)

        #update bounding Box 
        if not self.bb.isValid():
            self.bb = QRect(QPoint(x,y), QSize(1,1))
        #grow bounding box
        self.bb.setLeft(  min(self.bb.left(),   max(0,                   x-self.brushSize/2-1) ) )
        self.bb.setRight( max(self.bb.right(),  min(self.sliceRect[0]-1, x+self.brushSize/2+1) ) )
        self.bb.setTop(   min(self.bb.top(),    max(0,                   y-self.brushSize/2-1) ) )
        self.bb.setBottom(max(self.bb.bottom(), min(self.sliceRect[1]-1, y+self.brushSize/2+1) ) )
        
        #update/move position
        self.pos = pos
Exemplo n.º 13
0
class BrushingModel(QObject):
    brushSizeChanged = pyqtSignal(int)
    brushColorChanged = pyqtSignal(QColor)
    brushStrokeAvailable = pyqtSignal(QPointF, object)
    drawnNumberChanged = pyqtSignal(int)

    minBrushSize = 1
    maxBrushSize = 61
    defaultBrushSize = 3
    defaultDrawnNumber = 1
    defaultColor = Qt.white
    erasingColor = Qt.black
    erasingNumber = 100

    def __init__(self, parent=None):
        QObject.__init__(self, parent=parent)
        self.sliceRect = None
        self.bb = QRect()  #bounding box enclosing the drawing
        self.brushSize = self.defaultBrushSize
        self.drawColor = self.defaultColor
        self._temp_color = None
        self._temp_number = None
        self.drawnNumber = self.defaultDrawnNumber

        self.pos = None
        self.erasing = False
        self._hasMoved = False

        self.drawOnto = None

        #an empty scene, where we add all drawn line segments
        #a QGraphicsLineItem, and which we can use to then
        #render to an image
        self.scene = QGraphicsScene()

    def toggleErase(self):
        self.erasing = not (self.erasing)
        if self.erasing:
            self.setErasing()
        else:
            self.disableErasing()

    def setErasing(self):
        self.erasing = True
        self._temp_color = self.drawColor
        self._temp_number = self.drawnNumber
        self.setBrushColor(self.erasingColor)
        self.brushColorChanged.emit(self.erasingColor)
        self.setDrawnNumber(self.erasingNumber)

    def disableErasing(self):
        self.erasing = False
        self.setBrushColor(self._temp_color)
        self.brushColorChanged.emit(self.drawColor)
        self.setDrawnNumber(self._temp_number)

    def setBrushSize(self, size):
        self.brushSize = size
        self.brushSizeChanged.emit(self.brushSize)

    def setDrawnNumber(self, num):
        self.drawnNumber = num
        self.drawnNumberChanged.emit(num)

    def getBrushSize(self):
        return self.brushSize

    def brushSmaller(self):
        b = self.brushSize
        if b > self.minBrushSize:
            self.setBrushSize(b - 1)

    def brushBigger(self):
        b = self.brushSize
        if self.brushSize < self.maxBrushSize:
            self.setBrushSize(b + 1)

    def setBrushColor(self, color):
        self.drawColor = color
        self.brushColorChanged.emit(self.drawColor)

    def beginDrawing(self, pos, sliceRect):
        '''

        pos -- QPointF-like
        '''
        self.sliceRect = sliceRect
        self.scene.clear()
        self.bb = QRect()
        self.pos = QPointF(pos.x(), pos.y())
        self._hasMoved = False

    def endDrawing(self, pos):
        has_moved = self._hasMoved  # _hasMoved will change after calling moveTo
        if has_moved:
            self.moveTo(pos)
        else:
            assert (self.pos == pos)
            self.moveTo(QPointF(pos.x() + 0.0001,
                                pos.y() + 0.0001))  # move a little

        # Qt seems to use strange rules for determining which pixels to set when rendering a brush stroke to a QImage.
        # We seem to get better results if we do the following:
        # 1) Slightly offset the source window because apparently there is a small shift in the data
        # 2) Render the scene to an image that is MUCH larger than the scene resolution (4x by 4x)
        # 3) Downsample each 4x4 patch from the large image back to a single pixel in the final image,
        #     applying some threshold to determine if the final pixel is on or off.

        tempi = QImage(QSize(4 * self.bb.width(), 4 * self.bb.height()),
                       QImage.Format_ARGB32_Premultiplied)  #TODO: format
        tempi.fill(0)
        painter = QPainter(tempi)
        # Offset the source window.  At first I thought the right offset was 0.5, because
        #  that would seem to make sure points are rounded to pixel CENTERS, but
        #  experimentation indicates that 0.25 is slightly better for some reason...
        source_rect = QRectF(QPointF(self.bb.x() + 0.25,
                                     self.bb.y() + 0.25),
                             QSizeF(self.bb.width(), self.bb.height()))
        target_rect = QRectF(QPointF(0, 0),
                             QSizeF(4 * self.bb.width(), 4 * self.bb.height()))
        self.scene.render(painter, target=target_rect, source=source_rect)
        painter.end()

        # Now downsample: convert each 4x4 patch into a single pixel by summing and dividing
        ndarr = qimage2ndarray.rgb_view(tempi)[:, :, 0].astype(int)
        ndarr = ndarr.reshape((ndarr.shape[0], ) + (ndarr.shape[1] // 4, ) +
                              (4, ))
        ndarr = ndarr.sum(axis=-1)
        ndarr = ndarr.transpose()
        ndarr = ndarr.reshape((ndarr.shape[0], ) + (ndarr.shape[1] // 4, ) +
                              (4, ))
        ndarr = ndarr.sum(axis=-1)
        ndarr = ndarr.transpose()
        ndarr //= 4 * 4

        downsample_threshold = (7. / 16) * 255
        labels = numpy.where(ndarr >= downsample_threshold,
                             numpy.uint8(self.drawnNumber), numpy.uint8(0))
        labels = labels.swapaxes(0, 1)
        assert labels.shape[0] == self.bb.width()
        assert labels.shape[1] == self.bb.height()

        ##
        ## ensure that at least one pixel is label when the brush size is 1
        ##
        ## this happens when the user just clicked without moving
        ## in that case the lineitem will be so tiny, that it won't be rendered
        ## into a single pixel by the code above
        if not has_moved and self.brushSize <= 1 and numpy.count_nonzero(
                labels) == 0:
            labels[labels.shape[0] // 2,
                   labels.shape[1] // 2] = self.drawnNumber

        self.brushStrokeAvailable.emit(QPointF(self.bb.x(), self.bb.y()),
                                       labels)

    def dumpDraw(self, pos):
        res = self.endDrawing(pos)
        self.beginDrawing(pos, self.sliceRect)
        return res

    def moveTo(self, pos):
        #data coordinates
        oldX, oldY = self.pos.x(), self.pos.y()
        x, y = pos.x(), pos.y()

        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(
            QPen(QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))
        self.scene.addItem(line)
        self._hasMoved = True

        #update bounding Box
        if not self.bb.isValid():
            self.bb = QRect(QPoint(oldX, oldY), QSize(1, 1))
        #grow bounding box
        self.bb.setLeft(
            min(self.bb.left(), max(0, x - self.brushSize // 2 - 1)))
        self.bb.setRight(
            max(self.bb.right(),
                min(self.sliceRect[0] - 1, x + self.brushSize // 2 + 1)))
        self.bb.setTop(min(self.bb.top(), max(0, y - self.brushSize // 2 - 1)))
        self.bb.setBottom(
            max(self.bb.bottom(),
                min(self.sliceRect[1] - 1, y + self.brushSize // 2 + 1)))

        #update/move position
        self.pos = pos
Exemplo n.º 14
0
class ConnecMapTool(ParentMapTool):
    """ Button 20: User select connections from layer 'connec'
    Execute SQL function: 'gw_fct_connect_to_network' """
    def __init__(self, iface, settings, action, index_action):
        """ Class constructor """

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

        self.dragging = False

        # Select rectangle
        self.select_rect = QRect()

    """ QgsMapTools inherited event functions """

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

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

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

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

        else:

            # Hide marker
            self.vertex_marker.hide()

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            event_point = QPoint(x, y)

            # Snapping
            (retval, result) = self.snapper.snapToBackgroundLayers(
                event_point)  # @UnusedVariable

            # That's the snapped features
            if result:
                for snapped_feat in result:
                    # Check if it belongs to 'connec' or 'gully' group
                    exist_connec = self.snapper_manager.check_connec_group(
                        snapped_feat.layer)
                    exist_gully = self.snapper_manager.check_gully_group(
                        snapped_feat.layer)
                    if exist_connec or exist_gully:
                        # Get the point and add marker
                        point = QgsPoint(result[0].snappedVertex)
                        self.vertex_marker.setCenter(point)
                        self.vertex_marker.show()
                        break

    def canvasPressEvent(self, event):  #@UnusedVariable

        self.select_rect.setRect(0, 0, 0, 0)
        self.rubber_band.reset(QGis.Polygon)

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

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

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            event_point = QPoint(x, y)

            # Simple selection
            if not self.dragging:

                # Snap to connec or gully
                (retval, result) = self.snapper.snapToBackgroundLayers(
                    event_point)  # @UnusedVariable

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

                        # Hide marker
                        self.vertex_marker.hide()

            # Multiple selection
            else:

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

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

                self.set_rubber_band()
                selected_geom = self.rubber_band.asGeometry()  #@UnusedVariable
                self.select_multiple_features(self.selected_rectangle)
                self.dragging = False

                # Refresh map canvas
                self.rubber_band.reset()

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

            # Check selected records
            number_features = 0
            for layer in self.layer_connec_man:
                number_features += layer.selectedFeatureCount()

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

            if self.layer_gully_man:
                # Check selected records
                number_features = 0
                for layer in self.layer_gully_man:
                    number_features += layer.selectedFeatureCount()

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

    def activate(self):

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

        # Rubber band
        self.rubber_band.reset()

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

        # Clear snapping
        self.snapper_manager.clear_snapping()

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

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

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

    def deactivate(self):

        # Call parent method
        ParentMapTool.deactivate(self)

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

        # Check features selected
        number_features = 0
        for layer in layers:
            number_features += layer.selectedFeatureCount()

        if number_features == 0:
            message = "You have to select at least one feature!"
            self.controller.show_warning(message)
            return

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

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

                # Execute function
                function_name = "gw_fct_connect_to_network"
                sql = ("SELECT " + self.schema_name + "." + function_name + ""
                       "('" + list_feature_id + "', '" + geom_type.upper() +
                       "');")
                self.controller.execute_sql(sql, log_sql=True)
                layer.removeSelection()
        # Refresh map canvas
        self.rubber_band.reset()
        self.refresh_map_canvas()
        self.iface.actionPan().trigger()

    def set_rubber_band(self):

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

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

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

        self.selected_rectangle = QgsRectangle(ll, ur)

    def select_multiple_features(self, selectGeometry):

        if self.layer_connec_man is None and self.layer_gully_man is None:
            return

        key = QApplication.keyboardModifiers()

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

        # Selection for all connec and gully layers
        for layer in self.layer_connec_man:
            layer.selectByRect(selectGeometry, behaviour)

        if self.layer_gully_man:
            for layer in self.layer_gully_man:
                layer.selectByRect(selectGeometry, behaviour)
Exemplo n.º 15
0
class BrushingModel(QObject):
    brushSizeChanged     = pyqtSignal(int)
    brushColorChanged    = pyqtSignal(QColor)
    brushStrokeAvailable = pyqtSignal(QPointF, object)
    drawnNumberChanged   = pyqtSignal(int)

    minBrushSize       = 1
    maxBrushSize       = 61
    defaultBrushSize   = 3
    defaultDrawnNumber = 1
    defaultColor       = Qt.white
    erasingColor       = Qt.black
    erasingNumber      = 100

    def __init__(self, parent=None):
        QObject.__init__(self, parent=parent)
        self.sliceRect = None
        self.bb    = QRect() #bounding box enclosing the drawing
        self.brushSize = self.defaultBrushSize
        self.drawColor = self.defaultColor
        self._temp_color = None
        self._temp_number = None
        self.drawnNumber = self.defaultDrawnNumber

        self.pos = None
        self.erasing = False
        self._hasMoved = False

        self.drawOnto = None

        #an empty scene, where we add all drawn line segments
        #a QGraphicsLineItem, and which we can use to then
        #render to an image
        self.scene = QGraphicsScene()

    def toggleErase(self):
        self.erasing = not(self.erasing)
        if self.erasing:
            self.setErasing()
        else:
            self.disableErasing()

    def setErasing(self):
        self.erasing = True
        self._temp_color = self.drawColor
        self._temp_number = self.drawnNumber
        self.setBrushColor(self.erasingColor)
        self.brushColorChanged.emit(self.erasingColor)
        self.setDrawnNumber(self.erasingNumber)

    def disableErasing(self):
        self.erasing = False
        self.setBrushColor(self._temp_color)
        self.brushColorChanged.emit(self.drawColor)
        self.setDrawnNumber(self._temp_number)

    def setBrushSize(self, size):
        self.brushSize = size
        self.brushSizeChanged.emit(self.brushSize)

    def setDrawnNumber(self, num):
        self.drawnNumber = num
        self.drawnNumberChanged.emit(num)

    def getBrushSize(self):
        return self.brushSize

    def brushSmaller(self):
        b = self.brushSize
        if b > self.minBrushSize:
            self.setBrushSize(b-1)

    def brushBigger(self):
        b = self.brushSize
        if self.brushSize < self.maxBrushSize:
            self.setBrushSize(b+1)

    def setBrushColor(self, color):
        self.drawColor = color
        self.brushColorChanged.emit(self.drawColor)

    def beginDrawing(self, pos, sliceRect):
        '''

        pos -- QPointF-like
        '''
        self.sliceRect = sliceRect
        self.scene.clear()
        self.bb = QRect()
        self.pos = QPointF(pos.x(), pos.y())
        self._hasMoved = False

    def endDrawing(self, pos):
        has_moved = self._hasMoved # _hasMoved will change after calling moveTo
        if has_moved:
            self.moveTo(pos)
        else:
            assert(self.pos == pos)
            self.moveTo(QPointF(pos.x()+0.0001, pos.y()+0.0001)) # move a little

        # Qt seems to use strange rules for determining which pixels to set when rendering a brush stroke to a QImage.
        # We seem to get better results if we do the following:
        # 1) Slightly offset the source window because apparently there is a small shift in the data
        # 2) Render the scene to an image that is MUCH larger than the scene resolution (4x by 4x)
        # 3) Downsample each 4x4 patch from the large image back to a single pixel in the final image,
        #     applying some threshold to determine if the final pixel is on or off. 

        tempi = QImage(QSize(4*self.bb.width(), 4*self.bb.height()), QImage.Format_ARGB32_Premultiplied) #TODO: format
        tempi.fill(0)
        painter = QPainter(tempi)
        # Offset the source window.  At first I thought the right offset was 0.5, because 
        #  that would seem to make sure points are rounded to pixel CENTERS, but 
        #  experimentation indicates that 0.25 is slightly better for some reason...
        source_rect = QRectF( QPointF(self.bb.x()+0.25, self.bb.y()+0.25), 
                              QSizeF(self.bb.width(), self.bb.height()) )
        target_rect = QRectF( QPointF(0,0),
                             QSizeF(4*self.bb.width(), 4*self.bb.height()) )
        self.scene.render(painter, target=target_rect, source=source_rect)
        painter.end()

        # Now downsample: convert each 4x4 patch into a single pixel by summing and dividing
        ndarr = qimage2ndarray.rgb_view(tempi)[:,:,0].astype(int)
        ndarr = ndarr.reshape( (ndarr.shape[0],) + (ndarr.shape[1]//4,) + (4,) )
        ndarr = ndarr.sum(axis=-1)
        ndarr = ndarr.transpose()
        ndarr = ndarr.reshape( (ndarr.shape[0],) + (ndarr.shape[1]//4,) + (4,) )
        ndarr = ndarr.sum(axis=-1)
        ndarr = ndarr.transpose()
        ndarr //= 4*4

        downsample_threshold = (7./16)*255
        labels = numpy.where(ndarr>=downsample_threshold, numpy.uint8(self.drawnNumber), numpy.uint8(0))
        labels = labels.swapaxes(0,1)
        assert labels.shape[0] == self.bb.width()
        assert labels.shape[1] == self.bb.height()

        ##
        ## ensure that at least one pixel is label when the brush size is 1
        ##
        ## this happens when the user just clicked without moving
        ## in that case the lineitem will be so tiny, that it won't be rendered
        ## into a single pixel by the code above
        if not has_moved and self.brushSize <= 1 and numpy.count_nonzero(labels) == 0:
            labels[labels.shape[0]//2, labels.shape[1]//2] = self.drawnNumber

        self.brushStrokeAvailable.emit(QPointF(self.bb.x(), self.bb.y()), labels)

    def dumpDraw(self, pos):
        res = self.endDrawing(pos)
        self.beginDrawing(pos, self.sliceRect)
        return res

    def moveTo(self, pos):
        #data coordinates
        oldX, oldY = self.pos.x(), self.pos.y()
        x,y = pos.x(), pos.y()

        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(QPen( QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.scene.addItem(line)
        self._hasMoved = True

        #update bounding Box
        if not self.bb.isValid():
            self.bb = QRect(QPoint(oldX,oldY), QSize(1,1))
        #grow bounding box
        self.bb.setLeft(  min(self.bb.left(),   max(0,                   x-self.brushSize//2-1) ) )
        self.bb.setRight( max(self.bb.right(),  min(self.sliceRect[0]-1, x+self.brushSize//2+1) ) )
        self.bb.setTop(   min(self.bb.top(),    max(0,                   y-self.brushSize//2-1) ) )
        self.bb.setBottom(max(self.bb.bottom(), min(self.sliceRect[1]-1, y+self.brushSize//2+1) ) )

        #update/move position
        self.pos = pos
Exemplo n.º 16
0
class SelectByRect(QgsMapTool):
    def __init__(self, canvas):
        self.mCanvas = canvas
        QgsMapTool.__init__(self, canvas)
        self.mCursor = Qt.ArrowCursor
        self.mRubberBand = None
        self.mDragging = False
        self.mSelectRect = QRect()

#     QgsRubberBand* mRubberBand;
#     def reset(self):
#         self.startPoint = None
#         self.endPoint = None
#         self.isDrawing = False
#         SelectByRect.RubberRect.reset(QGis.Polygon)
#         self.layer = self.canvas.currentLayer()

    def canvasPressEvent(self, e):
        self.mSelectRect.setRect(0, 0, 0, 0)
        self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon)
#         self.reset()
#         self.startPoint = self.toMapCoordinates(e.pos())
#         self.isDrawing = True

    def canvasMoveEvent(self, e):
        if (e.buttons() != Qt.LeftButton):
            return
        if (not self.mDragging):
            self.mDragging = True
            self.mSelectRect.setTopLeft(e.pos())
        self.mSelectRect.setBottomRight(e.pos())
        QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect,
                                            self.mRubberBand)
#         if not self.isDrawing:
#             return
#         SelectByRect.RubberRect.reset(QGis.Polygon)
#         self.endPoint = self.toMapCoordinates(e.pos())
#         self.rect = QgsRectangle(self.startPoint, self.endPoint)
#         SelectByRect.RubberRect.addGeometry(QgsGeometry.fromRect(self.rect), None)
#         SelectByRect.RubberRect.show()

    def canvasReleaseEvent(self, e):
        selectedFeatures = None
        vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer(self.mCanvas)
        if (vlayer == None):
            if (self.mRubberBand != None):
                self.mRubberBand.reset(QGis.Polygon)
                del self.mRubberBand
                self.mRubberBand = None
                self.mDragging = False
            return

        if (not self.mDragging):
            QgsMapToolSelectUtils.expandSelectRectangle(
                self.mSelectRect, vlayer, e.pos())
        else:
            if (self.mSelectRect.width() == 1):
                self.mSelectRect.setLeft(self.mSelectRect.left() + 1)
            if (self.mSelectRect.height() == 1):
                self.mSelectRect.setBottom(self.mSelectRect.bottom() + 1)

        if (self.mRubberBand != None):
            QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect,
                                                self.mRubberBand)
            selectGeom = self.mRubberBand.asGeometry()
            # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, selectGeom, e )
            selectedFeatures = QgsMapToolSelectUtils.setSelectFeatures1(
                self.mCanvas, selectGeom, e)
            del selectGeom

            self.mRubberBand.reset(QGis.Polygon)
            del self.mRubberBand
            self.mRubberBand = None
        self.mDragging = False
        self.emit(SIGNAL("getSelectedFeatures"), selectedFeatures)
Exemplo n.º 17
0
class SelectedFeatureByRectTasDraw(QgsMapTool):
    def __init__(self, canvas, distance):
        self.mCanvas = canvas
        QgsMapTool.__init__(self, canvas)
        self.mCursor = Qt.ArrowCursor
        self.mRubberBand = None
        self.mDragging = False
        self.mSelectRect = QRect()
        self.rubberBandLine = None
        self.distance = distance
        self.mSnapper = QgsMapCanvasSnapper(canvas)
#     QgsRubberBand* mRubberBand;
#     def reset(self):
#         self.startPoint = None
#         self.endPoint = None
#         self.isDrawing = False
#         SelectByRect.RubberRect.reset(QGis.Polygon)
#         self.layer = self.canvas.currentLayer()

    def canvasPressEvent(self, e):
        self.mSelectRect.setRect(0, 0, 0, 0)
        self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon)
        self.startPoint, self.pointID, self.layer = self.snapPoint(e.pos())
#         self.reset()
#         self.startPoint = self.toMapCoordinates(e.pos())
#         self.isDrawing = True

    def canvasMoveEvent(self, e):
        if (e.buttons() != Qt.LeftButton):
            return
        if (not self.mDragging):
            self.mDragging = True
            self.mSelectRect.setTopLeft(e.pos())
        self.mSelectRect.setBottomRight(e.pos())
        QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect,
                                            self.mRubberBand)
#         if not self.isDrawing:
#             return
#         SelectByRect.RubberRect.reset(QGis.Polygon)
#         self.endPoint = self.toMapCoordinates(e.pos())
#         self.rect = QgsRectangle(self.startPoint, self.endPoint)
#         SelectByRect.RubberRect.addGeometry(QgsGeometry.fromRect(self.rect), None)
#         SelectByRect.RubberRect.show()

    def canvasReleaseEvent(self, e):
        self.endPoint, self.pointID, self.layer = self.snapPoint(e.pos())
        if len(define._newGeometryList) > 0:
            geom = define._newGeometryList[0]
            if geom.intersects(self.mRubberBand.asGeometry()):
                pointArray = geom.asPolyline()
                # pointArray1 = QgisHelper.offsetCurve(pointArray, 1200)
                if self.rubberBandLine != None:
                    self.rubberBandLine.reset(QGis.Line)
                    del self.rubberBandLine
                    self.rubberBandLine = None
                self.rubberBandLine = QgsRubberBand(self.mCanvas, QGis.Line)
                self.rubberBandLine.setColor(Qt.blue)
                bearing = 0.0
                if self.startPoint.y() >= self.endPoint.y() and (
                        math.fabs(self.startPoint.x() - self.endPoint.x()) <
                        math.fabs(self.startPoint.y() - self.endPoint.y())):
                    bearing = Unit.ConvertDegToRad(180)
                elif self.startPoint.x() >= self.endPoint.x() and (
                        math.fabs(self.startPoint.x() - self.endPoint.x()) >
                        math.fabs(self.startPoint.y() - self.endPoint.y())):
                    bearing = Unit.ConvertDegToRad(270)
                elif self.startPoint.x() < self.endPoint.x() and (
                        math.fabs(self.startPoint.x() - self.endPoint.x()) >
                        math.fabs(self.startPoint.y() - self.endPoint.y())):
                    bearing = Unit.ConvertDegToRad(90)
                else:
                    bearing = 0.0

                for point in pointArray:

                    pt = MathHelper.distanceBearingPoint(
                        Point3D(point.x(), point.y()), bearing, self.distance
                    )  # MathHelper.getBearing(self.startPoint, self.endPoint), self.distance)
                    self.rubberBandLine.addPoint(pt)
                gg = self.rubberBandLine.asGeometry()
                g = gg.asPolyline()
                # self.rubberBandLine.show()
                if (self.mRubberBand != None):
                    self.mRubberBand.reset(QGis.Polygon)
                    del self.mRubberBand
                    self.mRubberBand = None
                    self.mDragging = False
                    self.emit(
                        SIGNAL("resultSelectedFeatureByRectTasDraw"), gg,
                        self.distance, bearing
                    )  # MathHelper.getBearing(self.startPoint, self.endPoint))
                return
        vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer(self.mCanvas)
        if (vlayer == None):
            if (self.mRubberBand != None):
                self.mRubberBand.reset(QGis.Polygon)
                del self.mRubberBand
                self.mRubberBand = None
                self.mDragging = False
            return

        if (not self.mDragging):
            QgsMapToolSelectUtils.expandSelectRectangle(
                self.mSelectRect, vlayer, e.pos())
        else:
            if (self.mSelectRect.width() == 1):
                self.mSelectRect.setLeft(self.mSelectRect.left() + 1)
            if (self.mSelectRect.height() == 1):
                self.mSelectRect.setBottom(self.mSelectRect.bottom() + 1)

        if (self.mRubberBand != None):
            QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect,
                                                self.mRubberBand)
            selectGeom = self.mRubberBand.asGeometry()

            # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, selectGeom, e )
            selectedFeatures = QgsMapToolSelectUtils.setSelectFeaturesOrRubberband_Tas_1(
                self.mCanvas, selectGeom, e)
            if len(selectedFeatures) > 0:
                geom = selectedFeatures[0].geometry()
                if geom.intersects(self.mRubberBand.asGeometry()):
                    pointArray = geom.asPolyline()
                    # pointArray1 = QgisHelper.offsetCurve(pointArray, 1200)
                    if self.rubberBandLine != None:
                        self.rubberBandLine.reset(QGis.Line)
                        del self.rubberBandLine
                        self.rubberBandLine = None
                    self.rubberBandLine = QgsRubberBand(
                        self.mCanvas, QGis.Line)
                    self.rubberBandLine.setColor(Qt.blue)
                    bearing = 0.0
                    gg = None
                    if self.startPoint.y() >= self.endPoint.y() and (
                            math.fabs(self.startPoint.x() - self.endPoint.x())
                            < math.fabs(self.startPoint.y() -
                                        self.endPoint.y())):
                        bearing = Unit.ConvertDegToRad(180)
                        gg = self.newCreateLine(geom, self.distance, 180)
                    elif self.startPoint.x() >= self.endPoint.x() and (
                            math.fabs(self.startPoint.x() - self.endPoint.x())
                            > math.fabs(self.startPoint.y() -
                                        self.endPoint.y())):
                        bearing = Unit.ConvertDegToRad(270)
                        gg = self.newCreateLine(geom, self.distance, 270)
                    elif self.startPoint.x() < self.endPoint.x() and (
                            math.fabs(self.startPoint.x() - self.endPoint.x())
                            > math.fabs(self.startPoint.y() -
                                        self.endPoint.y())):
                        bearing = Unit.ConvertDegToRad(90)
                        gg = self.newCreateLine(geom, self.distance, 90)
                    else:
                        bearing = 0.0
                        gg = self.newCreateLine(geom, self.distance, 0)
                    for point in pointArray:
                        pt = MathHelper.distanceBearingPoint(
                            Point3D(point.x(),
                                    point.y()), bearing, self.distance
                        )  #MathHelper.getBearing(self.startPoint, self.endPoint), self.distance)

                        self.rubberBandLine.addPoint(pt)
                    # gg= self.newCreateLine(geom, -self.distance, 0)

                    self.emit(
                        SIGNAL("resultSelectedFeatureByRectTasDraw"), gg,
                        self.distance, bearing
                    )  #MathHelper.getBearing(self.startPoint, self.endPoint))
                    self.rubberBandLine.reset(QGis.Line)
            del selectGeom

            self.mRubberBand.reset(QGis.Polygon)
            del self.mRubberBand
            self.mRubberBand = None
        self.mDragging = False


#         self.canvasMoveEvent(e)
#         if self.layer != None:
#             self.layer.removeSelection()
#             if self.layer.crs().mapUnits() != self.canvas.mapUnits():
#                 if self.layer.crs().mapUnits == QGis.Meters:
#                     lstPoint = QgisHelper.Degree2MeterList([self.startPoint, self.endPoint])
#                 else:
#                     lstPoint = QgisHelper.Meter2DegreeList([self.startPoint, self.endPoint])
#                 rect = QgsRectangle(lstPoint[0], lstPoint[1])
#                 self.layer.select(rect, True)
#             else:
#                 self.layer.select(self.rect, False)
#         else:
#             QMessageBox.warning(None, "Information", "Please select layer!")
#         self.reset()

    def snapPoint(self, p, bNone=False):
        if define._snapping == False:
            return (
                define._canvas.getCoordinateTransform().toMapCoordinates(p),
                None, None)
        snappingResults = self.mSnapper.snapToBackgroundLayers(p)
        if (snappingResults[0] != 0 or len(snappingResults[1]) < 1):

            if bNone:
                return (None, None, None)
            else:
                return (define._canvas.getCoordinateTransform().
                        toMapCoordinates(p), None, None)
        else:
            return (snappingResults[1][0].snappedVertex,
                    snappingResults[1][0].snappedAtGeometry,
                    snappingResults[1][0].layer)

    def newCreateLine(self, geom, dist, angle):
        if define._units != QGis.Meters:
            dist = define._qgsDistanceArea.convertMeasurement(
                dist, QGis.Meters, QGis.Degrees, False)[0]
        g = geom.offsetCurve(dist, 0, 2, 2)
        pointArrayOld = geom.asPolyline()
        pointArrayNew = g.asPolyline()
        if MathHelper.calcDistance(
                pointArrayNew[0], pointArrayOld[0]) > MathHelper.calcDistance(
                    pointArrayNew[0], pointArrayOld[len(pointArrayOld) - 1]):
            array = []
            i = len(pointArrayNew) - 1
            while i >= 0:
                array.append(pointArrayNew[i])
                i -= 1
            pointArrayNew = array
        if angle == 0:
            if pointArrayNew[0].y() < pointArrayOld[0].y():
                g = geom.offsetCurve(-dist, 0, 2, 2)
                pointArrayNew = g.asPolyline()
        elif angle == 90:
            if pointArrayNew[0].x() < pointArrayOld[0].x():
                g = geom.offsetCurve(-dist, 0, 2, 2)
                pointArrayNew = g.asPolyline()
        elif angle == 180:
            if pointArrayNew[0].y() > pointArrayOld[0].y():
                g = geom.offsetCurve(-dist, 0, 2, 2)
                pointArrayNew = g.asPolyline()
        elif angle == 270:
            if pointArrayNew[0].x() > pointArrayOld[0].x():
                g = geom.offsetCurve(-dist, 0, 2, 2)
                pointArrayNew = g.asPolyline()
        if MathHelper.calcDistance(
                pointArrayNew[0], pointArrayOld[0]) > MathHelper.calcDistance(
                    pointArrayNew[0], pointArrayOld[len(pointArrayOld) - 1]):
            array = []
            i = len(pointArrayNew) - 1
            while i >= 0:
                array.append(pointArrayNew[i])
                i -= 1
            pointArrayNew = array
        i = 0

        while i < len(pointArrayNew) - 1:
            if i == 0:
                i += 1
                continue
            line = None
            if define._units == QGis.Meters:
                if angle == 0:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[0],
                        QgsPoint(pointArrayOld[0].x(), 100000000)
                    ])
                elif angle == 90:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[0],
                        QgsPoint(100000000, pointArrayOld[0].y())
                    ])
                elif angle == 180:
                    line = QgsGeometry.fromPolyline(
                        [pointArrayOld[0],
                         QgsPoint(pointArrayOld[0].x(), 0)])
                elif angle == 270:
                    line = QgsGeometry.fromPolyline(
                        [pointArrayOld[0],
                         QgsPoint(0, pointArrayOld[0].y())])
            else:
                if angle == 0:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[0],
                        QgsPoint(pointArrayOld[0].x(),
                                 pointArrayOld[0].y() + 0.1)
                    ])
                elif angle == 90:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[0],
                        QgsPoint(pointArrayOld[0].x() + 0.1,
                                 pointArrayOld[0].y())
                    ])
                elif angle == 180:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[0],
                        QgsPoint(pointArrayOld[0].x(),
                                 pointArrayOld[0].y() - 0.1)
                    ])
                elif angle == 270:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[0],
                        QgsPoint(pointArrayOld[0].x() - 0.1,
                                 pointArrayOld[0].y())
                    ])
            lineNew = QgsGeometry.fromPolyline([
                MathHelper.distanceBearingPoint(
                    Point3D(pointArrayNew[i].x(), pointArrayNew[i].y()),
                    MathHelper.getBearing(pointArrayNew[i],
                                          pointArrayNew[i - 1]), 100000),
                pointArrayNew[i]
            ])

            if line.intersects(lineNew):
                pointGeom = line.intersection(lineNew)
                intersectPoint = pointGeom.asPoint()
                pointArrayNew.pop(i - 1)
                pointArrayNew.insert(i - 1, intersectPoint)
                break
            else:
                pointArrayNew.pop(i - 1)
                continue
            i += 1
        i = len(pointArrayNew) - 1
        while i > 1:
            line = None
            if define._units == QGis.Meters:
                if angle == 0:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(),
                                 100000000)
                    ])
                elif angle == 90:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(100000000,
                                 pointArrayOld[len(pointArrayOld) - 1].y())
                    ])
                elif angle == 180:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 0)
                    ])
                elif angle == 270:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(0, pointArrayOld[len(pointArrayOld) - 1].y())
                    ])
            else:
                if angle == 0:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(
                            pointArrayOld[len(pointArrayOld) - 1].x(),
                            pointArrayOld[len(pointArrayOld) - 1].y() + 0.1)
                    ])
                elif angle == 90:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(
                            pointArrayOld[len(pointArrayOld) - 1].x() + 0.1,
                            pointArrayOld[len(pointArrayOld) - 1].y())
                    ])
                elif angle == 180:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(
                            pointArrayOld[len(pointArrayOld) - 1].x(),
                            pointArrayOld[len(pointArrayOld) - 1].y() - 0.1)
                    ])
                elif angle == 270:
                    line = QgsGeometry.fromPolyline([
                        pointArrayOld[len(pointArrayOld) - 1],
                        QgsPoint(
                            pointArrayOld[len(pointArrayOld) - 1].x() - 0.1,
                            pointArrayOld[len(pointArrayOld) - 1].y())
                    ])
            # line = QgsGeometry.fromPolyline([pointArrayOld[len(pointArrayOld) - 1], QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 100000000)])
            lineNew = QgsGeometry.fromPolyline([
                MathHelper.distanceBearingPoint(
                    Point3D(pointArrayNew[i].x(), pointArrayNew[i].y()),
                    MathHelper.getBearing(pointArrayNew[i - 1],
                                          pointArrayNew[i]), 100000),
                pointArrayNew[i - 1]
            ])
            if line.intersects(lineNew):
                pointGeom = line.intersection(lineNew)
                intersectPoint = pointGeom.asPoint()
                pointArrayNew.pop(i)
                pointArrayNew.insert(i, intersectPoint)
                break
            else:
                pointArrayNew.pop(i)
                i -= 1
                continue
            i -= 1
        return QgsGeometry.fromPolyline(pointArrayNew)
Exemplo n.º 18
0
class BrushingModel(QObject):
    brushSizeChanged = pyqtSignal(int)
    brushColorChanged = pyqtSignal(QColor)
    brushStrokeAvailable = pyqtSignal(QPointF, object)
    drawnNumberChanged = pyqtSignal(int)

    minBrushSize = 1
    maxBrushSize = 61
    defaultBrushSize = 3
    defaultDrawnNumber = 1
    defaultColor = Qt.white
    erasingColor = Qt.black
    erasingNumber = 100

    def __init__(self, parent=None):
        QObject.__init__(self, parent=parent)
        self.sliceRect = None
        self.bb = QRect()  #bounding box enclosing the drawing
        self.brushSize = self.defaultBrushSize
        self.drawColor = self.defaultColor
        self._temp_color = None
        self._temp_number = None
        self.drawnNumber = self.defaultDrawnNumber

        self.pos = None
        self.erasing = False
        self._hasMoved = False

        self.drawOnto = None

        #an empty scene, where we add all drawn line segments
        #a QGraphicsLineItem, and which we can use to then
        #render to an image
        self.scene = QGraphicsScene()

    def toggleErase(self):
        self.erasing = not (self.erasing)
        if self.erasing:
            self.setErasing()
        else:
            self.disableErasing()

    def setErasing(self):
        self.erasing = True
        self._temp_color = self.drawColor
        self._temp_number = self.drawnNumber
        self.setBrushColor(self.erasingColor)
        self.brushColorChanged.emit(self.erasingColor)
        self.setDrawnNumber(self.erasingNumber)

    def disableErasing(self):
        self.erasing = False
        self.setBrushColor(self._temp_color)
        self.brushColorChanged.emit(self.drawColor)
        self.setDrawnNumber(self._temp_number)

    def setBrushSize(self, size):
        self.brushSize = size
        self.brushSizeChanged.emit(self.brushSize)

    def setDrawnNumber(self, num):
        self.drawnNumber = num
        self.drawnNumberChanged.emit(num)

    def getBrushSize(self):
        return self.brushSize

    def brushSmaller(self):
        b = self.brushSize
        if b > self.minBrushSize:
            self.setBrushSize(b - 1)

    def brushBigger(self):
        b = self.brushSize
        if self.brushSize < self.maxBrushSize:
            self.setBrushSize(b + 1)

    def setBrushColor(self, color):
        self.drawColor = color
        self.brushColorChanged.emit(self.drawColor)

    def beginDrawing(self, pos, sliceRect):
        '''

        pos -- QPointF-like
        '''
        self.sliceRect = sliceRect
        self.scene.clear()
        self.bb = QRect()
        self.pos = QPointF(pos.x(), pos.y())
        self._hasMoved = False

    def endDrawing(self, pos):
        has_moved = self._hasMoved  # _hasMoved will change after calling moveTo
        if has_moved:
            self.moveTo(pos)
        else:
            assert (self.pos == pos)
            self.moveTo(QPointF(pos.x() + 0.0001,
                                pos.y() + 0.0001))  # move a little

        tempi = QImage(QSize(self.bb.width(), self.bb.height()),
                       QImage.Format_ARGB32_Premultiplied)  #TODO: format
        tempi.fill(0)
        painter = QPainter(tempi)
        self.scene.render(painter,
                          target=QRectF(),
                          source=QRectF(
                              QPointF(self.bb.x(), self.bb.y()),
                              QSizeF(self.bb.width(), self.bb.height())))
        painter.end()

        ndarr = qimage2ndarray.rgb_view(tempi)[:, :, 0]
        labels = numpy.where(ndarr > 0, numpy.uint8(self.drawnNumber),
                             numpy.uint8(0))
        labels = labels.swapaxes(0, 1)
        assert labels.shape[0] == self.bb.width()
        assert labels.shape[1] == self.bb.height()

        ##
        ## ensure that at least one pixel is label when the brush size is 1
        ##
        ## this happens when the user just clicked without moving
        ## in that case the lineitem will be so tiny, that it won't be rendered
        ## into a single pixel by the code above
        if not has_moved and self.brushSize <= 1 and numpy.count_nonzero(
                labels) == 0:
            labels[labels.shape[0] // 2,
                   labels.shape[1] // 2] = self.drawnNumber

        self.brushStrokeAvailable.emit(QPointF(self.bb.x(), self.bb.y()),
                                       labels)

    def dumpDraw(self, pos):
        res = self.endDrawing(pos)
        self.beginDrawing(pos, self.sliceRect)
        return res

    def moveTo(self, pos):
        #data coordinates
        oldX, oldY = self.pos.x(), self.pos.y()
        x, y = pos.x(), pos.y()

        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(
            QPen(QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))
        self.scene.addItem(line)
        self._hasMoved = True

        #update bounding Box
        if not self.bb.isValid():
            self.bb = QRect(QPoint(oldX, oldY), QSize(1, 1))
        #grow bounding box
        self.bb.setLeft(min(self.bb.left(), max(0,
                                                x - self.brushSize / 2 - 1)))
        self.bb.setRight(
            max(self.bb.right(),
                min(self.sliceRect[0] - 1, x + self.brushSize / 2 + 1)))
        self.bb.setTop(min(self.bb.top(), max(0, y - self.brushSize / 2 - 1)))
        self.bb.setBottom(
            max(self.bb.bottom(),
                min(self.sliceRect[1] - 1, y + self.brushSize / 2 + 1)))

        #update/move position
        self.pos = pos
class ObstacleAreaJigSelectArea(QgsMapTool):

    def __init__(self, canvas, areaType):
        self.mCanvas = canvas
        self.areaType = areaType
        QgsMapTool.__init__(self, canvas)
        self.mCursor = Qt.ArrowCursor
        self.mRubberBand = None
        self.mDragging = False
        self.mSelectRect = QRect()
        self.mRubberBandResult = None
        self.mSnapper = QgsMapCanvasSnapper(canvas)
        self.lineCount = 0
        self.resultGeomList = []
        self.geomList = []
        self.area = None
        self.isFinished = False
#     QgsRubberBand* mRubberBand;
#     def reset(self):
#         self.startPoint = None
#         self.endPoint = None
#         self.isDrawing = False
#         SelectByRect.RubberRect.reset(QGis.Polygon)
#         self.layer = self.canvas.currentLayer()

    def canvasPressEvent(self, e):
        QgisHelper.ClearRubberBandInCanvas(define._canvas)
        self.mSelectRect.setRect( 0, 0, 0, 0 )
        self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon )
        self.startPoint, self.pointID, self.layer= self.snapPoint(e.pos())

    def canvasMoveEvent(self, e):
        if self.areaType == ProtectionAreaType.Secondary:
            if self.lineCount == 0:
                define._messageLabel.setText("Select a line or arc representing the INNER edge of the secondary area.")
            elif self.lineCount == 1:
                define._messageLabel.setText("Select a line representing the OUTER edge of the secondary area.")
        elif self.areaType == ProtectionAreaType.Primary:
            define._messageLabel.setText("")
        elif self.areaType == ProtectionAreaType.PrimaryAndSecondary:
            if self.lineCount == 0:
                define._messageLabel.setText("Select a line or arc representing the INNER edge of the FIRST secondary area.")
            elif self.lineCount == 1:
                define._messageLabel.setText("Select a line representing the OUTER edge of the FIRST secondary area.")
            elif self.lineCount == 2:
                define._messageLabel.setText("Select a line or arc representing the INNER edge of the SECOND secondary area.")
            elif self.lineCount == 3:
                define._messageLabel.setText("Select a line representing the OUTER edge of the SECOND secondary area.")
        else:
            define._messageLabel.setText("")


        if ( e.buttons() != Qt.LeftButton ):
            return
        if ( not self.mDragging ):
            self.mDragging = True
            self.mSelectRect.setTopLeft( e.pos() )
        self.mSelectRect.setBottomRight( e.pos() )
        QgsMapToolSelectUtils.setRubberBand( self.mCanvas, self.mSelectRect,self.mRubberBand )

    def canvasReleaseEvent(self, e):
        self.endPoint, self.pointID, self.layer= self.snapPoint(e.pos())

        vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer( self.mCanvas )
        if ( vlayer == None ):
            if ( self.mRubberBand != None):
                self.mRubberBand.reset( QGis.Polygon )
                del self.mRubberBand
                self.mRubberBand = None
                self.mDragging = False
            return


        if (not self.mDragging ):
            QgsMapToolSelectUtils.expandSelectRectangle(self. mSelectRect, vlayer, e.pos() )
        else:
            if ( self.mSelectRect.width() == 1 ):
                self.mSelectRect.setLeft( self.mSelectRect.left() + 1 )
            if ( self.mSelectRect.height() == 1 ):
                self.mSelectRect.setBottom( self.mSelectRect.bottom() + 1 )

        if ( self.mRubberBand != None ):
            QgsMapToolSelectUtils.setRubberBand( self.mCanvas, self.mSelectRect, self.mRubberBand )
            selectGeom = self.mRubberBand.asGeometry()


            selectedFeatures = QgsMapToolSelectUtils.setSelectFeaturesOrRubberband_Tas_1( self.mCanvas, selectGeom, e )
            if len(selectedFeatures) > 0:
                self.lineCount += 1
                geom = selectedFeatures[0].geometry()
                resultArray = QgisHelper.findArcOrLineInLineGeometry(geom, selectGeom)
                # if resultArray != None:
                #     bulge = MathHelper.smethod_60(resultArray[0], resultArray[int(len(resultArray)/2)], resultArray[len(resultArray)-1])
                #     bulge1 = MathHelper.smethod_60(resultArray[len(resultArray)-1], resultArray[int(len(resultArray)/2)], resultArray[0])
                #     n = 0
                pointArray0 = geom.asPolyline()
                self.resultGeomList.append(resultArray)
                self.geomList.append(pointArray0)
                if self.lineCount == 2 and self.areaType != ProtectionAreaType.PrimaryAndSecondary and self.areaType != ProtectionAreaType.Complex:
                    self.area = self.makeArea(self.resultGeomList, self.areaType)
                    pointArray = self.getPointArray(self.resultGeomList).method_14_closed()
                    self.mRubberBandResult = None
                    self.mRubberBandResult = QgsRubberBand( self.mCanvas, QGis.Polygon )
                    self.mRubberBandResult.setFillColor(QColor(255, 255, 255, 100))
                    self.mRubberBandResult.setBorderColor(QColor(0, 0, 0))
                    for point in pointArray:
                        self.mRubberBandResult.addPoint(point)
                    self.mRubberBandResult.show()


                    self.emit(SIGNAL("outputResult"), self.area, self.mRubberBandResult)
                    self.lineCount = 0
                    self.resultGeomList = []
                    self.isFinished = True
                    # self.rubberBandLine.reset(QGis.Line)
                elif self.lineCount == 4 and self.areaType == ProtectionAreaType.PrimaryAndSecondary:
                    self.area = self.makeArea(self.resultGeomList, self.areaType)
                    pointArray = self.getPointArray([self.resultGeomList[1], self.resultGeomList[3]]).method_14_closed()
                    self.mRubberBandResult = None
                    self.mRubberBandResult = QgsRubberBand( self.mCanvas, QGis.Polygon )
                    self.mRubberBandResult.setFillColor(QColor(255, 255, 255, 100))
                    self.mRubberBandResult.setBorderColor(QColor(0, 0, 0))
                    for point in pointArray:
                        self.mRubberBandResult.addPoint(point)
                    self.mRubberBandResult.show()


                    self.emit(SIGNAL("outputResult"), self.area, self.mRubberBandResult)
                    self.lineCount = 0
                    self.resultGeomList = []
                # else:
                #     return
            del selectGeom

            self.mRubberBand.reset( QGis.Polygon )
            del self.mRubberBand
            self.mRubberBand = None
        self.mDragging = False
    def getPointArray(self, geomList):
        pointArrayInner = geomList[0]
        pointArray1Outer = geomList[1]

        innerStartPoint = pointArrayInner[0]
        innerEndPoint = pointArrayInner[1]
        innerBulge = pointArrayInner[2]
        outerStartPoint = pointArray1Outer[0]
        outerEndPoint = pointArray1Outer[1]
        outerBulge = pointArray1Outer[2]

        line0 = QgsGeometry.fromPolyline([innerStartPoint, outerStartPoint])
        line1 = QgsGeometry.fromPolyline([innerEndPoint, outerEndPoint])

        # for i in range(1, len(pointArray0)):

        if line0.intersects(line1):
            tempPoint = outerStartPoint
            outerStartPoint = outerEndPoint
            outerEndPoint = tempPoint
            outerBulge = -outerBulge

        polylineArea = PolylineArea()
        polylineArea.Add(PolylineAreaPoint(innerStartPoint, innerBulge))
        polylineArea.Add(PolylineAreaPoint(innerEndPoint))
        polylineArea.Add(PolylineAreaPoint(outerEndPoint, -outerBulge))
        polylineArea.Add(PolylineAreaPoint(outerStartPoint))
        return polylineArea
    def makeArea(self, geomList, areaType):
        if areaType == ProtectionAreaType.Primary or areaType == ProtectionAreaType.Secondary:
            return self.makePrimaryAreaOrSecondaryArea(geomList, areaType)
        elif areaType == ProtectionAreaType.PrimaryAndSecondary:
            pointArray0 = geomList[0]
            pointArray1 = geomList[1]
            pointArray2 = geomList[2]
            pointArray3 = geomList[3]
            primaryArea = self.makePrimaryAreaOrSecondaryArea([pointArray0, pointArray2], ProtectionAreaType.Primary)
            secondaryArea1 = self.makePrimaryAreaOrSecondaryArea([pointArray0, pointArray1], ProtectionAreaType.Secondary)
            secondaryArea2 = self.makePrimaryAreaOrSecondaryArea([pointArray2, pointArray3], ProtectionAreaType.Secondary)
            return PrimarySecondaryObstacleArea(primaryArea, secondaryArea1, secondaryArea2)
            # if len(geomList[0]) == 2 and len(geomList[1]) == 2 and len(geomList[2]) == 2 and len(geomList[3]) == 2:
            #     for i in range(1, len(geomList)):
            #         pointArray0 = geomList[0]
            #         pointArray1 = geomList[i]
            #         line0 = QgsGeometry.fromPolyline([pointArray0[0], pointArray1[0]])
            #         line1 = QgsGeometry.fromPolyline([pointArray0[len(pointArray0) - 1], pointArray1[len(pointArray1) - 1]])
            #         if line0.intersects(line1):
            #             pointArray1.reverse()
            #     pointArray0 = geomList[0]
            #     pointArray1 = geomList[1]
            #     pointArray2 = geomList[2]
            #     pointArray3 = geomList[3]
            #     area = PrimarySecondaryObstacleArea()
            #     area.set_areas(pointArray0, pointArray1, pointArray2, pointArray3)
            #     return area
            # return None

        return None
    def makePrimaryAreaOrSecondaryArea(self, geomList, areaType):
        pointArrayInner = geomList[0]
        pointArray1Outer = geomList[1]

        innerStartPoint = pointArrayInner[0]
        innerEndPoint = pointArrayInner[1]
        innerBulge = pointArrayInner[2]
        outerStartPoint = pointArray1Outer[0]
        outerEndPoint = pointArray1Outer[1]
        outerBulge = pointArray1Outer[2]

        line0 = QgsGeometry.fromPolyline([innerStartPoint, outerStartPoint])
        line1 = QgsGeometry.fromPolyline([innerEndPoint, outerEndPoint])

        # for i in range(1, len(pointArray0)):

        if line0.intersects(line1):
            tempPoint = Point3D(outerStartPoint.get_X(), outerStartPoint.get_Y())
            outerStartPoint = Point3D(outerEndPoint.get_X(), outerEndPoint.get_Y())
            outerEndPoint = Point3D(tempPoint.get_X(), tempPoint.get_Y())
            outerBulge = -outerBulge
        if areaType == ProtectionAreaType.Primary:
            polylineArea = PolylineArea()
            polylineArea.Add(PolylineAreaPoint(innerStartPoint, innerBulge))
            polylineArea.Add(PolylineAreaPoint(innerEndPoint))
            polylineArea.Add(PolylineAreaPoint(outerEndPoint, -outerBulge))
            polylineArea.Add(PolylineAreaPoint(outerStartPoint))
            return PrimaryObstacleArea(polylineArea)
        elif areaType == ProtectionAreaType.Secondary:
            if innerBulge == 0 and outerBulge == 0:
                return SecondaryObstacleArea(innerStartPoint, innerEndPoint, outerStartPoint, outerEndPoint, MathHelper.getBearing(innerStartPoint, innerEndPoint))
            elif innerBulge != 0 and outerBulge != 0:
                if round(innerBulge, 1) != round(outerBulge, 1):
                    return None
                innerCenterPoint = MathHelper.smethod_71(innerStartPoint, innerEndPoint, innerBulge)
                outerCenterPoint = MathHelper.smethod_71(outerStartPoint, outerEndPoint, outerBulge)

                innerRadius = MathHelper.calcDistance(innerCenterPoint, innerStartPoint);
                outerRadius = MathHelper.calcDistance(outerCenterPoint, outerStartPoint);

                bearing = (MathHelper.getBearing(innerCenterPoint, innerStartPoint) + MathHelper.getBearing(innerCenterPoint, innerEndPoint)) / 2
                innerMiddlePoint = MathHelper.distanceBearingPoint(innerCenterPoint, bearing, innerRadius)
                if round(MathHelper.smethod_60(innerStartPoint, innerMiddlePoint, innerEndPoint), 4) != round(outerBulge, 4):
                    bearing += 3.14159265358979
                    innerMiddlePoint = MathHelper.distanceBearingPoint(innerCenterPoint, bearing, innerRadius)

                bearing = (MathHelper.getBearing(outerCenterPoint, outerStartPoint) + MathHelper.getBearing(outerCenterPoint, outerEndPoint)) / 2
                outerMiddlePoint = MathHelper.distanceBearingPoint(outerCenterPoint, bearing, outerRadius)
                if round(MathHelper.smethod_60(outerStartPoint, outerMiddlePoint, outerEndPoint), 4) != round(outerBulge, 4):
                    bearing += 3.14159265358979
                    outerMiddlePoint = MathHelper.distanceBearingPoint(outerCenterPoint, bearing, outerRadius)
                return SecondaryObstacleArea(innerStartPoint, innerMiddlePoint, innerEndPoint, outerStartPoint, None, outerMiddlePoint, outerEndPoint, innerBulge, innerBulge)
            return None
    def snapPoint(self, p, bNone = False):
        if define._snapping == False:
            return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None)
        snappingResults = self.mSnapper.snapToBackgroundLayers( p )
        if ( snappingResults[0] != 0 or len(snappingResults[1]) < 1 ):

            if bNone:
                return (None, None, None)
            else:
                return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None)
        else:
            return (snappingResults[1][0].snappedVertex, snappingResults[1][0].snappedAtGeometry, snappingResults[1][0].layer)
Exemplo n.º 20
0
class BrushingModel(QObject):
    brushSizeChanged     = pyqtSignal(int)
    brushColorChanged    = pyqtSignal(QColor)
    brushStrokeAvailable = pyqtSignal(QPointF, object)
    drawnNumberChanged   = pyqtSignal(int)

    minBrushSize       = 1
    maxBrushSize       = 61
    defaultBrushSize   = 3
    defaultDrawnNumber = 1
    defaultColor       = Qt.white
    erasingColor       = Qt.black
    erasingNumber      = 100

    def __init__(self, parent=None):
        QObject.__init__(self, parent=parent)
        self.sliceRect = None
        self.bb    = QRect() #bounding box enclosing the drawing
        self.brushSize = self.defaultBrushSize
        self.drawColor = self.defaultColor
        self._temp_color = None
        self._temp_number = None
        self.drawnNumber = self.defaultDrawnNumber

        self.pos = None
        self.erasing = False
        self._hasMoved = False

        self.drawOnto = None

        #an empty scene, where we add all drawn line segments
        #a QGraphicsLineItem, and which we can use to then
        #render to an image
        self.scene = QGraphicsScene()

    def toggleErase(self):
        self.erasing = not(self.erasing)
        if self.erasing:
            self.setErasing()
        else:
            self.disableErasing()

    def setErasing(self):
        self.erasing = True
        self._temp_color = self.drawColor
        self._temp_number = self.drawnNumber
        self.setBrushColor(self.erasingColor)
        self.brushColorChanged.emit(self.erasingColor)
        self.setDrawnNumber(self.erasingNumber)

    def disableErasing(self):
        self.erasing = False
        self.setBrushColor(self._temp_color)
        self.brushColorChanged.emit(self.drawColor)
        self.setDrawnNumber(self._temp_number)

    def setBrushSize(self, size):
        self.brushSize = size
        self.brushSizeChanged.emit(self.brushSize)

    def setDrawnNumber(self, num):
        self.drawnNumber = num
        self.drawnNumberChanged.emit(num)

    def getBrushSize(self):
        return self.brushSize

    def brushSmaller(self):
        b = self.brushSize
        if b > self.minBrushSize:
            self.setBrushSize(b-1)

    def brushBigger(self):
        b = self.brushSize
        if self.brushSize < self.maxBrushSize:
            self.setBrushSize(b+1)

    def setBrushColor(self, color):
        self.drawColor = color
        self.brushColorChanged.emit(self.drawColor)

    def beginDrawing(self, pos, sliceRect):
        '''

        pos -- QPointF-like
        '''
        self.sliceRect = sliceRect
        self.scene.clear()
        self.bb = QRect()
        self.pos = QPointF(pos.x(), pos.y())
        self._hasMoved = False

    def endDrawing(self, pos):
        has_moved = self._hasMoved # _hasMoved will change after calling moveTo
        if has_moved:
            self.moveTo(pos)
        else:
            assert(self.pos == pos)
            self.moveTo(QPointF(pos.x()+0.0001, pos.y()+0.0001)) # move a little

        tempi = QImage(QSize(self.bb.width(), self.bb.height()), QImage.Format_ARGB32_Premultiplied) #TODO: format
        tempi.fill(0)
        painter = QPainter(tempi)
        self.scene.render(painter, target=QRectF(), source=QRectF(QPointF(self.bb.x(), self.bb.y()), QSizeF(self.bb.width(), self.bb.height())))
        painter.end()

        ndarr = qimage2ndarray.rgb_view(tempi)[:,:,0]
        labels = numpy.where(ndarr>0,numpy.uint8(self.drawnNumber),numpy.uint8(0))
        labels = labels.swapaxes(0,1)
        assert labels.shape[0] == self.bb.width()
        assert labels.shape[1] == self.bb.height()

        ##
        ## ensure that at least one pixel is label when the brush size is 1
        ##
        ## this happens when the user just clicked without moving
        ## in that case the lineitem will be so tiny, that it won't be rendered
        ## into a single pixel by the code above
        if not has_moved and self.brushSize <= 1 and numpy.count_nonzero(labels) == 0:
            labels[labels.shape[0]//2, labels.shape[1]//2] = self.drawnNumber

        self.brushStrokeAvailable.emit(QPointF(self.bb.x(), self.bb.y()), labels)

    def dumpDraw(self, pos):
        res = self.endDrawing(pos)
        self.beginDrawing(pos, self.sliceRect)
        return res

    def moveTo(self, pos):
        #data coordinates
        oldX, oldY = self.pos.x(), self.pos.y()
        x,y = pos.x(), pos.y()

        line = QGraphicsLineItem(oldX, oldY, x, y)
        line.setPen(QPen( QBrush(Qt.white), self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.scene.addItem(line)
        self._hasMoved = True

        #update bounding Box
        if not self.bb.isValid():
            self.bb = QRect(QPoint(oldX,oldY), QSize(1,1))
        #grow bounding box
        self.bb.setLeft(  min(self.bb.left(),   max(0,                   x-self.brushSize/2-1) ) )
        self.bb.setRight( max(self.bb.right(),  min(self.sliceRect[0]-1, x+self.brushSize/2+1) ) )
        self.bb.setTop(   min(self.bb.top(),    max(0,                   y-self.brushSize/2-1) ) )
        self.bb.setBottom(max(self.bb.bottom(), min(self.sliceRect[1]-1, y+self.brushSize/2+1) ) )

        #update/move position
        self.pos = pos
Exemplo n.º 21
0
    def __paintEventNoStyle(self):
        p = QPainter(self)
        opt = QStyleOptionToolButton()
        self.initStyleOption(opt)

        fm = QFontMetrics(opt.font)
        palette = opt.palette

        # highlight brush is used as the background for the icon and background
        # when the tab is expanded and as mouse hover color (lighter).
        brush_highlight = palette.highlight()
        if opt.state & QStyle.State_Sunken:
            # State 'down' pressed during a mouse press (slightly darker).
            background_brush = brush_darker(brush_highlight, 110)
        elif opt.state & QStyle.State_MouseOver:
            background_brush = brush_darker(brush_highlight, 95)
        elif opt.state & QStyle.State_On:
            background_brush = brush_highlight
        else:
            # The default button brush.
            background_brush = palette.button()

        rect = opt.rect
        icon = opt.icon
        icon_size = opt.iconSize

        # TODO: add shift for pressed as set by the style (PM_ButtonShift...)

        pm = None
        if not icon.isNull():
            if opt.state & QStyle.State_Enabled:
                mode = QIcon.Normal
            else:
                mode = QIcon.Disabled

            pm = opt.icon.pixmap(
                    rect.size().boundedTo(icon_size), mode,
                    QIcon.On if opt.state & QStyle.State_On else QIcon.Off)

        icon_area_rect = QRect(rect)
        icon_area_rect.setRight(int(icon_area_rect.height() * 1.26))

        text_rect = QRect(rect)
        text_rect.setLeft(icon_area_rect.right() + 10)

        # Background  (TODO: Should the tab button have native
        # toolbutton shape, drawn using PE_PanelButtonTool or even
        # QToolBox tab shape)

        # Default outline pen
        pen = QPen(palette.color(QPalette.Mid))

        p.save()
        p.setPen(Qt.NoPen)
        p.setBrush(QBrush(background_brush))
        p.drawRect(rect)

        # Draw the background behind the icon if the background_brush
        # is different.
        if not opt.state & QStyle.State_On:
            p.setBrush(brush_highlight)
            p.drawRect(icon_area_rect)
            # Line between the icon and text
            p.setPen(pen)
            p.drawLine(icon_area_rect.topRight(),
                       icon_area_rect.bottomRight())

        if opt.state & QStyle.State_HasFocus:
            # Set the focus frame pen and draw the border
            pen = QPen(QColor(FOCUS_OUTLINE_COLOR))
            p.setPen(pen)
            p.setBrush(Qt.NoBrush)
            # Adjust for pen
            rect = rect.adjusted(0, 0, -1, -1)
            p.drawRect(rect)

        else:
            p.setPen(pen)
            # Draw the top/bottom border
            if self.position == QStyleOptionToolBoxV2.OnlyOneTab or \
                    self.position == QStyleOptionToolBoxV2.Beginning or \
                    self.selected & \
                        QStyleOptionToolBoxV2.PreviousIsSelected:

                p.drawLine(rect.topLeft(), rect.topRight())

            p.drawLine(rect.bottomLeft(), rect.bottomRight())

        p.restore()

        p.save()
        text = fm.elidedText(opt.text, Qt.ElideRight, text_rect.width())
        p.setPen(QPen(palette.color(QPalette.ButtonText)))
        p.setFont(opt.font)

        p.drawText(text_rect,
                   int(Qt.AlignVCenter | Qt.AlignLeft) | \
                   int(Qt.TextSingleLine),
                   text)
        if pm:
            pm_rect = QRect(QPoint(0, 0), pm.size())
            centered_rect = QRect(pm_rect)
            centered_rect.moveCenter(icon_area_rect.center())
            p.drawPixmap(centered_rect, pm, pm_rect)
        p.restore()
Exemplo n.º 22
0
    def paint(self, painter, option, index):
        self.initStyleOption(option, index)
        if hasattr(option, "checkState"):
            if option.checkState == Qt.Unchecked:
                option.checkState = Qt.PartiallyChecked
            elif option.checkState == Qt.PartiallyChecked:
                option.checkState = Qt.Unchecked
            elif option.checkState == Qt.Checked:
                option.font = QFont(option.font)
                option.font.setStrikeOut(True)
        # ref: qt4-x11-4.6.2/src/gui/styles/qcommonstyle.cpp
        painter.save()
        painter.setClipRect(option.rect)
        # QApplication.style().drawControl(
        #     QStyle.CE_ItemViewItem, option, painter,
        #     getattr(option, "widget", None))
        style = QApplication.style()
        widget = getattr(option, "widget", None)
        # log.debug("widget: %r style: %r" % (widget, style.metaObject().className()))
        style.drawPrimitive(
            QStyle.PE_PanelItemViewItem, option, painter, widget)

        if option.checkState == Qt.Checked:
            painter.setOpacity(0.3)
        text_rect = style.subElementRect(
            QStyle.SE_ItemViewItemText, option, widget)
        item_text = option.fontMetrics.elidedText(
            option.text, option.textElideMode, text_rect.width())
        painter.setFont(option.font)
        style.drawItemText(painter, text_rect, option.displayAlignment,
                           option.palette, True, item_text, QPalette.Text)

        check_rect = style.subElementRect(
            QStyle.SE_ItemViewItemCheckIndicator, option, widget)
        if option.checkState == Qt.PartiallyChecked:
            brush = option.palette.brush(QPalette.Base)
            painter.fillRect(check_rect, brush)
            bullet_rect = QRect(check_rect)
            if bullet_rect.width() > BULLET_SIZE:
                bullet_rect.setLeft(
                    bullet_rect.left() +
                    (bullet_rect.width() - BULLET_SIZE) / 2)
                bullet_rect.setWidth(BULLET_SIZE)
            if bullet_rect.height() > BULLET_SIZE:
                bullet_rect.setTop(
                    bullet_rect.top() +
                    (bullet_rect.height() - BULLET_SIZE) / 2)
                bullet_rect.setHeight(BULLET_SIZE)
            painter.setPen(QPen(option.palette.color(QPalette.Text)))
            painter.setBrush(option.palette.brush(QPalette.Text))
            painter.drawEllipse(bullet_rect)
        else:
            check_opt = QStyleOptionButton()
            check_opt.rect = check_rect
            check_opt.state = option.state & ~QStyle.State_HasFocus
            if option.checkState == Qt.Checked:
                check_opt.state |= QStyle.State_On
            else:
                check_opt.state |= QStyle.State_Off
            style.drawPrimitive(
                QStyle.PE_IndicatorItemViewItemCheck, check_opt, painter,
                widget)
        painter.restore()
class ExtractRasterValue(ParentMapTool):
    """ Button 18. User select nodes and assign raster elevation or value """

    def __init__(self, iface, settings, action, index_action):
        """ Class constructor """

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

        self.dragging = False

        # Vertex marker
        self.vertexMarker = QgsVertexMarker(self.canvas)
        self.vertexMarker.setColor(QColor(255, 25, 25))
        self.vertexMarker.setIconSize(11)
        self.vertexMarker.setIconType(QgsVertexMarker.ICON_BOX)  # or ICON_CROSS, ICON_X
        self.vertexMarker.setPenWidth(5)

        # Rubber band
        self.rubberBand = QgsRubberBand(self.canvas, True)
        mFillColor = QColor(100, 0, 0)
        self.rubberBand.setColor(mFillColor)
        self.rubberBand.setWidth(3)
        mBorderColor = QColor(254, 58, 29)
        self.rubberBand.setBorderColor(mBorderColor)

        # Select rectangle
        self.selectRect = QRect()

        # Init
        self.vectorLayer = None
        self.rasterLayer = None

    def reset(self):
        """ Clear selected features """

        layer = self.vectorLayer
        if layer is not None:
            layer.removeSelection()

        # Graphic elements
        self.rubberBand.reset()

    def set_config_action(self, action_99):
        """ Get the config form action"""
        self.configAction = action_99

    """ QgsMapTools inherited event functions """

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

        if self.vectorLayer is None:
            return

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

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

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

        else:

            # Hide highlight
            self.vertexMarker.hide()

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            eventPoint = QPoint(x, y)

            # Snapping
            (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint)  # @UnusedVariable

            # That's the snapped point
            if result <> []:

                # Check Arc or Node
                for snapPoint in result:

                    if snapPoint.layer == self.vectorLayer:

                        # Get the point
                        point = QgsPoint(result[0].snappedVertex)

                        # Add marker
                        self.vertexMarker.setCenter(point)
                        self.vertexMarker.show()

                        break

    def canvasPressEvent(self, event):

        self.selectRect.setRect(0, 0, 0, 0)
        self.rubberBand.reset()

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

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

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            eventPoint = QPoint(x, y)

            # Node layer
            layer = self.vectorLayer

            # Not dragging, just simple selection
            if not self.dragging:

                # Snap to node
                (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint)  # @UnusedVariable

                # That's the snapped point
                if result <> [] and (result[0].layer.name() == self.vectorLayer.name()):

                    point = QgsPoint(result[0].snappedVertex)  # @UnusedVariable
                    layer.removeSelection()
                    layer.select([result[0].snappedAtGeometry])

                    # Interpolate values
                    self.raster_interpolate()

                    # Hide highlight
                    self.vertexMarker.hide()

            else:

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

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

                self.set_rubber_band()
                selectGeom = self.rubberBand.asGeometry()  # @UnusedVariable
                self.select_multiple_features(self.selectRectMapCoord)
                self.dragging = False

                # Interpolate values
                self.raster_interpolate()

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

            # Interpolate values
            self.raster_interpolate()

    def activate(self):

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

        # Rubber band
        self.rubberBand.reset()

        # Store user snapping configuration
        self.snapperManager.storeSnappingOptions()

        # Clear snapping
        self.snapperManager.clearSnapping()

        # Get layers
        res = self.find_raster_layers()
        #        if res == 0:
        #            self.controller.show_warning("Raster configuration tool not properly configured.")
        #            return

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

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

        # Control current layer (due to QGIS bug in snapping system)
        try:
            if self.canvas.currentLayer().type() == QgsMapLayer.VectorLayer:
                self.canvas.setCurrentLayer(self.layer_arc)
        except:
            self.canvas.setCurrentLayer(self.layer_arc)

    def deactivate(self):

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

        # Rubber band
        self.rubberBand.reset()

        # Restore previous snapping
        self.snapperManager.recoverSnappingOptions()

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

    def nearestNeighbor(self, thePoint):

        ident = self.dataProv.identify(thePoint, QgsRaster.IdentifyFormatValue)
        value = None
        if ident is not None:  # and ident.has_key(choosenBand+1):
            try:
                value = float(ident.results()[int(self.band)])
            except TypeError:
                value = None
        if value == self.noDataValue:
            return None
        return value

    def writeInterpolation(self, f, fieldIdx):

        thePoint = f.geometry().asPoint()
        value = self.nearestNeighbor(thePoint)
        self.vectorLayer.changeAttributeValue(f.id(), fieldIdx, value)

    def raster_interpolate(self):
        """ Interpolate features value from raster """

        # Interpolate values
        if self.vectorLayer is None and self.rasterLayer is None:
            return

        # Get data provider
        layer = self.vectorLayer
        self.dataProv = self.rasterLayer.dataProvider()
        if self.dataProv.srcNoDataValue(int(self.band)):
            self.noDataValue = self.dataProv.srcNoDataValue(int(self.band))
        else:
            self.noDataValue = None

        self.continueProcess = True

        self.fieldIdx = ""
        self.fieldIdx = layer.fieldNameIndex(self.fieldName)

        if self.band == 0:
            self.controller.show_warning("You must choose a band for the raster layer.")
            return
        if self.fieldName == "":
            self.controller.show_warning("You must choose a field to write values.")
            return
        if self.fieldIdx < 0:
            self.controller.show_warning("Selected field does not exist in feature layer.")
            return

        k = 0
        c = 0
        f = QgsFeature()

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

            return

        # Check editable
        if not layer.isEditable():
            layer.startEditing()

        # Get selected id's
        ids = self.vectorLayer.selectedFeaturesIds()

        for fid in ids:

            k += 1
            layer.getFeatures(QgsFeatureRequest(fid)).nextFeature(f)
            c += 1
            self.writeInterpolation(f, self.fieldIdx)
            QCoreApplication.processEvents()

        self.controller.show_info(
            "%u values have been updated in layer %s.%s over %u points using %s raster"
            % (c, self.vectorLayer.name(), self.fieldName, k, self.table_raster)
        )

        # Check editable
        if layer.isEditable():
            layer.commitChanges()

        # Refresh map canvas
        self.rubberBand.reset()
        self.iface.mapCanvas().refresh()

    def set_rubber_band(self):

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

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

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

        self.selectRectMapCoord = QgsRectangle(ll, ur)

    def select_multiple_features(self, selectGeometry):

        # Default choice
        behaviour = QgsVectorLayer.SetSelection

        # Modifiers
        modifiers = QApplication.keyboardModifiers()

        if modifiers == Qt.ControlModifier:
            behaviour = QgsVectorLayer.AddToSelection
        elif modifiers == Qt.ShiftModifier:
            behaviour = QgsVectorLayer.RemoveFromSelection

        if self.vectorLayer is None:
            return

        # Change cursor
        QApplication.setOverrideCursor(Qt.WaitCursor)

        # Selection
        self.vectorLayer.selectByRect(selectGeometry, behaviour)

        # Old cursor
        QApplication.restoreOverrideCursor()

    def find_raster_layers(self):

        # Query database (form data)
        sql = "SELECT *"
        sql += " FROM " + self.schema_name + ".config_extract_raster_value"

        rows = self.controller.get_rows(sql)

        if not rows:
            self.controller.show_warning("Any data found in table config_extract_raster_value")
            self.configAction.activate(QAction.Trigger)
            return 0

        # Layers
        row = rows[0]
        self.table_raster = row[1]
        self.band = row[2]
        self.table_vector = row[3]
        self.fieldName = row[4]

        # Check if we have any layer loaded
        layers = self.iface.legendInterface().layers()
        if len(layers) == 0:
            return

        # Init layers
        self.rasterLayer = None
        self.vectorLayer = None

        # Iterate over all layers to get the ones specified in 'db' config section
        for cur_layer in layers:

            if cur_layer.name() == self.table_raster:
                self.rasterLayer = cur_layer

            (uri_schema, uri_table) = self.controller.get_layer_source(cur_layer)  # @UnusedVariable
            if uri_table is not None:
                if self.table_vector in uri_table:
                    self.vectorLayer = cur_layer

        # Check config
        if self.vectorLayer is None or self.rasterLayer is None:
            self.configAction.activate(QAction.Trigger)

        # Set snapping
        if self.vectorLayer <> None:
            self.snapperManager.snapToLayer(self.vectorLayer)
        else:
            self.controller.show_warning("Check vector_layer in config form, layer does not exist or is not defined.")
            return 0

        if self.rasterLayer == None:
            self.controller.show_warning("Check raster_layer in config form, layer does not exist or is not defined.")
            return 0

        return 1
Exemplo n.º 24
0
    def __paintEventNoStyle(self):
        p = QPainter(self)
        opt = QStyleOptionToolButton()
        self.initStyleOption(opt)

        fm = QFontMetrics(opt.font)
        palette = opt.palette

        # highlight brush is used as the background for the icon and background
        # when the tab is expanded and as mouse hover color (lighter).
        brush_highlight = palette.highlight()
        if opt.state & QStyle.State_Sunken:
            # State 'down' pressed during a mouse press (slightly darker).
            background_brush = brush_darker(brush_highlight, 110)
        elif opt.state & QStyle.State_MouseOver:
            background_brush = brush_darker(brush_highlight, 95)
        elif opt.state & QStyle.State_On:
            background_brush = brush_highlight
        else:
            # The default button brush.
            background_brush = palette.button()

        rect = opt.rect
        icon = opt.icon
        icon_size = opt.iconSize

        # TODO: add shift for pressed as set by the style (PM_ButtonShift...)

        pm = None
        if not icon.isNull():
            if opt.state & QStyle.State_Enabled:
                mode = QIcon.Normal
            else:
                mode = QIcon.Disabled

            pm = opt.icon.pixmap(
                rect.size().boundedTo(icon_size), mode,
                QIcon.On if opt.state & QStyle.State_On else QIcon.Off)

        icon_area_rect = QRect(rect)
        icon_area_rect.setRight(int(icon_area_rect.height() * 1.26))

        text_rect = QRect(rect)
        text_rect.setLeft(icon_area_rect.right() + 10)

        # Background  (TODO: Should the tab button have native
        # toolbutton shape, drawn using PE_PanelButtonTool or even
        # QToolBox tab shape)

        # Default outline pen
        pen = QPen(palette.color(QPalette.Mid))

        p.save()
        p.setPen(Qt.NoPen)
        p.setBrush(QBrush(background_brush))
        p.drawRect(rect)

        # Draw the background behind the icon if the background_brush
        # is different.
        if not opt.state & QStyle.State_On:
            p.setBrush(brush_highlight)
            p.drawRect(icon_area_rect)
            # Line between the icon and text
            p.setPen(pen)
            p.drawLine(icon_area_rect.topRight(), icon_area_rect.bottomRight())

        if opt.state & QStyle.State_HasFocus:
            # Set the focus frame pen and draw the border
            pen = QPen(QColor(FOCUS_OUTLINE_COLOR))
            p.setPen(pen)
            p.setBrush(Qt.NoBrush)
            # Adjust for pen
            rect = rect.adjusted(0, 0, -1, -1)
            p.drawRect(rect)

        else:
            p.setPen(pen)
            # Draw the top/bottom border
            if self.position == QStyleOptionToolBoxV2.OnlyOneTab or \
                    self.position == QStyleOptionToolBoxV2.Beginning or \
                    self.selected & \
                        QStyleOptionToolBoxV2.PreviousIsSelected:

                p.drawLine(rect.topLeft(), rect.topRight())

            p.drawLine(rect.bottomLeft(), rect.bottomRight())

        p.restore()

        p.save()
        text = fm.elidedText(opt.text, Qt.ElideRight, text_rect.width())
        p.setPen(QPen(palette.color(QPalette.ButtonText)))
        p.setFont(opt.font)

        p.drawText(text_rect,
                   int(Qt.AlignVCenter | Qt.AlignLeft) | \
                   int(Qt.TextSingleLine),
                   text)
        if pm:
            pm_rect = QRect(QPoint(0, 0), pm.size())
            centered_rect = QRect(pm_rect)
            centered_rect.moveCenter(icon_area_rect.center())
            p.drawPixmap(centered_rect, pm, pm_rect)
        p.restore()
Exemplo n.º 25
0
class ConnecMapTool(ParentMapTool):
    """ Button 20. User select connections from layer 'connec'
    Execute SQL function: 'gw_fct_connect_to_network' """

    def __init__(self, iface, settings, action, index_action):
        """ Class constructor """

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

        self.dragging = False

        # Vertex marker
        self.vertexMarker = QgsVertexMarker(self.canvas)
        self.vertexMarker.setColor(QColor(255, 25, 25))
        self.vertexMarker.setIconSize(11)
        self.vertexMarker.setIconType(QgsVertexMarker.ICON_BOX)  # or ICON_CROSS, ICON_X
        self.vertexMarker.setPenWidth(5)

        # Rubber band
        self.rubberBand = QgsRubberBand(self.canvas, True)
        mFillColor = QColor(100, 0, 0)
        self.rubberBand.setColor(mFillColor)
        self.rubberBand.setWidth(3)
        mBorderColor = QColor(254, 58, 29)
        self.rubberBand.setBorderColor(mBorderColor)

        # Select rectangle
        self.selectRect = QRect()

    def reset(self):
        """ Clear selected features """

        layer = self.layer_connec
        if layer is not None:
            layer.removeSelection()

        # Graphic elements
        self.rubberBand.reset()

    """ QgsMapTools inherited event functions """

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

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

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

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

        else:

            # Hide highlight
            self.vertexMarker.hide()

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            eventPoint = QPoint(x, y)

            # Snapping
            (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint)  # @UnusedVariable

            # That's the snapped point
            if result <> []:

                # Check Arc or Node
                for snapPoint in result:

                    if snapPoint.layer == self.layer_connec:

                        # Get the point
                        point = QgsPoint(result[0].snappedVertex)

                        # Add marker
                        self.vertexMarker.setCenter(point)
                        self.vertexMarker.show()

                        break

    def canvasPressEvent(self, event):

        self.selectRect.setRect(0, 0, 0, 0)
        self.rubberBand.reset()

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

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

            # Get the click
            x = event.pos().x()
            y = event.pos().y()
            eventPoint = QPoint(x, y)

            # Node layer
            layer = self.layer_connec

            # Not dragging, just simple selection
            if not self.dragging:

                # Snap to node
                (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint)  # @UnusedVariable

                # That's the snapped point
                if result <> [] and (result[0].layer.name() == self.layer_connec.name()):

                    point = QgsPoint(result[0].snappedVertex)  # @UnusedVariable
                    layer.removeSelection()
                    layer.select([result[0].snappedAtGeometry])

                    # Create link
                    self.link_connec()

                    # Hide highlight
                    self.vertexMarker.hide()

            else:

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

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

                self.set_rubber_band()
                selectGeom = self.rubberBand.asGeometry()  # @UnusedVariable
                self.select_multiple_features(self.selectRectMapCoord)
                self.dragging = False

                # Create link
                self.link_connec()

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

            # Create link
            self.link_connec()

    def activate(self):

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

        # Rubber band
        self.rubberBand.reset()

        # Store user snapping configuration
        self.snapperManager.storeSnappingOptions()

        # Clear snapping
        self.snapperManager.clearSnapping()

        # Set snapping to arc and node
        self.snapperManager.snapToConnec()

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

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

        # Control current layer (due to QGIS bug in snapping system)
        try:
            if self.canvas.currentLayer().type() == QgsMapLayer.VectorLayer:
                self.canvas.setCurrentLayer(self.layer_connec)
        except:
            self.canvas.setCurrentLayer(self.layer_connec)

    def deactivate(self):

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

        # Rubber band
        self.rubberBand.reset()

        # Restore previous snapping
        self.snapperManager.recoverSnappingOptions()

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

    def link_connec(self):
        """ Link selected connec to the pipe """

        # Get selected features (from layer 'connec')
        aux = "{"
        layer = self.layer_connec
        if layer.selectedFeatureCount() == 0:
            message = "You have to select at least one feature!"
            self.controller.show_warning(message, context_name="ui_message")

            return
        features = layer.selectedFeatures()
        for feature in features:
            connec_id = feature.attribute("connec_id")
            aux += str(connec_id) + ", "
        connec_array = aux[:-2] + "}"

        # Execute function
        function_name = "gw_fct_connect_to_network"
        sql = "SELECT " + self.schema_name + "." + function_name + "('" + connec_array + "');"
        self.controller.execute_sql(sql)

        # Refresh map canvas
        self.rubberBand.reset()
        self.iface.mapCanvas().refresh()

    def set_rubber_band(self):

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

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

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

        self.selectRectMapCoord = QgsRectangle(ll, ur)

    def select_multiple_features(self, selectGeometry):

        # Default choice
        behaviour = QgsVectorLayer.SetSelection

        # Modifiers
        modifiers = QApplication.keyboardModifiers()

        if modifiers == Qt.ControlModifier:
            behaviour = QgsVectorLayer.AddToSelection
        elif modifiers == Qt.ShiftModifier:
            behaviour = QgsVectorLayer.RemoveFromSelection

        if self.layer_connec is None:
            return

        # Change cursor
        QApplication.setOverrideCursor(Qt.WaitCursor)

        # Selection
        self.layer_connec.selectByRect(selectGeometry, behaviour)

        # Old cursor
        QApplication.restoreOverrideCursor()