class LineDrawer(QgsMapToolEmitPoint):

    def __init__(self, canvas):
        # call the parent constructor
        QgsMapToolEmitPoint.__init__(self, canvas)
        # store the passed canvas
        self.canvas = canvas

        # flag to know whether the tool is performing a drawing operation 
        self.isDrawing = False

        # create and setup the rubber band to display the line
        self.rubberBand = QgsRubberBand( self.canvas, False )    # False = not a polygon = a line
        self.rubberBand.setColor( Qt.red )
        self.rubberBand.setWidth( 1 )


    def clear(self):
        self.rubberBand.reset( False )    # False = not a polygon = a line

    def delete(self):
        self.canvas.scene().removeItem( self.rubberBand )

    def canvasPressEvent(self, e):
        # which the mouse button?
        if e.button() == Qt.LeftButton:
            # left click

            # if it's the first left click, clear the rubberband 
            if not self.isDrawing:
                self.clear()

            # we are drawing now
            self.isDrawing = True

            # convert the clicked position to map coordinates
            point = self.toMapCoordinates( e.pos() )
            # add a new point to the rubber band
            self.rubberBand.addPoint( point, True )    # True = display updates on the canvas
            # and finally show the rubber band
            self.rubberBand.show()

        elif e.button() == Qt.RightButton:
            # right click, stop drawing
            self.isDrawing = False
            # emit a signal
            self.emit( SIGNAL("editingFinished()") )

    def canvasMoveEvent(self, e):
        # check if it's already drawing
        if not self.isDrawing:
            return

        # convert the mouse position to map coordinates
        point = self.toMapCoordinates( e.pos() )
        # move the last point to the new coordinates
        self.rubberBand.movePoint( point )

    def geometry(self):
        return self.rubberBand.asGeometry()
Example #2
0
    def _draw_rubberband(self, extent, colour, width=2):
        """
        Draw a rubber band on the canvas.

        .. versionadded: 2.2.0

        :param extent: Extent that the rubber band should be drawn for.
        :type extent: QgsRectangle

        :param colour: Colour for the rubber band.
        :type colour: QColor

        :param width: The width for the rubber band pen stroke.
        :type width: int

        :returns: Rubber band that should be set to the extent.
        :rtype: QgsRubberBand
        """
        rubberband = QgsRubberBand(
            self.iface.mapCanvas(), geometryType=QGis.Line)
        rubberband.setColor(colour)
        rubberband.setWidth(width)
        update_display_flag = False
        point = QgsPoint(extent.xMinimum(), extent.yMinimum())
        rubberband.addPoint(point, update_display_flag)
        point = QgsPoint(extent.xMaximum(), extent.yMinimum())
        rubberband.addPoint(point, update_display_flag)
        point = QgsPoint(extent.xMaximum(), extent.yMaximum())
        rubberband.addPoint(point, update_display_flag)
        point = QgsPoint(extent.xMinimum(), extent.yMaximum())
        rubberband.addPoint(point, update_display_flag)
        point = QgsPoint(extent.xMinimum(), extent.yMinimum())
        update_display_flag = True
        rubberband.addPoint(point, update_display_flag)
        return rubberband
Example #3
0
class QgepMapTool( QgsMapTool ):
    '''
    Base class for all the map tools
    '''
    
    highLightedPoints = []
    logger = logging.getLogger( __name__ )
    
    def __init__( self, iface, button ):
        QgsMapTool.__init__( self, iface.mapCanvas() )
        self.canvas = iface.mapCanvas()
        self.cursor = QCursor( Qt.CrossCursor )
        self.button = button
        self.msgBar = iface.messageBar()

        settings = QSettings()
        currentProfileColor = settings.value( "/QGEP/CurrentProfileColor", u'#FF9500' )
        
        self.rubberBand = QgsRubberBand( self.canvas )
        self.rubberBand.setColor( QColor( currentProfileColor ) )
        self.rubberBand.setWidth( 3 )

    # Gets called when the tool is activated
    def activate( self ):
        QgsMapTool.activate( self )
        self.canvas.setCursor( self.cursor )
        self.button.setChecked( True )

    # Gets called whenever the tool is deactivated directly or indirectly
    def deactivate( self ):
        QgsMapTool.deactivate( self )
        self.button.setChecked( False )

    def isZoomTool( self ):
        return False

    def setCursor( self, cursor ):
        self.cursor = QCursor( cursor )

    #===========================================================================
    # Events
    #===========================================================================
    
    def canvasMoveEvent( self, event ):
        try:
            self.mouseMoved( event )
        except AttributeError:
            pass

    def canvasReleaseEvent( self, event ):
        if event.button() == Qt.RightButton:
            self.rightClicked ( event )
        else:
            self.leftClicked( event )

    def canvasDoubleClickEvent( self, event ):
        try:
            self.doubleClicked( event )
        except AttributeError:
            pass
Example #4
0
    def _draw_rubberband(self, geometry, colour, width):
        """Draw a rubber band on the canvas.

        .. versionadded: 2.2.0

        :param geometry: Extent that the rubber band should be drawn for.
        :type geometry: QgsGeometry

        :param colour: Colour for the rubber band.
        :type colour: QColor

        :param width: The width for the rubber band pen stroke.
        :type width: int

        :returns: Rubber band that should be set to the extent.
        :rtype: QgsRubberBand
        """
        # noinspection PyArgumentList
        rubber_band = QgsRubberBand(
            self._map_canvas, geometryType=QGis.Polygon)
        rubber_band.setBrushStyle(Qt.NoBrush)
        rubber_band.setColor(colour)
        rubber_band.setWidth(width)
        rubber_band.setToGeometry(geometry, None)
        return rubber_band
class PlaceMarkerMapTool(QgsMapToolEmitPoint):
    '''
    classdocs
    '''

    def __init__(self, canvas):
        '''
        Constructor
        '''
        self.canvas = canvas
        super(PlaceMarkerMapTool, self).__init__(self.canvas)
        self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon)
        self.rubberBand.setColor(Qt.red)
        self.rubberBand.setWidth(1)
        self.reset()

    def reset(self):
        self.rubberBand.reset(QGis.Polygon)

    def canvasReleaseEvent(self, e):
        p1 = self.canvas.getCoordinateTransform().toMapCoordinates(e.x() - 2, e.y() - 2)
        p2 = self.canvas.getCoordinateTransform().toMapCoordinates(e.x() + 2, e.y() - 2)
        p3 = self.canvas.getCoordinateTransform().toMapCoordinates(e.x() + 2, e.y() + 2)
        p4 = self.canvas.getCoordinateTransform().toMapCoordinates(e.x() - 2, e.y() + 2)
        self.reset()

        self.rubberBand.addPoint(p1, False)
        self.rubberBand.addPoint(p2, False)
        self.rubberBand.addPoint(p3, False)
        self.rubberBand.addPoint(p4, True)
        self.rubberBand.show()

    def deactivate(self):
        self.reset()
        super(PlaceMarkerMapTool, self).deactivate()
	def loadLines(self, lines, points, markers, suffix):
		no = self.project.readEntry("TUVIEW", "lines{0}no".format(suffix))[0]
		if no:
			no = int(no)
			for i in range(no):
				a = self.project.readEntry("TUVIEW", 'lines{0}x{1}'.format(suffix, i))[0]
				a = a.split('~~')
				b = self.project.readEntry("TUVIEW", 'lines{0}y{1}'.format(suffix, i))[0]
				b = b.split('~~')
				points.clear()
				for j in range(len(a)):
					x = float(a[j])
					y = float(b[j])
					point = QgsPoint(x, y)
					points.append(point)
					if i + 1 == no:
						marker = QgsVertexMarker(self.tuView.canvas)
						if suffix == 'cs':
							marker.setColor(Qt.red)
							marker.setIconSize(10)
							marker.setIconType(QgsVertexMarker.ICON_BOX)
						else:  # 'q'
							marker.setColor(Qt.blue)
							marker.setIconSize(12)
							marker.setIconType(QgsVertexMarker.ICON_DOUBLE_TRIANGLE)
						marker.setCenter(QgsPointXY(point))
						markers.append(marker)
				line = QgsRubberBand(self.tuView.canvas, False)
				line.setWidth(2)
				if suffix == 'cs':
					line.setColor(QColor(Qt.red))
				else:  # 'q'
					line.setColor(QColor(Qt.blue))
				line.setToGeometry(QgsGeometry.fromPolyline(points), None)
				lines.append(line)
    def zoomAndShowWKT(self, wtk):
        geom = QgsGeometry.fromWkt(wtk)
        canvas = self.iface.mapCanvas() 
        self.clear()

        r = QgsRubberBand(canvas, geom.type() == 3 )
        r.setToGeometry(geom, None)
        r.setColor(QColor(0, 0, 255))
        r.setFillColor(QColor(0, 0, 255, 50))
        r.setWidth(3)

        pt = geom.pointOnSurface().asPoint()
        m = QgsVertexMarker(canvas)
        m.setCenter( pt )
        m.setColor(QColor(0, 0, 255))
        m.setIconSize(5)
        m.setIconType(QgsVertexMarker.ICON_BOX)  
        m.setPenWidth(3)

        if geom.type() == 3 or geom.type() == 2:
           rec = geom.boundingBox()
           canvas.setExtent(rec)
        else:
           self.moveMapTo( pt[0], pt[1], 0)

        self.graphics.append(r) 
        self.graphics.append(m) 
        self._refresh_layers()
class GetPointMapTool(QgsMapToolEmitPoint):

    coordCaptured = ""

    def __init__(self, canvas, iface, dockwidget, currentMapTool):
        self.canvas = canvas
        self.iface = iface
        self.currentMapTool = currentMapTool
        self.dockwidget = dockwidget
        QgsMapToolEmitPoint.__init__(self, self.canvas)
        self.rubberBand = QgsRubberBand(self.canvas, QGis.Point)
        self.rubberBand.setColor(QColor(255,5,5))
        self.rubberBand.setWidth(1)
        self.reset()

    def reset(self):
        self.startPoint = self.endPoint = None
        self.isEmittingPoint = False
        self.rubberBand.reset(QGis.Polygon)

    def canvasPressEvent(self, e):
        self.point = self.toMapCoordinates(e.pos())
        self.isEmittingPoint = True
        self.showPoint(self.point)

    def canvasReleaseEvent(self, e):
        self.isEmittingPoint = False
        self.coordCaptured = self.pointdef()
        if self.coordCaptured is not None:
            print "Point:", self.coordCaptured
            self.coordCaptured = str(self.coordCaptured).strip("(")
            self.coordCaptured = str(self.coordCaptured).strip(")")
            self.dockwidget.munLineEdit.setText(self.coordCaptured)


        self.iface.mapCanvas().setMapTool(self.currentMapTool)

    def canvasMoveEvent(self, e):
        if not self.isEmittingPoint:
            return

        self.endPoint = self.toMapCoordinates(e.pos())
       # self.showRect(self.startPoint, self.endPoint)

    def showPoint(self, point):
        self.rubberBand.reset(QGis.Polygon)


        point1 = QgsPoint(point.x(), point.y())


        self.rubberBand.addPoint(point1, False)

        self.rubberBand.show()

    def pointdef(self):

        return QgsPoint(self.point)
 def addGraphic(self, geom ):
     canvas = self.iface.mapCanvas()      
     rBand = QgsRubberBand(canvas, True) 
     self.graphics.append( rBand )
     rBand.setToGeometry( geom, None )
     rBand.setColor(QtGui.QColor(0,0,255, 70))
     if QGis.QGIS_VERSION_INT >= 20600:
         rBand.setBorderColor( QtGui.QColor(0,0,250, 220) )
     rBand.setWidth(3)
Example #10
0
class QgepMapToolAddFeature( QgsMapTool ):
    def __init__(self, iface, layer):
        QgsMapTool.__init__(self, iface.mapCanvas() )
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.layer = layer
        self.rubberband = QgsRubberBand( iface.mapCanvas(), layer.geometryType() )
        self.rubberband.setColor( QColor( "#ee5555" ) )
        self.rubberband.setWidth( 2 )
        self.tempRubberband = QgsRubberBand( iface.mapCanvas(), layer.geometryType() )
        self.tempRubberband.setColor( QColor( "#ee5555" ) )
        self.tempRubberband.setWidth( 2 )
        self.tempRubberband.setLineStyle(Qt.DotLine)

    def activate(self):
        QgsMapTool.activate( self )
        self.canvas.setCursor( QCursor( Qt.CrossCursor ) )
        pass

    def deactivate(self):
        QgsMapTool.deactivate( self )
        self.canvas.unsetCursor()
        pass

    def isZoomTool( self ):
        return False

    #===========================================================================
    # Events
    #===========================================================================

    def canvasMoveEvent( self, event ):
        self.mouseMoved( event )

    def canvasReleaseEvent( self, event ):
        if event.button() == Qt.RightButton:
            self.rightClicked ( event )
        else:
            self.leftClicked( event )

    def leftClicked(self, event):
        mousePos = self.canvas.getCoordinateTransform().toMapCoordinates( event.pos().x(), event.pos().y() )
        self.rubberband.addPoint( mousePos )
        self.tempRubberband.reset()

    def rightClicked(self, event):
        f = QgsFeature( self.layer.pendingFields() )
        f.setGeometry( self.rubberband.asGeometry() )
        dlg = self.iface.getFeatureForm( self.layer, f )
        dlg.setIsAddDialog(True)
        dlg.exec_()
        self.rubberband.reset()
        self.tempRubberband.reset()

    def mouseMoved(self, event):
        mousePos = self.canvas.getCoordinateTransform().toMapCoordinates( event.pos().x(), event.pos().y() )
        self.tempRubberband.movePoint( mousePos )
Example #11
0
 def _setRubberBandMarker(self, geom):
     m = QgsRubberBand(self.qgisIface.mapCanvas(), False)  # not polygon
     if QgsWkbTypes.geometryType(geom.wkbType()) == QgsWkbTypes.LineGeometry:
         linegeom = geom
     elif QgsWkbTypes.geometryType(geom.wkbType()) == QgsWkbTypes.PolygonGeometry:
         linegeom = QgsGeometry.fromPolylineXY(geom.asPolygon()[0])
     m.setToGeometry(linegeom, None)
     m.setColor(QColor(self.config['rubber_color']))
     m.setWidth(self.config['rubber_width'])
     return m
 def initRubberLayer(self):
     if self.rubberLayer:
         rb = self.rubberLayer
         rb.reset(True)
     else:
         rb = QgsRubberBand(self.iface.mapCanvas(), True)
     rb.setColor(QColor(255, 0, 255, 255))
     rb.setWidth(3)
     rb.setFillColor(QColor(255, 0, 255, 50))
     self.rubberLayer = rb
Example #13
0
class CurrentSelection(QgsRubberBand):
    """
    Position marker for the current location in the viewer.
    """

    class AniObject(QObject):
        def __init__(self, band):
            super(CurrentSelection.AniObject, self).__init__()
            self.color = QColor()

        @pyqtProperty(int)
        def alpha(self):
            return self.color.alpha()

        @alpha.setter
        def alpha(self, value):
            self.color.setAlpha(value)

    def __init__(self, canvas):
        super(CurrentSelection, self).__init__(canvas)
        self.outline = QgsRubberBand(canvas)
        self.outline.setBrushStyle(Qt.NoBrush)
        self.outline.setWidth(5)
        self.outline.setIconSize(30)
        self.aniobject = CurrentSelection.AniObject(self)
        self.anim = QPropertyAnimation(self.aniobject, "alpha")
        self.anim.setDuration(500)
        self.anim.setStartValue(50)
        self.anim.setEndValue(100)
        self.anim.valueChanged.connect(self.value_changed)

    def setOutlineColour(self, color):
        self.outline.setColor(color)

    def setToGeometry(self, geom, layer):
        super(CurrentSelection, self).setToGeometry(geom, layer)
        self.outline.setToGeometry(geom, layer)
        self.anim.stop()
        self.anim.start()

    def reset(self, geomtype=QGis.Line):
        super(CurrentSelection, self).reset(geomtype)
        self.outline.reset(geomtype)
        self.anim.stop()

    def value_changed(self, value):
        self.setColor(self.aniobject.color)
        self.update()

    def setColor(self, color):
        self.aniobject.color = color
        super(CurrentSelection, self).setColor(color)
Example #14
0
    def drawManyPaths(self, rows, columns, con, args, geomType, canvasItemList, mapCanvas):
        '''
            draws multi line string on the mapCanvas.
        '''
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_path_id = None
        for row in rows:
            cur2 = con.cursor()
            result_path_id = str(row[columns[0]])
            args['result_node_id'] = sql.Literal(row[columns[1]])
            args['result_edge_id'] = sql.Literal(row[columns[2]])

            if result_path_id != cur_path_id:
                cur_path_id = result_path_id
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas, Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)

            if row[columns[2]] != -1:
                query2 = sql.SQL("""
                    SELECT ST_AsText({transform_s}{geometry}{transform_e})
                    FROM {edge_schema}.{edge_table}
                    WHERE {source} = {result_node_id} AND {id} = {result_edge_id}

                    UNION

                    SELECT ST_AsText({transform_s}ST_Reverse({geometry}){transform_e})
                    FROM {edge_schema}.{edge_table}
                    WHERE {target} = {result_node_id} AND {id} = {result_edge_id}
                    """).format(**args).as_string(con)

                cur2.execute(query2)
                row2 = cur2.fetchone()

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            rubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        rubberBand.addPoint(pt)

        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
Example #15
0
class DrawPolygon(QgsMapTool):
    '''Outil de sélection par polygone, tiré de selectPlusFr'''

    selectionDone = pyqtSignal()
    move = pyqtSignal()

    def __init__(self, iface, couleur):
        canvas = iface.mapCanvas()
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas
        self.iface = iface
        self.status = 0
        self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
        self.rb.setColor(couleur)
        return None

    def keyPressEvent(self, e):
        if e.matches(QKeySequence.Undo):
            if self.rb.numberOfVertices() > 1:
                self.rb.removeLastPoint()

    def canvasPressEvent(self, e):
        if e.button() == Qt.LeftButton:
            if self.status == 0:
                self.rb.reset(QgsWkbTypes.PolygonGeometry)
                self.status = 1
            self.rb.addPoint(self.toMapCoordinates(e.pos()))
        else:
            if self.rb.numberOfVertices() > 2:
                self.status = 0
                self.selectionDone.emit()
            else:
                self.reset()
        return None

    def canvasMoveEvent(self, e):
        if self.rb.numberOfVertices() > 0 and self.status == 1:
            self.rb.removeLastPoint(0)
            self.rb.addPoint(self.toMapCoordinates(e.pos()))
        self.move.emit()
        return None

    def reset(self):
        self.status = 0
        self.rb.reset(True)

    def deactivate(self):
        self.rb.reset(True)
        QgsMapTool.deactivate(self)
Example #16
0
 def _createRubberBand(self, geometryType, moveBand=False):
     settings = QSettings()
     rb = QgsRubberBand(self.canvas(), geometryType)
     rb.setWidth(int(settings.value('/qgis/digitizing/line_width', 1)))
     color = QColor(int(settings.value('/qgis/digitizing/line_color_red', 255)),
                    int(settings.value('/qgis/digitizing/line_color_green', 0)),
                    int(settings.value('/qgis/digitizing/line_color_blue', 0)))
     myAlpha = int(settings.value('/qgis/digitizing/line_color_alpha', 200)) / 255.0
     if (moveBand):
         myAlpha = myAlpha * float(settings.value('/qgis/digitizing/line_color_alpha_scale', 0.75))
         rb.setLineStyle(Qt.DotLine)
     if (geometryType == QGis.Polygon):
         color.setAlphaF(myAlpha)
     color.setAlphaF(myAlpha)
     rb.setColor(color)
     rb.show()
     return rb
Example #17
0
class lineTool(QgsMapTool):
    def __init__(self, iface, callback):
        QgsMapTool.__init__(self,iface.mapCanvas())
        self.iface  = iface
        self.canvas = iface.mapCanvas()
        self.cursor = QCursor(Qt.CrossCursor)
        self.callback   = callback
        
        self.rubberBand = QgsRubberBand(self.canvas, False)
        self.points  = []
        self.rubberBand.setColor(Qt.red)
        self.rubberBand.setWidth(1.6)

    def canvasReleaseEvent(self,event):
        if event.button() == Qt.RightButton:
          self.points.append(QgsPoint( self.toMapCoordinates( event.pos()) ) )
          if len(self.points) <= 1 :return
        
          self.rubberBand.setToGeometry( QgsGeometry.fromPolyline(self.points), None )
          self.callback( self.rubberBand )
          QgsMapTool.deactivate(self)
        else:
          self.points.append(QgsPoint( self.toMapCoordinates(event.pos()) ) )
          if len(self.points) <= 1 : return
          self.rubberBand.setToGeometry( QgsGeometry.fromPolyline(self.points), None )

    def canvasDoubleClickEvent(self,event):
        self.points.append(QgsPoint( self.toMapCoordinates( event.pos()) ))
        if len(self.points) <= 1 : return
      
        self.rubberBand.setToGeometry( QgsGeometry.fromPolyline(self.points), None )
        self.callback( self.rubberBand )
        QgsMapTool.deactivate(self)
    
    def activate(self):
      QgsMapTool.activate(self)
      self.canvas.setCursor(self.cursor)

    def isZoomTool(self):
        return False

    def setCursor(self,cursor):
        self.cursor = QCursor(cursor)
Example #18
0
class SelectPoint(QgsMapTool):
    select = pyqtSignal()
    selectionDone = pyqtSignal()

    def __init__(self, iface, couleur):
        canvas = iface.mapCanvas()
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas
        self.iface = iface
        self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
        self.rb.setColor(couleur)
        self.rbSelect = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
        return None

    def canvasReleaseEvent(self, e):
        if e.button() == Qt.LeftButton:
            self.rbSelect.reset(QgsWkbTypes.PolygonGeometry)
            cp = self.toMapCoordinates(
                QPoint(e.pos().x() - 5, e.pos().y() - 5))
            self.rbSelect.addPoint(cp)
            cp = self.toMapCoordinates(
                QPoint(e.pos().x() + 5, e.pos().y() - 5))
            self.rbSelect.addPoint(cp)
            cp = self.toMapCoordinates(
                QPoint(e.pos().x() + 5, e.pos().y() + 5))
            self.rbSelect.addPoint(cp)
            cp = self.toMapCoordinates(
                QPoint(e.pos().x() - 5, e.pos().y() + 5))
            self.rbSelect.addPoint(cp)
            self.select.emit()
        else:
            self.selectionDone.emit()
        return None

    def reset(self):
        self.rb.reset(QgsWkbTypes.PolygonGeometry)
        self.rbSelect.reset(QgsWkbTypes.PolygonGeometry)

    def deactivate(self):
        self.rb.reset(QgsWkbTypes.PolygonGeometry)
        self.rbSelect.reset(QgsWkbTypes.PolygonGeometry)
        QgsMapTool.deactivate(self)
Example #19
0
class RubberBandResultRenderer():

    def __init__(self, iface, color = QColor('magenta'), size = 12):
        self.iface = iface
        self.rb = QgsRubberBand(self.iface.mapCanvas(), QGis.Point)
        self.rb.setColor(color)
        self.rb.setIconSize(size)

        self.srs_wgs84 = QgsCoordinateReferenceSystem(4326)
        self.transformation = QgsCoordinateTransform(self.srs_wgs84, self.srs_wgs84)

    def show_point(self, point, center=False):
        #check srs
        if self.need_transform():
            point = self.transform_point(point)

        self.rb.addPoint(point)
        if center:
            self.center_to_point(point)

    def clear(self):
        self.rb.reset(QGis.Point)

    def need_transform(self):
        return self.iface.mapCanvas().mapRenderer().destinationCrs().postgisSrid() != 4326

    def transform_point(self, point):
        dest_srs_id = self.iface.mapCanvas().mapRenderer().destinationCrs().srsid()
        self.transformation.setDestCRSID(dest_srs_id)
        try:
            return self.transformation.transform(point)
        except:
            print 'Error on transform!'  # DEBUG! need message???
            return

    def center_to_point(self, point):
        canvas = self.iface.mapCanvas()
        new_extent = QgsRectangle(canvas.extent())
        new_extent.scale(1, point)
        canvas.setExtent(new_extent)
        canvas.refresh()
Example #20
0
 def createMoveTrack(self, line=False, color=QColor(255, 71, 25, 170), width=0.2):
     '''Create move track.
     
         :param line: Flag indicating if geometry to draw is a line (True)
             or a polygon(False).
         :type line: bool
     
         :param color: Color of line.
         :type color: QColor
         
         :param width: Width of line.
         :type width: int
         
         :return: Created rubber band. 
         :rtype: QgsRubberBand
     '''
     
     moveTrack = QgsRubberBand(self.canvas, line)
     moveTrack.setColor(color)
     moveTrack.setWidth(width)
     return moveTrack
class FreehandPolygonMaptool(QgsMapTool, QObject):
    trigger = pyqtSignal(QgsGeometry)
    
    def __init__(self, canvas):
        
        QgsMapTool.__init__(self,canvas)
        self.canvas = canvas
        self.rb = QgsRubberBand(canvas, QgsWkbTypes.PolygonGeometry)
        self.rb.setColor(QColor(255, 0, 0, 50))
    
    def activate(self):
        self.rb.reset(QgsWkbTypes.PolygonGeometry)
        
    def deactivate(self):
        self.rb.reset(QgsWkbTypes.PolygonGeometry)
        
    def canvasMoveEvent(self, ev):
        
        worldPoint = QgsMapToPixel.toMapCoordinates(self.canvas.getCoordinateTransform(), ev.pos().x(), ev.pos().y())
        self.rb.movePoint(worldPoint)
        
    def canvasPressEvent(self, ev):
        
        if ev.button() == Qt.LeftButton:
            """ Add a new point to the rubber band """
            worldPoint = QgsMapToPixel.toMapCoordinates(self.canvas.getCoordinateTransform(), ev.pos().x(), ev.pos().y())
            self.rb.addPoint(worldPoint)
        
        elif ev.button() == Qt.RightButton:
            """ Send back the geometry to the calling class """
            self.trigger.emit(self.rb.asGeometry())

    def isZoomTool(self):
        return False
    
    def isTransient(self):
        return False
      
    def isEditTool(self):
        return False
 def highlight(self,geometry):
     def processEvents():
         try:
             qApp.processEvents()
         except:
             QApplication.processEvents()
             
     highlight = QgsRubberBand(self.canvas, geometry.type())
     highlight.setColor(QColor("#36AF6C"))
     highlight.setFillColor(QColor("#36AF6C"))
     highlight.setWidth(2)
     highlight.setToGeometry(geometry,self.canvas.currentLayer())
     processEvents()
     sleep(.1)
     highlight.hide()
     processEvents()
     sleep(.1)
     highlight.show()
     processEvents()
     sleep(.1)
     highlight.reset()
     processEvents()
Example #23
0
class DistanceDialog(QDialog, Ui_place_distance):
    def __init__(self, distance, canvas):
        QDialog.__init__(self)
        self.setupUi(self)
        self.settings = MySettings()

        # this is a reference, distance observation is modified in outer class
        self.distance = distance

        self.rubber = QgsRubberBand(canvas)
        self.rubber.setColor(self.settings.value("rubberColor"))
        self.rubber.setIconSize(self.settings.value("rubberSize"))

        self.x.setText("%.3f" % distance.point.x())
        self.y.setText("%.3f" % distance.point.y())
        self.observation.setValue(distance.observation)
        self.precision.setValue(distance.precision)
        self.observation.selectAll()

    @pyqtSignature("on_observation_valueChanged(double)")
    def on_observation_valueChanged(self, v):
        self.distance.observation = v
        self.rubber.setToGeometry(self.distance.geometry(), None)

    @pyqtSignature("on_precision_valueChanged(double)")
    def on_precision_valueChanged(self, v):
        self.distance.precision = v

    def accept(self):
        self.rubber.reset()
        QDialog.accept(self)

    def reject(self):
        self.rubber.reset()
        QDialog.reject(self)

    def closeEvent(self, e):
        self.rubber.reset()
Example #24
0
class DrawPoint(QgsMapTool):
    selectionDone = pyqtSignal()

    def __init__(self, iface, couleur):
        canvas = iface.mapCanvas()
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas
        self.iface = iface
        self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rb.setColor(couleur)
        self.rb.setWidth(3)

    def canvasReleaseEvent(self, e):
        if e.button() == Qt.LeftButton:
            self.rb.addPoint(self.toMapCoordinates(e.pos()))
            self.selectionDone.emit()

    def reset(self):
        self.rb.reset(QgsWkbTypes.PointGeometry)

    def deactivate(self):
        self.rb.reset(QgsWkbTypes.PointGeometry)
        QgsMapTool.deactivate(self)
Example #25
0
class RectangleMapTool(QgsMapToolEmitPoint):

    def __init__(self, canvas):
        QgsMapToolEmitPoint.__init__(self, canvas)

        self.canvas = canvas
        self.rubberBand = QgsRubberBand(canvas, QGis.Polygon)
        self.rubberBand.setColor(QColor(255, 0, 0, 180))
        self.rubberBand.setWidth(1)
        self.reset()

    def reset(self):
        self.startPoint = self.endPoint = None
        self.isDrawing = False
        self.rubberBand.reset(QGis.Polygon)

    def canvasPressEvent(self, e):
        self.startPoint = self.toMapCoordinates(e.pos())
        self.endPoint = self.startPoint

        mapSettings = self.canvas.mapSettings(
        ) if QGis.QGIS_VERSION_INT >= 20300 else self.canvas.mapRenderer()
        self.mupp = mapSettings.mapUnitsPerPixel()
        self.rotation = mapSettings.rotation() if QGis.QGIS_VERSION_INT >= 20700 else 0

        self.isDrawing = True
        self.showRect(self.startPoint, self.endPoint)

    def canvasReleaseEvent(self, e):
        self.isDrawing = False
        self.emit(SIGNAL("rectangleCreated()"))

    def canvasMoveEvent(self, e):
        if not self.isDrawing:
            return
        self.endPoint = self.toMapCoordinates(e.pos())
        self.showRect(self.startPoint, self.endPoint)

    def showRect(self, startPoint, endPoint):
        self.rubberBand.reset(QGis.Polygon)
        if startPoint.x() == endPoint.x() and startPoint.y() == endPoint.y():
            return

        for i, pt in enumerate(self._rect(startPoint, endPoint).vertices()):
            self.rubberBand.addPoint(pt, bool(i == 3))
        self.rubberBand.show()

    def _rect(self, startPoint, endPoint):
        if startPoint is None or endPoint is None:
            return None

        p0 = self.toCanvasCoordinates(startPoint)
        p1 = self.toCanvasCoordinates(endPoint)
        canvas_rect = QgsRectangle(
            QgsPoint(
                p0.x(), p0.y()), QgsPoint(
                p1.x(), p1.y()))
        center = QgsPoint(
            (startPoint.x() + endPoint.x()) / 2,
            (startPoint.y() + endPoint.y()) / 2)
        return RotatedRect(center, self.mupp * canvas_rect.width(),
                           self.mupp * canvas_rect.height()).rotate(self.rotation, center)

    def rectangle(self):
        return self._rect(self.startPoint, self.endPoint)

    def setRectangle(self, rect):
        if rect == self._rect(self.startPoint, self.endPoint):
            return False

        v = rect.vertices()
        self.startPoint = v[3]
        self.endPoint = v[1]
        self.showRect(self.startPoint, self.endPoint)
        return True
Example #26
0
class EditTool(MapTool):
    """
        Inspection tool which copies the feature to a new layer
        and copies selected data from the underlying feature.
    """
    
    finished = pyqtSignal(object, QgsFeature)
    featuresfound = pyqtSignal(dict)

    def __init__(self, canvas, forms, snapradius = 2):
        MapTool.__init__(self, canvas, [])
        self.canvas = canvas
        self.radius = snapradius
        self.forms = forms
        
        self.band = QgsRubberBand(self.canvas)
        self.band.setColor(QColor.fromRgb(224,162,16))
        self.band.setWidth(3)
        
        self.selectband = None
        
        self.selectrect = QRect()
        self.dragging = False

        self.cursor = QCursor(QPixmap(["16 16 3 1",
            "      c None",
            ".     c #FF0000",
            "+     c #FFFFFF",
            "                ",
            "       +.+      ",
            "      ++.++     ",
            "     +.....+    ",
            "    +.     .+   ",
            "   +.   .   .+  ",
            "  +.    .    .+ ",
            " ++.    .    .++",
            " ... ...+... ...",
            " ++.    .    .++",
            "  +.    .    .+ ",
            "   +.   .   .+  ",
            "   ++.     .+   ",
            "    ++.....+    ",
            "      ++.++     ",
            "       +.+      "]))

    def addForm(self, form):
        self.forms.append(form)
        self.layersupdated.emit(True)

    def layers(self):
        """
        Return a set of layers that this edit tool can work on
        """
        return set([form.QGISLayer for form in self.forms])

    def formsforlayer(self, layer):
        for form in self.forms:
            if form.QGISLayer == layer:
                yield form

    def reset(self):
        self.forms = []
        self.layersupdated.emit(False)

    def getFeatures(self, rect):
        rq = QgsFeatureRequest().setFilterRect(rect)

        self.band.reset()
        for layer in self.layers():
            forms = list(self.formsforlayer(layer))
            rq = QgsFeatureRequest().setFilterRect(rect)
            for feature in layer.getFeatures(rq):
                if feature.isValid():
                    yield feature, forms
                    
    def toSearchRect(self, point):
        searchRadius =  self.canvas.extent().width() * ( self.radius / 100.0 )

        point = self.toMapCoordinates(point)

        rect = QgsRectangle()                                                 
        rect.setXMinimum(point.x() - searchRadius)
        rect.setXMaximum(point.x() + searchRadius)
        rect.setYMinimum(point.y() - searchRadius)
        rect.setYMaximum(point.y() + searchRadius)
        return rect

    def canvasPressEvent(self, event):
        self.selectrect.setRect( 0, 0, 0, 0 )
        
        self.selectband = QgsRubberBand(self.canvas, QGis.Polygon )
        self.selectband.setColor(QColor.fromRgb(0,0,255, 65))
        self.selectband.setWidth(5)
        
    def canvasMoveEvent(self, event):
        if not event.buttons() == Qt.LeftButton:
            return
        
        if not self.dragging:
            self.dragging = True
            self.selectrect.setTopLeft(event.pos())
        self.selectrect.setBottomRight(event.pos())
        
        maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband)  
                     
    def canvasReleaseEvent(self, event):
        if self.dragging:
            geometry = self.selectband.asGeometry()
            if not geometry:
                return

            rect = geometry.boundingBox()            
        else:
            rect = self.toSearchRect(event.pos())
            
        self.dragging = False
        self.selectband.reset()
            
        features = dict(self.getFeatures(rect))
        print features
            
        if len(features) == 1:
            feature = features.keys()[0]
            forms = features.values()[0]
            if len(forms) == 1:
                self.finished.emit(forms[0], feature)
            else:
                self.featuresfound.emit(features)
        elif len(features) > 0:
            self.featuresfound.emit(features)

    def isEditTool(self):
        return True
Example #27
0
class ProfiletoolMapTool(QgsMapTool):
    
    # Signals
    sig_clearMap = pyqtSignal()
    sig_createProfile = pyqtSignal()
    sig_changeCoord = pyqtSignal(QgsPointXY, str)


    def __init__(self, canvas, drawLineButton, showProfileButton): #buttonShowProf
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas
        
        self.cursor = QCursor(Qt.CrossCursor)

        # Red line
        self.rubberband = QgsRubberBand(self.canvas)
        self.rubberband.setWidth(3)
        self.rubberband.setColor(QColor(231, 28, 35))
    
        # Buttons from main dialog
        self.drawLineButton = drawLineButton
        self.buttonShowProf = showProfileButton

        # Coordinates of drawn line points
        self.pointsToDraw = []
        # Temporary save double clicks
        self.dblclktemp = None
        # Drawn line geometry
        self.drawnLine = None
        # Point markers on each end of the line
        self.markers = []
        
        # Backup the last active Tool before the pofile tool became active
        self.savedTool = self.canvas.mapTool()


    def drawLine(self):
        # Emit signal that clears map and deletes profile
        self.sig_clearMap.emit()
        self.reset()
        self.canvas.setMapTool(self)        # runs function self.activate()


    def activate(self):
        self.canvas.setCursor(self.cursor)


    def deactivate(self):
        self.canvas.setCursor(QCursor(Qt.OpenHandCursor))
        self.pointsToDraw = []
        # Stop pressing down button
        self.drawLineButton.setChecked(False)


    def reset(self):
        self.removeStueMarker()
        self.canvas.setMapTool(self.savedTool)
        self.rubberband.reset()
        self.pointsToDraw = []
        self.dblclktemp = None
        self.drawnLine = None
        
        
    def canvasMoveEvent(self, event):
        if len(self.pointsToDraw) > 0:
            self.rubberband.reset()
            line = [self.pointsToDraw[0], event.mapPoint()]
            self.rubberband.setToGeometry(QgsGeometry.fromPolylineXY(line), None)
 

    def canvasReleaseEvent(self, event):
        mapPos = event.mapPoint()
        if mapPos == self.dblclktemp:
            self.dblclktemp = None
            return
        else:
            # Mark point with marker symbol
            self.drawStueMarker(mapPos)
            
            # Klick ist first point of line
            if len(self.pointsToDraw) == 0:
                self.rubberband.reset()
                self.pointsToDraw.append(mapPos)
                return
            
            # Klick is second point of line
            elif len(self.pointsToDraw) == 1:
                self.pointsToDraw.append(mapPos)
                self.removeStueMarker()
                self.dblclktemp = mapPos
                self.drawnLine = self.createDigiFeature(self.pointsToDraw)
                self.sig_changeCoord.emit(self.pointsToDraw[0], 'A')
                self.sig_changeCoord.emit(self.pointsToDraw[1], 'E')
                self.canvas.setMapTool(self.savedTool)      # self.deactivate()


    def setCursor(self, cursor):
        self.cursor = cursor


    def updateLine(self, points):
        self.rubberband.setToGeometry(QgsGeometry.fromPolylineXY(points), None)
        self.drawnLine = self.createDigiFeature(points)
        self.drawStueMarker(points[0])
        self.drawStueMarker(points[1])


    def drawStueMarker(self, point):
        marker = QgsStueMarker(self.canvas)
        marker.setCenter(point)
        self.markers.append(marker)
        self.canvas.refresh()


    def removeStueMarker(self, position=-1):
        if position >= 0:
            marker = self.markers[position]
            self.canvas.scene().removeItem(marker)
            self.markers.pop(position)
        else:
            for marker in self.markers:
                self.canvas.scene().removeItem(marker)
            self.markers = []
        self.canvas.refresh()


    @staticmethod
    def createDigiFeature(pnts):
        line = QgsGeometry.fromPolylineXY(pnts)
        qgFeat = QgsFeature()
        qgFeat.setGeometry(line)
        return qgFeat
class BanLocatorFilter(QgsLocatorFilter):

    HEADERS = {b'User-Agent': b'Mozilla/5.0 QGIS BAN Locator Filter'}

    message_emitted = pyqtSignal(str, str, Qgis.MessageLevel, QWidget)

    def __init__(self, iface: QgisInterface = None):
        """"
        :param filter_type: the type of filter
        :param locale_lang: the language of the locale.
        :param iface: QGIS interface, given when on the main thread (which will display/trigger results), None otherwise
        :param crs: if iface is not given, it shall be provided, see clone()
        """
        super().__init__()
        self.rubber_band = None
        self.feature_rubber_band = None
        self.iface = iface
        self.map_canvas = None
        self.settings = Settings()
        self.transform_4326 = None
        self.current_timer = None
        self.crs = None
        self.event_loop = None
        self.result_found = False
        self.search_delay = 0.5
        self.dbg_info("initialisation")

        if iface is not None:
            # happens only in main thread
            self.map_canvas = iface.mapCanvas()
            self.map_canvas.destinationCrsChanged.connect(
                self.create_transforms)

            self.rubber_band = QgsRubberBand(self.map_canvas,
                                             QgsWkbTypes.PointGeometry)
            self.rubber_band.setColor(QColor(255, 255, 50, 200))
            self.rubber_band.setIcon(self.rubber_band.ICON_CIRCLE)
            self.rubber_band.setIconSize(15)
            self.rubber_band.setWidth(4)
            self.rubber_band.setBrushStyle(Qt.NoBrush)

            self.feature_rubber_band = QgsRubberBand(
                self.map_canvas, QgsWkbTypes.PolygonGeometry)
            self.feature_rubber_band.setColor(QColor(255, 50, 50, 200))
            self.feature_rubber_band.setFillColor(QColor(255, 255, 50, 160))
            self.feature_rubber_band.setBrushStyle(Qt.SolidPattern)
            self.feature_rubber_band.setLineStyle(Qt.SolidLine)
            self.feature_rubber_band.setWidth(4)

            self.create_transforms()

    def name(self):
        return 'Recherche Adresse BAN'

    def clone(self):
        return BanLocatorFilter(self.iface)

    def priority(self):
        return self.settings.value('locations_priority')

    def displayName(self):
        return self.tr('Ban Adress Location')

    def prefix(self):
        return 'ban'

    def clearPreviousResults(self):
        self.rubber_band.reset(QgsWkbTypes.PointGeometry)
        self.feature_rubber_band.reset(QgsWkbTypes.PolygonGeometry)

        if self.current_timer is not None:
            self.current_timer.stop()
            self.current_timer.deleteLater()
            self.current_timer = None

    def hasConfigWidget(self):
        return True

    def openConfigWidget(self, parent=None):
        ConfigDialog(parent).exec_()

    def create_transforms(self):
        # this should happen in the main thread
        dst_crs = self.map_canvas.mapSettings().destinationCrs()
        src_crs_4326 = QgsCoordinateReferenceSystem('EPSG:4326')
        self.transform_4326 = QgsCoordinateTransform(src_crs_4326, dst_crs,
                                                     QgsProject.instance())

    def group_info(self, group: str) -> str:
        return TYPE_RESULT[group]

    @staticmethod
    def url_with_param(url, params) -> str:
        url = QUrl(url)
        q = QUrlQuery(url)
        for key, value in params.items():
            q.addQueryItem(key, value)
        url.setQuery(q)
        return url.url()

    def fetchResults(self, search: str, context: QgsLocatorContext,
                     feedback: QgsFeedback):
        try:
            self.dbg_info("start Ban locator search...")

            if len(search) < 5:
                return

            self.result_found = False

            url = 'https://api-adresse.data.gouv.fr/search/'
            params = {
                'q': str(search),
                'limit': str(self.settings.value('locations_limit'))
            }

            # Locations, WMS layers
            nam = NetworkAccessManager()
            feedback.canceled.connect(nam.abort)
            url = self.url_with_param(url, params)
            self.dbg_info(url)
            try:
                (response, content) = nam.request(url,
                                                  headers=self.HEADERS,
                                                  blocking=True)
                self.handle_response(response)
            except RequestsExceptionUserAbort:
                pass
            except RequestsException as err:
                self.info(err)

            if not self.result_found:
                result = QgsLocatorResult()
                result.filter = self
                result.displayString = self.tr('No result found.')
                result.userData = NoResult
                self.resultFetched.emit(result)

        except Exception as e:
            self.info(e, Qgis.Critical)
            exc_type, exc_obj, exc_traceback = sys.exc_info()
            filename = os.path.split(
                exc_traceback.tb_frame.f_code.co_filename)[1]
            self.info(
                '{} {} {}'.format(exc_type, filename, exc_traceback.tb_lineno),
                Qgis.Critical)
            self.info(
                traceback.print_exception(exc_type, exc_obj, exc_traceback),
                Qgis.Critical)

    def handle_response(self, response):
        try:
            if response.status_code != 200:
                if not isinstance(response.exception,
                                  RequestsExceptionUserAbort):
                    self.info(
                        "Error in main response with status code: {} from {}".
                        format(response.status_code, response.url))
                return

            data = json.loads(response.content.decode('utf-8'))
            # self.dbg_info(data)
            for loc in data['features']:
                importance = loc['properties']['importance']
                citycode = loc['properties']['citycode']
                score = loc['properties']['score']
                type_result = loc['properties']['type']
                label = loc['properties']['label']
                x = float(loc['geometry']['coordinates'][0])
                y = float(loc['geometry']['coordinates'][1])
                result = QgsLocatorResult()
                result.filter = self
                result.displayString = label
                result.group = self.group_info(type_result)
                result.icon = QIcon(
                    ":/plugins/swiss_locator/icons/ban_locator.png")
                result.userData = LocationResult(importance, citycode, score,
                                                 type_result, label, x, y)
                self.result_found = True
                self.resultFetched.emit(result)

        except Exception as e:
            self.info(str(e), Qgis.Critical)
            exc_type, exc_obj, exc_traceback = sys.exc_info()
            filename = os.path.split(
                exc_traceback.tb_frame.f_code.co_filename)[1]
            self.info(
                '{} {} {}'.format(exc_type, filename, exc_traceback.tb_lineno),
                Qgis.Critical)
            self.info(
                traceback.print_exception(exc_type, exc_obj, exc_traceback),
                Qgis.Critical)

    def triggerResult(self, result: QgsLocatorResult):
        # this should be run in the main thread, i.e. mapCanvas should not be None

        # remove any map tip
        self.clearPreviousResults()

        if type(result.userData) == NoResult:
            pass
        else:
            point = QgsGeometry.fromPointXY(result.userData.point)
            if not point:
                return

            point.transform(self.transform_4326)

            self.highlight(point, result.userData.type_result)

            if not self.settings.value('keep_marker_visible'):
                self.current_timer = QTimer()
                self.current_timer.timeout.connect(self.clearPreviousResults)
                self.current_timer.setSingleShot(True)
                self.current_timer.start(8000)

    def highlight(self, point, type_result=None):

        self.rubber_band.reset(QgsWkbTypes.PointGeometry)
        self.rubber_band.addGeometry(point, None)

        if type_result in ('housenumber', 'street'):
            zoom = float(self.settings.value('location_housenumber_zoom'))
        else:
            zoom = float(self.settings.value('location_default_zoom'))
        self.map_canvas.setCenter(point.asPoint())
        self.map_canvas.zoomScale(zoom)

    def info(self, msg="", level=Qgis.Info, emit_message: bool = False):
        self.logMessage(str(msg), level)
        if emit_message:
            self.message_emitted.emit(msg, level)

    def dbg_info(self, msg=""):
        if DEBUG:
            self.info(msg)
Example #29
0
class IntersectionDialog(QDialog, Ui_Intersection, SettingDialog):
    def __init__(self, iface, observations, initPoint):
        QDialog.__init__(self)
        self.setupUi(self)
        self.settings = MySettings()
        SettingDialog.__init__(self, self.settings, UpdateMode.NoUpdate)
        self.processButton.clicked.connect(self.doIntersection)
        self.okButton.clicked.connect(self.accept)
        self.finished.connect(self.resetRubber)
        self.initPoint = initPoint

        self.observations = []
        self.solution = None
        self.report = ""

        self.rubber = QgsRubberBand(iface.mapCanvas(), QGis.Point)
        self.rubber.setColor(self.settings.value("rubberColor"))
        self.rubber.setIcon(self.settings.value("rubberIcon"))
        self.rubber.setIconSize(self.settings.value("rubberSize"))

        self.observationTableWidget.displayRows(observations)
        self.observationTableWidget.itemChanged.connect(self.disbaleOKbutton)
        self.doIntersection()

    def resetRubber(self, dummy=0):
        self.rubber.reset()

    def disbaleOKbutton(self):
        self.okButton.setDisabled(True)

    def doIntersection(self):
        self.observations = []
        self.solution = None
        self.report = ""
        self.rubber.reset()

        observations = self.observationTableWidget.getObservations()
        nObs = len(observations)
        if nObs < 2:
            self.reportBrowser.setText(QCoreApplication.translate("IntersectIt",
                                                                  "No intersection can be done "
                                                                  "with less than 2 observations."))
            return
        if nObs == 2:
            if observations[0]["type"] == "distance" and observations[1]["type"] == "distance":
                intersection = TwoCirclesIntersection(observations, self.initPoint)
            elif observations[0]["type"] == "orientation" and observations[1]["type"] == "orientation":
                intersection = TwoOrientationIntersection(observations)
            else:
                intersection = DistanceOrientationIntersection(observations, self.initPoint)
        else:
            maxIter = self.advancedIntersecLSmaxIteration.value()
            threshold = self.advancedIntersecLSconvergeThreshold.value()
            intersection = LeastSquares(observations, self.initPoint, maxIter, threshold)

        self.reportBrowser.setText(intersection.report)

        if intersection.solution is not None:
            self.solution = intersection.solution
            self.observations = observations
            self.report = intersection.report
            self.okButton.setEnabled(True)
            self.rubber.setToGeometry(QgsGeometry().fromPoint(self.solution), None)
Example #30
0
 def _get_rubberband(self):
     rb_line = QgsRubberBand(self.canvas, QGis.Line)
     rb_line.setColor(self.color)
     rb_line.setLineStyle(Qt.DotLine)
     rb_line.setWidth(3)
     return rb_line
class VoGISProfilToolMainDialog(QDialog):
    def __init__(self, interface, settings):

        self.settings = settings
        self.iface = interface
        self.selectingVisibleRasters = False
        self.thread = None

        QDialog.__init__(self, interface.mainWindow())

        # Set up the user interface from Designer.
        self.ui = Ui_VoGISProfilToolMain()
        self.ui.setupUi(self)

        if self.settings.onlyHektoMode is True:
            self.ui.IDC_widRaster.hide()
            self.adjustSize()

        validator = QIntValidator(-32768, 32768, self)
        self.ui.IDC_tbNoDataExport.setValidator(validator)

        self.ui.IDC_tbFromX.setText('-30000')
        self.ui.IDC_tbFromY.setText('240000')
        self.ui.IDC_tbToX.setText('-20000')
        self.ui.IDC_tbToY.setText('230000')

        self.__addRastersToGui()
        self.__addPolygonsToGui()

        for line_lyr in self.settings.mapData.lines.lines():
            self.ui.IDC_cbLineLayers.addItem(line_lyr.name, line_lyr)

        if self.settings.mapData.lines.count() < 1:
            self.ui.IDC_rbDigi.setChecked(True)
            self.ui.IDC_rbShapeLine.setEnabled(False)

        #Einstellungen fuer Linie zeichen
        self.action = QAction(QIcon(":/plugins/vogisprofiltoolmain/icons/icon.png"), "VoGIS-Profiltool", self.iface.mainWindow())
        self.action.setWhatsThis("VoGIS-Profiltool")
        self.canvas = self.iface.mapCanvas()
        self.tool = ProfiletoolMapTool(self.canvas, self.action)
        self.savedTool = self.canvas.mapTool()
        self.polygon = False
        self.rubberband = QgsRubberBand(self.canvas, self.polygon)
        if QGis.QGIS_VERSION_INT >= 10900:
            #self.rubberband.setBrushStyle()
            self.rubberband.setLineStyle(Qt.SolidLine)
            self.rubberband.setWidth(4.0)
            self.rubberband.setColor(QColor(0, 255, 0))
            #http://www.qgis.org/api/classQgsRubberBand.html#a6f7cdabfcf69b65dfc6c164ce2d01fab
        self.pointsToDraw = []
        self.dblclktemp = None
        self.drawnLine = None

    def accept(self):
        try:
            #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "ACCEPTED")

            #QgsMessageLog.logMessage('nodata: {0}'.format(self.settings.nodata_value), 'VoGis')
            self.settings.nodata_value = int(self.ui.IDC_tbNoDataExport.text())
            QgsMessageLog.logMessage('maindlg: nodata: {0}'.format(self.settings.nodata_value), 'VoGis')

            if self.settings.onlyHektoMode is True and self.settings.mapData.rasters.count() > 0:
                self.settings.onlyHektoMode = False

            if self.settings.onlyHektoMode is False:
                if self.settings.mapData.rasters.count() < 1:
                    #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", u"Keine Raster vorhanden. Zum Hektometrieren Dialog neu öffnen.")
                    #return
                    retVal = QMessageBox.warning(self.iface.mainWindow(),
                                                 "VoGIS-Profiltool",
                                                 QApplication.translate('code', 'Keine Rasterebene vorhanden oder sichtbar! Nur hektometrieren?', None, QApplication.UnicodeUTF8),
                                                 QMessageBox.Yes | QMessageBox.No,
                                                 QMessageBox.Yes)
                    if retVal == QMessageBox.No:
                        return
                    else:
                        self.settings.onlyHektoMode = True
                        self.settings.createHekto = True

            if self.__getSettingsFromGui() is False:
                return

            if self.settings.onlyHektoMode is False:
                if len(self.settings.mapData.rasters.selectedRasters()) < 1:
                    #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "Kein Raster selektiert!")
                    #msg =
                    #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", msg)
                    QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", QApplication.translate('code', 'Kein Raster selektiert!', None, QApplication.UnicodeUTF8))
                    return

            QgsMessageLog.logMessage('modeLine!=line: {0}'.format(self.settings.modeLine != enumModeLine.line), 'VoGis')
            QgsMessageLog.logMessage('customLine is None: {0}'.format(self.settings.mapData.customLine is None), 'VoGis')

            if self.settings.modeLine != enumModeLine.line and self.settings.mapData.customLine is None:
                QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", QApplication.translate('code', 'Keine Profillinie vorhanden!', None, QApplication.UnicodeUTF8))
                return

            if len(self.settings.mapData.polygons.selected_polygons()) > 0 and len(self.settings.mapData.rasters.selectedRasters()) > 1:
                raster_names = list(raster.name for raster in self.settings.mapData.rasters.selectedRasters())
                sel_raster, ok_clicked = QInputDialog.getItem(
                                                self.iface.mainWindow(),
                                                u'DHM?',
                                                u'Welches DHM soll zur Flächenverschneidung verwendet werden?',
                                                raster_names,
                                                0,
                                                False
                                                )
                if ok_clicked is False:
                    return
                self.settings.intersection_dhm_idx = raster_names.index(sel_raster)

            #self.rubberband.reset(self.polygon)
            #QDialog.accept(self)

            QApplication.setOverrideCursor(Qt.WaitCursor)

            create_profile = CreateProfile(self.iface, self.settings)
            thread = QThread(self)
            create_profile.moveToThread(thread)
            create_profile.finished.connect(self.profiles_finished)
            create_profile.error.connect(self.profiles_error)
            create_profile.progress.connect(self.profiles_progress)
            thread.started.connect(create_profile.create)
            thread.start(QThread.LowestPriority)
            self.thread = thread
            self.create_profile = create_profile
            self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        except:
            QApplication.restoreOverrideCursor()
            ex = u'{0}'.format(traceback.format_exc())
            msg = 'Unexpected ERROR:\n\n{0}'.format(ex[:2000])
            QMessageBox.critical(self.iface.mainWindow(), "VoGIS-Profiltool", msg)


    def profiles_finished(self, profiles, intersections):
        QApplication.restoreOverrideCursor()
        self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
        #self.create_profile.deleteLater()
        self.thread.quit()
        self.thread.wait()
        #self.thread.deleteLater()

        #QGIS 2.0 http://gis.stackexchange.com/a/58754 http://gis.stackexchange.com/a/57090
        self.iface.mainWindow().statusBar().showMessage('VoGIS-Profiltool, {0} Profile'.format(len(profiles)))
        QgsMessageLog.logMessage(u'Profile Count: {0}'.format(len(profiles)), 'VoGis')

        if len(profiles) < 1:
            QApplication.restoreOverrideCursor()
            QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", QApplication.translate('code', 'Es konnten keine Profile erstellt werden.', None, QApplication.UnicodeUTF8))
            return

        dlg = VoGISProfilToolPlotDialog(self.iface, self.settings, profiles, intersections)
        dlg.show()
        #result = self.dlg.exec_()
        dlg.exec_()


    def profiles_error(self, exception_string):
        QApplication.restoreOverrideCursor()
        QgsMessageLog.logMessage(u'Error during profile creation: {0}'.format(exception_string), 'VoGis')
        QMessageBox.critical(self.iface.mainWindow(), "VoGIS-Profiltool", exception_string)


    def profiles_progress(self, msg):
        self.iface.mainWindow().statusBar().showMessage(msg)
        self.ui.IDC_lblCreateStatus.setText(msg)
        #QgsMessageLog.logMessage(msg, 'VoGis')
        QApplication.processEvents()


    def reject(self):
        if not self.thread is None:
            if self.thread.isRunning():
                self.create_profile.abort()
                return

        self.rubberband.reset(self.polygon)
        QDialog.reject(self)


    def selectVisibleRasters(self):
        self.refreshRasterList()
        self.selectingVisibleRasters = True
        extCanvas = self.iface.mapCanvas().extent()
        #alle raster in den einstellunge deselektieren
        for r in self.settings.mapData.rasters.rasters():
            r.selected = False
        #alle raster in der ListView deselektieren
        for idx in xrange(self.ui.IDC_listRasters.count()):
            item = self.ui.IDC_listRasters.item(idx)
            item.setCheckState(Qt.Unchecked)
        #Raster im Extent selektieren
        for idx in xrange(self.ui.IDC_listRasters.count()):
            item = self.ui.IDC_listRasters.item(idx)
            if QGis.QGIS_VERSION_INT < 10900:
                raster = item.data(Qt.UserRole).toPyObject()
            else:
                raster = item.data(Qt.UserRole)
            for r in self.settings.mapData.rasters.rasters():
                if extCanvas.intersects(r.grid.extent()):
                    if r.id == raster.id:
                        r.selected = True
                        item.setCheckState(Qt.Checked)
        self.selectingVisibleRasters = False


    def lineLayerChanged(self, idx):
        if self.ui.IDC_rbShapeLine.isChecked() is False:
            self.ui.IDC_rbShapeLine.setChecked(True)
        if QGis.QGIS_VERSION_INT < 10900:
            lineLyr = (self.ui.IDC_cbLineLayers.itemData(self.ui.IDC_cbLineLayers.currentIndex()).toPyObject())
        else:
            lineLyr = (self.ui.IDC_cbLineLayers.itemData(self.ui.IDC_cbLineLayers.currentIndex()))
        lyr = lineLyr.line
        #QgsMessageLog.logMessage('{0}'.format(lyr.selectedFeatureCount()), 'VoGis')
        #QgsMessageLog.logMessage('{0}'.format(dir(lyr)), 'VoGis')
        if hasattr(lyr, 'selectedFeatureCount'):
            if(lyr.selectedFeatureCount() < 1):
                self.ui.IDC_chkOnlySelectedFeatures.setChecked(False)
            else:
                self.ui.IDC_chkOnlySelectedFeatures.setChecked(True)


    def valueChangedEquiDistance(self, val):
        if self.ui.IDC_rbEquiDistance.isChecked() is False:
            self.ui.IDC_rbEquiDistance.setChecked(True)


    def valueChangedVertexCount(self, val):
        if self.ui.IDC_rbVertexCount.isChecked() is False:
            self.ui.IDC_rbVertexCount.setChecked(True)


    def lvRasterItemChanged(self, item):
        if self.selectingVisibleRasters is True:
            return
        if item.checkState() == Qt.Checked:
            selected = True
        if item.checkState() == Qt.Unchecked:
            selected = False

        item_data = item.data(Qt.UserRole)
        if QGis.QGIS_VERSION_INT < 10900:
            raster_lyr = item_data.toPyObject()
        else:
            raster_lyr = item_data
        self.settings.mapData.rasters.getById(raster_lyr.id).selected = selected


    def lvPolygonItemChanged(self, item):
        if item.checkState() == Qt.Checked:
            selected = True
        if item.checkState() == Qt.Unchecked:
            selected = False

        item_data = item.data(Qt.UserRole)
        if QGis.QGIS_VERSION_INT < 10900:
            poly_lyr = item_data.toPyObject()
        else:
            poly_lyr = item_data
        self.settings.mapData.polygons.getById(poly_lyr.id).selected = selected


    def refreshRasterList(self):
        legend = self.iface.legendInterface()
        avail_lyrs = legend.layers()
        raster_coll = RasterCollection()

        for lyr in avail_lyrs:
            if legend.isLayerVisible(lyr):
                lyr_type = lyr.type()
                lyr_name = unicodedata.normalize('NFKD', unicode(lyr.name())).encode('ascii', 'ignore')
                if lyr_type == 1:
                    if lyr.bandCount() < 2:
                        new_raster = Raster(lyr.id(), lyr_name, lyr)
                        raster_coll.addRaster(new_raster)

        self.settings.mapData.rasters = raster_coll
        self.__addRastersToGui()

    def __addRastersToGui(self):
        self.ui.IDC_listRasters.clear()
        check = Qt.Unchecked
        if self.settings.mapData.rasters.count() == 1:
            check = Qt.Checked
            self.settings.mapData.rasters.rasters()[0].selected = True

        for raster_lyr in self.settings.mapData.rasters.rasters():
            item = QListWidgetItem(raster_lyr.name)
            item.setData(Qt.UserRole, raster_lyr)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(check)
            self.ui.IDC_listRasters.addItem(item)


    def __addPolygonsToGui(self):
        self.ui.IDC_listPolygons.clear()
        check = Qt.Unchecked
        for poly_lyr in self.settings.mapData.polygons.polygons():
            item = QListWidgetItem(poly_lyr.name)
            item.setData(Qt.UserRole, poly_lyr)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(check)
            self.ui.IDC_listPolygons.addItem(item)


    def drawLine(self):
        if self.ui.IDC_rbDigi.isChecked() is False:
            self.ui.IDC_rbDigi.setChecked(True)
        self.dblckltemp = None
        self.rubberband.reset(self.polygon)
        self.__cleanDigi()
        self.__activateDigiTool()
        self.canvas.setMapTool(self.tool)


    def __createDigiFeature(self, pnts):
        u = Util(self.iface)
        f = u.createQgLineFeature(pnts)
        self.settings.mapData.customLine = f


    def __lineFinished(self, position):
        mapPos = self.canvas.getCoordinateTransform().toMapCoordinates(position["x"], position["y"])
        newPoint = QgsPoint(mapPos.x(), mapPos.y())
        self.pointsToDraw.append(newPoint)
        #launch analyses
        self.iface.mainWindow().statusBar().showMessage(str(self.pointsToDraw))
        if len(self.pointsToDraw) < 2:
            self.__cleanDigi()
            self.pointsToDraw = []
            self.dblclktemp = newPoint
            self.drawnLine = None
            QMessageBox.warning(self, "VoGIS-Profiltool", QApplication.translate('code', 'Profillinie digitalisieren abgebrochen!', None, QApplication.UnicodeUTF8))
        self.drawnLine = self.__createDigiFeature(self.pointsToDraw)
        self.__cleanDigi()

        self.pointsToDraw = []
        self.dblclktemp = newPoint

    def __cleanDigi(self):
        self.pointsToDraw = []
        self.canvas.unsetMapTool(self.tool)
        self.canvas.setMapTool(self.savedTool)

    def __activateDigiTool(self):
        QObject.connect(self.tool, SIGNAL("moved"), self.__moved)
        QObject.connect(self.tool, SIGNAL("rightClicked"), self.__rightClicked)
        QObject.connect(self.tool, SIGNAL("leftClicked"), self.__leftClicked)
        QObject.connect(self.tool, SIGNAL("doubleClicked"), self.__doubleClicked)
        QObject.connect(self.tool, SIGNAL("deactivate"), self.__deactivateDigiTool)

    def __deactivateDigiTool(self):
        QObject.disconnect(self.tool, SIGNAL("moved"), self.__moved)
        QObject.disconnect(self.tool, SIGNAL("leftClicked"), self.__leftClicked)
        QObject.disconnect(self.tool, SIGNAL("rightClicked"), self.__rightClicked)
        QObject.disconnect(self.tool, SIGNAL("doubleClicked"), self.__doubleClicked)
        if QGis.QGIS_VERSION_INT < 10900:
            self.iface.mainWindow().statusBar().showMessage(QString(""))
        else:
            self.iface.mainWindow().statusBar().showMessage('')

    def __moved(self, position):
        if len(self.pointsToDraw) > 0:
            mapPos = self.canvas.getCoordinateTransform().toMapCoordinates(position["x"], position["y"])
            self.rubberband.reset(self.polygon)
            newPnt = QgsPoint(mapPos.x(), mapPos.y())
            if QGis.QGIS_VERSION_INT < 10900:
                for i in range(0, len(self.pointsToDraw)):
                    self.rubberband.addPoint(self.pointsToDraw[i])
                self.rubberband.addPoint(newPnt)
            else:
                pnts = self.pointsToDraw + [newPnt]
                self.rubberband.setToGeometry(QgsGeometry.fromPolyline(pnts),None)


    def __rightClicked(self, position):
        self.__lineFinished(position)

    def __leftClicked(self, position):
        mapPos = self.canvas.getCoordinateTransform().toMapCoordinates(position["x"], position["y"])
        newPoint = QgsPoint(mapPos.x(), mapPos.y())
        #if self.selectionmethod == 0:
        if newPoint == self.dblclktemp:
            self.dblclktemp = None
            return
        else:
            if len(self.pointsToDraw) == 0:
                self.rubberband.reset(self.polygon)
            self.pointsToDraw.append(newPoint)

    def __doubleClicked(self, position):
        pass

    #not in use right now
    def __lineCancel(self):
        pass

    def __getSettingsFromGui(self):
        self.settings.linesExplode = (self.ui.IDC_chkLinesExplode.checkState() == Qt.Checked)
        self.settings.linesMerge = (self.ui.IDC_chkLinesMerge.checkState() == Qt.Checked)
        self.settings.onlySelectedFeatures = (self.ui.IDC_chkOnlySelectedFeatures.checkState() == Qt.Checked)
        self.settings.equiDistance = self.ui.IDC_dblspinDistance.value()
        self.settings.vertexCnt = self.ui.IDC_dblspinVertexCnt.value()
        #self.settings.createHekto = (self.ui.IDC_chkCreateHekto.checkState() == Qt.Checked)
        self.settings.nodesAndVertices = (self.ui.IDC_chkNodesAndVertices.checkState() == Qt.Checked)

        if QGis.QGIS_VERSION_INT < 10900:
            self.settings.mapData.selectedLineLyr = (self.ui.IDC_cbLineLayers.itemData(
                                                     self.ui.IDC_cbLineLayers.currentIndex()
                                                     ).toPyObject()
                                                     )
        else:
            self.settings.mapData.selectedLineLyr = (self.ui.IDC_cbLineLayers.itemData(self.ui.IDC_cbLineLayers.currentIndex()))

        if self.settings.onlySelectedFeatures is True and self.settings.mapData.selectedLineLyr.line.selectedFeatureCount() < 1:
            QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", QApplication.translate('code', u'Der gewählte Layer hat keine selektierten Elemente.', None, QApplication.UnicodeUTF8))
            return False

        if self.ui.IDC_rbDigi.isChecked():
            self.settings.modeLine = enumModeLine.customLine
        elif self.ui.IDC_rbShapeLine.isChecked():
            self.settings.modeLine = enumModeLine.line
        else:
            #self.ui.IDC_rbStraigthLine
            self.settings.modeLine = enumModeLine.straightLine

        if self.ui.IDC_rbEquiDistance.isChecked():
            self.settings.modeVertices = enumModeVertices.equiDistant
        else:
            self.settings.modeVertices = enumModeVertices.vertexCnt

        if self.ui.IDC_rbStraigthLine.isChecked():
            ut = Util(self.iface)
            if ut.isFloat(self.ui.IDC_tbFromX.text(), QApplication.translate('code', 'Rechtswert von', None, QApplication.UnicodeUTF8)) is False:
                return False
            else:
                fromX = float(self.ui.IDC_tbFromX.text())
            if ut.isFloat(self.ui.IDC_tbFromY.text(), QApplication.translate('code', 'Hochwert von', None, QApplication.UnicodeUTF8)) is False:
                return False
            else:
                fromY = float(self.ui.IDC_tbFromY.text())
            if ut.isFloat(self.ui.IDC_tbToX.text(), QApplication.translate('code', 'Rechtswert nach', None, QApplication.UnicodeUTF8)) is False:
                return False
            else:
                toX = float(self.ui.IDC_tbToX.text())
            if ut.isFloat(self.ui.IDC_tbToY.text(), QApplication.translate('code', 'Hochwert nach', None, QApplication.UnicodeUTF8)) is False:
                return False
            else:
                toY = float(self.ui.IDC_tbToY.text())

            fromPnt = QgsPoint(fromX, fromY)
            toPnt = QgsPoint(toX, toY)

            self.settings.mapData.customLine = ut.createQgLineFeature([fromPnt, toPnt])

        return True
Example #32
0
class QuickFinder(QObject):

    name = "&Quick Finder"
    actions = None
    toolbar = None
    finders = {}

    loadingIcon = None

    def __init__(self, iface):
        QObject.__init__(self)
        self.iface = iface
        self.actions = {}
        self.finders = {}
        self.settings = MySettings()
        self.rubber = None

        self._init_finders()

        self.iface.projectRead.connect(self._reload_finders)
        self.iface.newProjectCreated.connect(self._reload_finders)

        # translation environment
        self.plugin_dir = os.path.dirname(__file__)
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, 'i18n',
                                  'quickfinder_{0}.qm'.format(locale))
        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)
            QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        self.actions['showSettings'] = QAction(
            QIcon(":/plugins/quickfinder/icons/settings.svg"),
            self.tr(u"&Settings"), self.iface.mainWindow())
        self.actions['showSettings'].triggered.connect(self.show_settings)
        self.iface.addPluginToMenu(self.name, self.actions['showSettings'])
        self._init_toolbar()

        # set selection area sytle and color
        self.rubber = QgsRubberBand(self.iface.mapCanvas())
        self.rubber.setColor(QColor(255, 255, 50, 200))
        self.rubber.setIcon(self.rubber.ICON_CIRCLE)
        self.rubber.setIconSize(15)
        self.rubber.setWidth(4)
        self.rubber.setBrushStyle(Qt.NoBrush)

    def unload(self):
        """ Unload plugin """
        for key in list(self.finders.keys()):
            self.finders[key].close()
        for action in self.actions.values():
            self.iface.removePluginMenu(self.name, action)
        if self.toolbar:
            del self.toolbar
        if self.rubber:
            self.iface.mapCanvas().scene().removeItem(self.rubber)
            del self.rubber

    def _init_toolbar(self):
        """setup the plugin toolbar."""
        self.toolbar = self.iface.addToolBar(self.name)
        self.toolbar.setObjectName('mQuickFinderToolBar')
        self.search_action = QAction(
            QIcon(":/plugins/quickfinder/icons/magnifier13.svg"),
            self.tr("Search"), self.toolbar)
        self.stop_action = QAction(
            QIcon(":/plugins/quickfinder/icons/wrong2.svg"), self.tr("Cancel"),
            self.toolbar)
        self.finder_box = FinderBox(self.finders, self.iface, self.toolbar)
        self.finder_box.search_started.connect(self.search_started)
        self.finder_box.search_finished.connect(self.search_finished)

        self.finder_box_action = self.toolbar.addWidget(self.finder_box)
        self.finder_box_action.setVisible(True)
        self.search_action.triggered.connect(self.finder_box.search)
        self.toolbar.addAction(self.search_action)
        self.stop_action.setVisible(False)
        self.stop_action.triggered.connect(self.finder_box.stop)
        self.toolbar.addAction(self.stop_action)
        self.toolbar.setVisible(True)

    def _init_finders(self):
        #        self.finders['geomapfish'] = GeomapfishFinder(self)
        self.finders['osm'] = OsmFinder(self)
        self.finders['project'] = ProjectFinder(self)
        self.finders['amap'] = AmapFinder(self)
        #        self.finders['postgis'] = PostgisFinder(self)
        for key in list(self.finders.keys()):
            self.finders[key].message.connect(self.display_message)
        self.refresh_project()

    def _reload_finders(self):
        for key in list(self.finders.keys()):
            self.finders[key].close()
            self.finders[key].reload()
        self.refresh_project()

    @pyqtSlot(str, Qgis.MessageLevel)
    def display_message(self, message, level):
        self.iface.messageBar().pushMessage("QuickFinder", message, level)

    def show_settings(self):
        #        self.win = ConfigurationDialog()
        #        self.win.show()
        #ConfigurationDialog().show()
        if ConfigurationDialog().exec_():
            self._reload_finders()

    def search_started(self):
        self.search_action.setVisible(False)
        self.stop_action.setVisible(True)

    def search_finished(self):
        self.search_action.setVisible(True)
        self.stop_action.setVisible(False)

    def refresh_project(self):
        if not self.finders['project'].activated:
            return
        if not self.settings.value("refreshAuto"):
            return
        n_days = self.settings.value("refreshDelay")
        # do not ask more ofen than 3 days
        ask_limit = min(3, n_days)
        recently_asked = self.settings.value(
            "refreshLastAsked") >= n_days_ago_iso_date(ask_limit)
        if recently_asked:
            return
        thresh_date = n_days_ago_iso_date(n_days)
        uptodate = True
        for search in list(self.finders['project'].searches.values()):
            if search.dateEvaluated <= thresh_date:
                uptodate = False
                break
        if uptodate:
            return
        self.settings.setValue("refreshLastAsked", n_days_ago_iso_date(0))
        ret = QMessageBox(
            QMessageBox.Warning, "Quick Finder",
            QCoreApplication.translate(
                "Auto Refresh",
                "Some searches are outdated. Do you want to refresh them ?"),
            QMessageBox.Cancel | QMessageBox.Yes).exec_()
        if ret == QMessageBox.Yes:
            RefreshDialog(self.finders['project']).exec_()
Example #33
0
class SelectFeatureTool(QgsMapToolEmitPoint):
    foundFeature = pyqtSignal(QgsFeature, object, str)

    def __init__(self, canvas, layer, column, bindto, radius):
        QgsMapToolEmitPoint.__init__(self, canvas)
        self.layer = layer
        self.column = column
        self.bindto = bindto
        self.canvas = canvas
        self.bindto = bindto
        self.searchradius = radius
        self.canvasClicked.connect(self.findFeature)
        self.canvas.setMapTool(self)
        self.band = QgsRubberBand(self.canvas)
        self.band.setColor(Qt.blue)
        self.band.setWidth(3)
        self.rect = QgsRectangle()
        self.cursor = QCursor(
            QPixmap([
                "16 16 3 1", "      c None", ".     c #32CD32",
                "+     c #32CD32", "                ", "       +.+      ",
                "      ++.++     ", "     +.....+    ", "    +.     .+   ",
                "   +.   .   .+  ", "  +.    .    .+ ", " ++.    .    .++",
                " ... ...+... ...", " ++.    .    .++", "  +.    .    .+ ",
                "   +.   .   .+  ", "   ++.     .+   ", "    ++.....+    ",
                "      ++.++     ", "       +.+      "
            ]))

    def findFeature(self, point, button):
        searchRadius = QgsTolerance.toleranceInMapUnits( self.searchradius, self.layer, \
                                                         self.canvas.mapRenderer(), QgsTolerance.Pixels)

        self.rect.setXMinimum(point.x() - searchRadius)
        self.rect.setXMaximum(point.x() + searchRadius)
        self.rect.setYMinimum(point.y() - searchRadius)
        self.rect.setYMaximum(point.y() + searchRadius)

        self.layer.select(self.layer.pendingAllAttributesList(), self.rect,
                          True, True)
        feature = QgsFeature()
        self.layer.nextFeature(feature)
        try:
            index = self.layer.fieldNameIndex(self.column)
            value = feature.attributeMap()[index]
            self.foundFeature.emit(feature, value, self.bindto)
        except KeyError:
            return

    def canvasMoveEvent(self, event):
        point = self.toMapCoordinates(event.pos())
        searchRadius = QgsTolerance.toleranceInMapUnits( self.searchradius, self.layer, \
                                                         self.canvas.mapRenderer(), QgsTolerance.Pixels)

        self.rect.setXMinimum(point.x() - searchRadius)
        self.rect.setXMaximum(point.x() + searchRadius)
        self.rect.setYMinimum(point.y() - searchRadius)
        self.rect.setYMaximum(point.y() + searchRadius)

        self.layer.select([], self.rect, True, True)
        feature = QgsFeature()
        self.layer.nextFeature(feature)

        if not feature.isValid():
            log("Not a vaild feature")
            return

        self.band.setToGeometry(feature.geometry(), None)

    def setActive(self):
        self.canvas.setMapTool(self)
        self.canvas.setCursor(self.cursor)

    def deactivate(self):
        self.band.hide()
Example #34
0
class InterpolateTool(QgsMapTool):
    def __init__(self, iface):
        """
        Constructor
        :param iface: interface
        """
        QgsMapTool.__init__(self, iface.mapCanvas())
        self.__iface = iface
        self.__canvas = iface.mapCanvas()
        self.__icon_path = ':/plugins/VDLTools/icons/interpolate_icon.png'
        self.__text = QCoreApplication.translate(
            "VDLTools",
            "Interpolate the elevation of a vertex and a point in the middle of a line"
        )
        # self.__oldTool = None
        self.__layer = None
        self.setCursor(Qt.ArrowCursor)
        self.__isEditing = False
        self.__lastFeatureId = None
        self.__layerList = None
        self.__lastLayer = None
        self.__confDlg = None
        self.__mapPoint = None
        self.__rubber = None
        self.__counter = 0
        self.__ownSettings = None
        self.__selectedFeature = None
        self.__linesConfig = None
        self.__findVertex = 0

    def icon_path(self):
        """
        To get the icon path
        :return: icon path
        """
        return self.__icon_path

    def text(self):
        """
        To get the menu text
        :return: menu text
        """
        return self.__text

    def setTool(self):
        """
        To set the current tool as this one
        """
        # self.__oldTool = self.__canvas.mapTool()
        self.__canvas.setMapTool(self)

    def setOwnSettings(self, settings):
        """
        To set the settings
        :param settings: income settings
        """
        self.__ownSettings = settings

    def activate(self):
        """
        When the action is selected
        """
        QgsMapTool.activate(self)
        self.__updateList()
        self.__rubber = QgsRubberBand(self.__canvas, QGis.Point)
        color = QColor("red")
        color.setAlphaF(0.78)
        self.__rubber.setColor(color)
        self.__rubber.setIcon(4)
        self.__rubber.setIconSize(20)
        self.__canvas.layersChanged.connect(self.__updateList)
        self.__canvas.scaleChanged.connect(self.__updateList)
        QgsProject.instance().snapSettingsChanged.connect(self.__updateList)

    def deactivate(self):
        """
        When the action is deselected
        """
        self.__rubber.reset()
        if self.__lastLayer is not None:
            self.__lastLayer.removeSelection()
        self.__canvas.layersChanged.disconnect(self.__updateList)
        self.__canvas.scaleChanged.disconnect(self.__updateList)
        QgsProject.instance().snapSettingsChanged.disconnect(self.__updateList)
        QgsMapTool.deactivate(self)

    def startEditing(self):
        """
        To set the action as enable, as the layer is editable
        """
        self.action().setEnabled(True)
        self.__layer.editingStarted.disconnect(self.startEditing)
        self.__layer.editingStopped.connect(self.stopEditing)

    def stopEditing(self):
        """
        To set the action as disable, as the layer is not editable
        """
        self.action().setEnabled(False)
        self.__layer.editingStopped.disconnect(self.stopEditing)
        self.__layer.editingStarted.connect(self.startEditing)
        if self.__canvas.mapTool == self:
            self.__iface.actionPan().trigger()
        #     self.__canvas.setMapTool(self.__oldTool)

    def removeLayer(self):
        """
        To remove the current working layer
        """
        if self.__layer is not None:
            if self.__layer.isEditable():
                self.__layer.editingStopped.disconnect(self.stopEditing)
            else:
                self.__layer.editingStarted.disconnect(self.startEditing)
            self.__layer = None

    def setEnable(self, layer):
        """
        To check if we can enable the action for the selected layer
        :param layer: selected layer
        """
        if layer is not None \
                and isinstance(layer, QgsVectorLayer) \
                and layer.geometryType() == QGis.Point:

            if layer == self.__layer:
                return

            if self.__layer is not None:
                if self.__layer.isEditable():
                    self.__layer.editingStopped.disconnect(self.stopEditing)
                else:
                    self.__layer.editingStarted.disconnect(self.startEditing)
            self.__layer = layer
            if self.__layer.isEditable():
                self.action().setEnabled(True)
                self.__layer.editingStopped.connect(self.stopEditing)
            else:
                self.action().setEnabled(False)
                self.__layer.editingStarted.connect(self.startEditing)
                if self.__canvas.mapTool == self:
                    self.__iface.actionPan().trigger()
                #    self.__canvas.setMapTool(self.__oldTool)
            return
        self.action().setEnabled(False)
        self.removeLayer()

    def __updateList(self):
        """
        To update the line layers list that we can use for interpolation
        """
        self.__layerList = []
        legend = self.__iface.legendInterface()
        scale = self.__iface.mapCanvas().scale()
        for layer in self.__iface.mapCanvas().layers():
            noUse, enabled, snappingType, unitType, tolerance, avoidIntersection = \
                QgsProject.instance().snapSettingsForLayer(layer.id())
            if isinstance(layer, QgsVectorLayer) and layer.hasGeometryType() \
                    and layer.geometryType() == QGis.Line:
                if not layer.hasScaleBasedVisibility(
                ) or layer.minimumScale() < scale <= layer.maximumScale():
                    if legend.isLayerVisible(layer) and enabled:
                        layerConfig = QgsSnappingUtils.LayerConfig(
                            layer, QgsPointLocator.Vertex, tolerance, unitType)
                        self.__layerList.append(layerConfig)

        if self.__ownSettings and self.__ownSettings.linesLayer():
            noUse, enabled, snappingType, unitType, tolerance, avoidIntersection = \
                QgsProject.instance().snapSettingsForLayer(self.__ownSettings.linesLayer().id())
            self.__linesConfig = QgsSnappingUtils.LayerConfig(
                self.__ownSettings.linesLayer(), QgsPointLocator.Vertex,
                tolerance, unitType)

    def canvasMoveEvent(self, event):
        """
        When the mouse is moved
        :param event: mouse event
        """
        if not self.__isEditing and not self.__findVertex and self.__layerList is not None:
            f_l = Finder.findClosestFeatureLayersAt(event.mapPoint(),
                                                    self.__layerList, self)

            if f_l is not None and self.__lastFeatureId != f_l[0].id():
                f = f_l[0]
                self.__lastFeatureId = f.id()
                if self.__lastLayer is not None:
                    self.__lastLayer.removeSelection()
                self.__lastLayer = f_l[1]
                self.__lastLayer.setSelectedFeatures([f.id()])
            if f_l is None and self.__lastLayer is not None:
                self.__lastLayer.removeSelection()
                # self.__rubber.reset()
                self.__lastFeatureId = None
        elif self.__findVertex:
            self.__rubber.reset()
            match = Finder.snap(event.mapPoint(), self.__canvas, True)
            if match.hasVertex() or match.hasEdge():
                point = match.point()
                if match.hasVertex():
                    if match.layer() and self.__selectedFeature.id(
                    ) == match.featureId():
                        self.__rubber.setIcon(4)
                        self.__rubber.setToGeometry(
                            QgsGeometry().fromPoint(point), None)
                    else:
                        intersection = Finder.snapCurvedIntersections(
                            match.point(), self.__canvas, self, True,
                            self.__selectedFeature.id())
                        if intersection:
                            self.__rubber.setIcon(1)
                            self.__rubber.setToGeometry(
                                QgsGeometry().fromPoint(intersection), None)
                if match.hasEdge():
                    intersection = Finder.snapCurvedIntersections(
                        match.point(), self.__canvas, self, True,
                        self.__selectedFeature.id())
                    if intersection:
                        self.__rubber.setIcon(1)
                        self.__rubber.setToGeometry(
                            QgsGeometry().fromPoint(intersection), None)
                    elif self.__selectedFeature.id() == match.featureId():
                        self.__rubber.setIcon(3)
                        self.__rubber.setToGeometry(
                            QgsGeometry().fromPoint(point), None)

    def canvasReleaseEvent(self, event):
        """
        When the mouse is clicked
        :param event: mouse event
        """
        if self.__lastLayer is not None and not self.__findVertex:
            found_features = self.__lastLayer.selectedFeatures()
            if len(found_features) > 0:
                if len(found_features) < 1:
                    self.__iface.messageBar().pushMessage(
                        QCoreApplication.translate("VDLTools",
                                                   "One feature at a time"),
                        level=QgsMessageBar.INFO)
                    return
                self.__selectedFeature = found_features[0]
                self.__findVertex = 1
        elif self.__findVertex:
            self.__rubber.reset()
            match = Finder.snap(event.mapPoint(), self.__canvas, True)
            if match.hasVertex() or match.hasEdge():
                point = match.point()
                ok = False
                if match.hasVertex():
                    if match.layer() and self.__selectedFeature.id(
                    ) == match.featureId():
                        ok = True
                    else:
                        intersection = Finder.snapCurvedIntersections(
                            match.point(), self.__canvas, self, True,
                            self.__selectedFeature.id())
                        if intersection:
                            point = intersection
                            ok = True
                if match.hasEdge():
                    intersection = Finder.snapCurvedIntersections(
                        match.point(), self.__canvas, self, True,
                        self.__selectedFeature.id())
                    if intersection:
                        point = intersection
                        ok = True
                    elif self.__selectedFeature.id() == match.featureId():
                        ok = True
                if ok:
                    self.__isEditing = True
                    self.__findVertex = 0
                    self.__mapPoint = point
                    if not match.hasVertex():
                        self.__confDlg = InterpolateConfirmDialog()
                        if self.__lastLayer.isEditable() is True:
                            self.__confDlg.setMainLabel(
                                QCoreApplication.translate(
                                    "VDLTools", "What do you want to do ?"))
                            self.__confDlg.setAllLabel(
                                QCoreApplication.translate(
                                    "VDLTools", "Create point and new vertex"))
                            self.__confDlg.setVtLabel(
                                QCoreApplication.translate(
                                    "VDLTools", "Create only the vertex"))
                        self.__confDlg.okButton().clicked.connect(
                            self.__onConfirmOk)
                        self.__confDlg.cancelButton().clicked.connect(
                            self.__onConfirmCancel)
                        self.__confDlg.show()
                    else:
                        self.__ok(False, True)

    def __onConfirmCancel(self):
        """
        When the Cancel button in Interpolate Confirm Dialog is pushed
        """
        self.__confDlg.close()
        self.__lastLayer.removeSelection()
        self.__rubber.reset()
        self.__lastFeatureId = None
        self.__isEditing = False

    def __onConfirmOk(self):

        id = self.__confDlg.getCheckedId()
        self.__confDlg.close()

        withVertex = True
        withPoint = True
        if id == 1:
            withVertex = False
        else:
            if self.__lastLayer.isEditable() is False:
                self.__lastLayer.startEditing()
        if id == 2:
            withPoint = False

        self.__ok(withVertex, withPoint)

    def __ok(self, withVertex, withPoint):
        line_v2, curved = GeometryV2.asLineV2(
            self.__selectedFeature.geometry())
        vertex_v2 = QgsPointV2()
        vertex_id = QgsVertexId()
        line_v2.closestSegment(QgsPointV2(self.__mapPoint), vertex_v2,
                               vertex_id, 0)

        x0 = line_v2.xAt(vertex_id.vertex - 1)
        y0 = line_v2.yAt(vertex_id.vertex - 1)
        d0 = Finder.sqrDistForCoords(x0, vertex_v2.x(), y0, vertex_v2.y())
        x1 = line_v2.xAt(vertex_id.vertex)
        y1 = line_v2.yAt(vertex_id.vertex)
        d1 = Finder.sqrDistForCoords(x1, vertex_v2.x(), y1, vertex_v2.y())
        z0 = line_v2.zAt(vertex_id.vertex - 1)
        z1 = line_v2.zAt(vertex_id.vertex)
        vertex_v2.addZValue((d0 * z1 + d1 * z0) / (d0 + d1))

        if withPoint:
            pt_feat = QgsFeature(self.__layer.pendingFields())
            pt_feat.setGeometry(QgsGeometry(vertex_v2))

            if self.__layer.editFormConfig().suppress(
            ) == QgsEditFormConfig.SuppressOn:
                self.__layer.addFeature(pt_feat)
            else:
                self.__iface.openFeatureForm(self.__layer, pt_feat)

        if withVertex:
            line_v2.insertVertex(vertex_id, vertex_v2)
            self.__lastLayer.changeGeometry(self.__selectedFeature.id(),
                                            QgsGeometry(line_v2))
        self.__lastLayer.removeSelection()
        self.__rubber.reset()
        self.__lastFeatureId = None
        self.__selectedFeature = None
        self.__isEditing = False

    def __snapToIntersection(self, mapPoint, selectedFeature):
        """
        To check is we can snap a close intersection
        :param mapPoint: the point to check
        :param selectedFeature: the feature that can intersect another one
        :return: an intersection QgsPointV2 or none
        """
        f = Finder.findClosestFeatureAt(mapPoint, self.__linesConfig, self)
        if f is None:
            return None
        intersect = Finder.intersect(selectedFeature.geometry(), f.geometry(),
                                     mapPoint)
        if intersect is not None:
            return QgsPointV2(intersect)
        else:
            return None
class LatLonTools:
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.crossRb = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry)
        self.crossRb.setColor(Qt.red)

    def initGui(self):
        '''Initialize Lot Lon Tools GUI.'''
        # Initialize the Settings Dialog box
        self.settingsDialog = SettingsWidget(self, self.iface, self.iface.mainWindow())
        self.mapTool = CopyLatLonTool(self.settingsDialog, self.iface)
        self.showMapTool = ShowOnMapTool(self.settingsDialog, self.iface)
        self.toMGRSDialog = ToMGRSWidget(self.iface, self.iface.mainWindow())
        self.MGRStoLayerDialog = MGRStoLayerWidget(self.iface, self.iface.mainWindow())
        
        # Add Interface for Coordinate Capturing
        icon = QIcon(os.path.dirname(__file__) + "/images/copyicon.png")
        self.copyAction = QAction(icon, "Copy Latitude, Longitude", self.iface.mainWindow())
        self.copyAction.triggered.connect(self.startCapture)
        self.copyAction.setCheckable(True)
        self.iface.addToolBarIcon(self.copyAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.copyAction)

        # Add Interface for Zoom to Coordinate
        icon = QIcon(os.path.dirname(__file__) + "/images/zoomicon.png")
        self.zoomToAction = QAction(icon, "Zoom To Latitude, Longitude", self.iface.mainWindow())
        self.zoomToAction.triggered.connect(self.showZoomToDialog)
        self.iface.addPluginToMenu('Lat Lon Tools', self.zoomToAction)
        self.canvas.mapToolSet.connect(self.unsetTool)

        self.zoomToDialog = ZoomToLatLon(self, self.iface, self.iface.mainWindow())
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.zoomToDialog)
        self.zoomToDialog.hide()
        
        # Add Interface for External Map
        icon = QIcon(os.path.dirname(__file__) + "/images/mapicon.png")
        self.externMapAction = QAction(icon, "Show in External Map", self.iface.mainWindow())
        self.externMapAction.triggered.connect(self.setShowMapTool)
        self.externMapAction.setCheckable(True)
        self.iface.addToolBarIcon(self.externMapAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.externMapAction)
        
        # Add Interface for Multi point zoom
        icon = QIcon(os.path.dirname(__file__) + '/images/multizoom.png')
        self.multiZoomToAction = QAction(icon, "Multi-location Zoom", self.iface.mainWindow())
        self.multiZoomToAction.triggered.connect(self.multiZoomTo)
        self.iface.addPluginToMenu('Lat Lon Tools', self.multiZoomToAction)

        self.multiZoomDialog = MultiZoomWidget(self, self.settingsDialog, self.iface.mainWindow())
        self.multiZoomDialog.hide()
        self.multiZoomDialog.setFloating(True)
        
        # Add To MGRS conversion
        icon = QIcon(os.path.dirname(__file__) + '/images/mgrs2point.png')
        icon2 = QIcon(os.path.dirname(__file__) + '/images/point2mgrs.png')
        menu = QMenu()
        menu.addAction(icon, "MGRS to Geometry", self.MGRStoLayer)
        menu.addAction(icon2, "Geometry to MGRS", self.toMGRS)
        self.toMGRSAction = QAction(icon2, "MGRS Conversions", self.iface.mainWindow())
        self.toMGRSAction.setMenu(menu)
        self.iface.addPluginToMenu('Lat Lon Tools', self.toMGRSAction)
        
        # Initialize the Settings Dialog Box
        settingsicon = QIcon(os.path.dirname(__file__) + '/images/settings.png')
        self.settingsAction = QAction(settingsicon, "Settings", self.iface.mainWindow())
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToMenu('Lat Lon Tools', self.settingsAction)
        
        # Help
        helpicon = QIcon(os.path.dirname(__file__) + '/images/help.png')
        self.helpAction = QAction(helpicon, "Help", self.iface.mainWindow())
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToMenu('Lat Lon Tools', self.helpAction)
                
    def unsetTool(self, tool):
        '''Uncheck the Copy Lat Lon tool'''
        try:
            if not isinstance(tool, CopyLatLonTool):
                self.copyAction.setChecked(False)
                self.multiZoomDialog.stopCapture()
                self.mapTool.capture4326 = False
            if not isinstance(tool, ShowOnMapTool):
                self.externMapAction.setChecked(False)
        except:
            pass

    def unload(self):
        '''Unload LatLonTools from the QGIS interface'''
        self.zoomToDialog.removeMarker()
        self.multiZoomDialog.removeMarkers()
        self.canvas.unsetMapTool(self.mapTool)
        self.canvas.unsetMapTool(self.showMapTool)
        self.iface.removePluginMenu('Lat Lon Tools', self.copyAction)
        self.iface.removeToolBarIcon(self.copyAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.externMapAction)
        self.iface.removeToolBarIcon(self.externMapAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.zoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.multiZoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.toMGRSAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.settingsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.helpAction)
        self.iface.removeDockWidget(self.zoomToDialog)
        self.iface.removeDockWidget(self.multiZoomDialog)
        self.zoomToDialog = None
        self.multiZoomDialog = None

    def startCapture(self):
        '''Set the focus of the copy coordinate tool and check it'''
        self.copyAction.setChecked(True)
        self.canvas.setMapTool(self.mapTool)

    def setShowMapTool(self):
        '''Set the focus of the external map tool and check it'''
        self.externMapAction.setChecked(True)
        self.canvas.setMapTool(self.showMapTool)

    def showZoomToDialog(self):
        '''Show the zoom to docked widget.'''
        self.zoomToDialog.show()

    def multiZoomTo(self):
        '''Display the Multi-zoom to dialog box'''
        self.multiZoomDialog.show()

    def toMGRS(self):
        '''Display the to MGRS  dialog box'''
        self.toMGRSDialog.show()

    def MGRStoLayer(self):
        '''Display the to MGRS  dialog box'''
        self.MGRStoLayerDialog.show()
    
    def settings(self):
        '''Show the settings dialog box'''
        self.settingsDialog.show()
        
    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(os.path.dirname(__file__) + "/index.html").toString()
        webbrowser.open(url, new=2)
        
    def settingsChanged(self):
        # Settings may have changed so we need to make sure the zoomToDialog window is configured properly
        self.zoomToDialog.configure()
        self.multiZoomDialog.settingsChanged()
            
 
    def zoomTo(self, srcCrs, lat, lon):
        canvasCrs = self.canvas.mapSettings().destinationCrs()
        transform = QgsCoordinateTransform(srcCrs, canvasCrs)
        x, y = transform.transform(float(lon), float(lat))
            
        rect = QgsRectangle(x,y,x,y)
        self.canvas.setExtent(rect)

        pt = QgsPointXY(x,y)
        self.highlight(pt)
        self.canvas.refresh()
        return pt
        
    def highlight(self, point):
        currExt = self.canvas.extent()
        
        leftPt = QgsPointXY(currExt.xMinimum(),point.y())
        rightPt = QgsPointXY(currExt.xMaximum(),point.y())
        
        topPt = QgsPointXY(point.x(),currExt.yMaximum())
        bottomPt = QgsPointXY(point.x(),currExt.yMinimum())
        
        horizLine = QgsGeometry.fromPolyline( [ leftPt , rightPt ] )
        vertLine = QgsGeometry.fromPolyline( [ topPt , bottomPt ] )
        
        self.crossRb.reset(QgsWkbTypes.LineGeometry)
        self.crossRb.addGeometry(horizLine, None)
        self.crossRb.addGeometry(vertLine, None)
        
        QTimer.singleShot(700, self.resetRubberbands)
        
    def resetRubberbands(self):
        self.crossRb.reset()
Example #36
0
class RectangleMapTool(QgsMapToolEmitPoint):

    rectangleCreated = pyqtSignal()
    deactivated = pyqtSignal()

    def __init__(self, canvas):
        self.canvas = canvas
        QgsMapToolEmitPoint.__init__(self, self.canvas)

        self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
        self.rubberBand.setColor(QColor(255, 0, 0, 100))
        self.rubberBand.setWidth(2)

        self.reset()

    def reset(self):
        self.startPoint = self.endPoint = None
        self.isEmittingPoint = False
        self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)

    def canvasPressEvent(self, e):
        self.startPoint = self.toMapCoordinates(e.pos())
        self.endPoint = self.startPoint
        self.isEmittingPoint = True

        self.showRect(self.startPoint, self.endPoint)

    def canvasReleaseEvent(self, e):
        self.isEmittingPoint = False
        if self.rectangle() is not None:
            self.rectangleCreated.emit()

    def canvasMoveEvent(self, e):
        if not self.isEmittingPoint:
            return

        self.endPoint = self.toMapCoordinates(e.pos())
        self.showRect(self.startPoint, self.endPoint)

    def showRect(self, startPoint, endPoint):
        self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)
        if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
            return

        point1 = QgsPointXY(startPoint.x(), startPoint.y())
        point2 = QgsPointXY(startPoint.x(), endPoint.y())
        point3 = QgsPointXY(endPoint.x(), endPoint.y())
        point4 = QgsPointXY(endPoint.x(), startPoint.y())

        self.rubberBand.addPoint(point1, False)
        self.rubberBand.addPoint(point2, False)
        self.rubberBand.addPoint(point3, False)
        # True to update canvas
        self.rubberBand.addPoint(point4, True)
        self.rubberBand.show()

    def rectangle(self):
        if self.startPoint is None or self.endPoint is None:
            return None
        elif self.startPoint.x() == self.endPoint.x() or \
                self.startPoint.y() == self.endPoint.y():
            return None

        return QgsRectangle(self.startPoint, self.endPoint)

    def setRectangle(self, rect):
        if rect == self.rectangle():
            return False

        if rect is None:
            self.reset()
        else:
            self.startPoint = QgsPointXY(rect.xMaximum(), rect.yMaximum())
            self.endPoint = QgsPointXY(rect.xMinimum(), rect.yMinimum())
            self.showRect(self.startPoint, self.endPoint)
        return True

    def deactivate(self):
        QgsMapTool.deactivate(self)
        self.deactivated.emit()
Example #37
0
class MapWidget(Ui_CanvasWidget, QMainWindow):
    def __init__(self, parent=None):
        super(MapWidget, self).__init__(parent)
        self.setupUi(self)

        self.firstshow = True
        self.layerbuttons = []
        self.editfeaturestack = []
        self.lastgpsposition = None
        self.project = None
        self.gps = None
        self.gpslogging = None
        self.selectionbands = defaultdict(partial(QgsRubberBand, self.canvas))

        self.canvas.setCanvasColor(Qt.white)
        self.canvas.enableAntiAliasing(True)
        self.canvas.setWheelAction(QgsMapCanvas.WheelZoomToMouseCursor)

        if hasattr(self.canvas, 'setParallelRenderingEnabled'):
            self.canvas.setParallelRenderingEnabled(True)

        pal = QgsPalLabeling()
        self.canvas.mapRenderer().setLabelingEngine(pal)
        self.canvas.setFrameStyle(QFrame.NoFrame)

        self.editgroup = QActionGroup(self)
        self.editgroup.setExclusive(True)
        self.editgroup.addAction(self.actionPan)
        self.editgroup.addAction(self.actionZoom_In)
        self.editgroup.addAction(self.actionZoom_Out)
        self.editgroup.addAction(self.actionInfo)

        self.actionGPS = GPSAction(":/icons/gps", self.canvas, self)
        self.projecttoolbar.addAction(self.actionGPS)

        gpsspacewidget= QWidget()
        gpsspacewidget.setMinimumWidth(30)
        gpsspacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.topspaceraction = self.projecttoolbar.insertWidget(self.actionGPS, gpsspacewidget)

        self.dataentryselection = QAction(self.projecttoolbar)
        self.dataentryaction = self.projecttoolbar.insertAction(self.topspaceraction, self.dataentryselection)
        self.dataentryselection.triggered.connect(self.select_data_entry)

        self.marker = GPSMarker(self.canvas)
        self.marker.hide()

        self.currentfeatureband = QgsRubberBand(self.canvas)
        self.currentfeatureband.setIconSize(20)
        self.currentfeatureband.setWidth(10)
        self.currentfeatureband.setColor(QColor(186, 93, 212, 76))

        self.gpsband = QgsRubberBand(self.canvas)
        self.gpsband.setColor(QColor(0, 0, 212, 76))
        self.gpsband.setWidth(5)

        RoamEvents.editgeometry.connect(self.queue_feature_for_edit)
        RoamEvents.selectioncleared.connect(self.clear_selection)
        RoamEvents.selectionchanged.connect(self.highlight_selection)
        RoamEvents.featureformloaded.connect(self.feature_form_loaded)

        self.connectButtons()

    def init_qgisproject(self, doc):
        parser = ProjectParser(doc)
        canvasnode = parser.canvasnode
        self.canvas.freeze()
        self.canvas.mapRenderer().readXML(canvasnode)
        self.canvaslayers = parser.canvaslayers()
        self.canvas.setLayerSet(self.canvaslayers)
        #red = QgsProject.instance().readNumEntry( "Gui", "/CanvasColorRedPart", 255 )[0];
        #green = QgsProject.instance().readNumEntry( "Gui", "/CanvasColorGreenPart", 255 )[0];
        #blue = QgsProject.instance().readNumEntry( "Gui", "/CanvasColorBluePart", 255 )[0];
        #color = QColor(red, green, blue);
        #self.canvas.setCanvasColor(color)
        self.canvas.updateScale()
        return self.canvas.mapRenderer().destinationCrs()

    def showEvent(self, *args, **kwargs):
        if self.firstshow:
            self.canvas.refresh()
            self.canvas.repaint()
            self.firstshow = False

    def feature_form_loaded(self, form, feature, project, editmode):
        self.currentfeatureband.setToGeometry(feature.geometry(), form.QGISLayer)

    def highlight_selection(self, results):
        self.clear_selection()
        for layer, features in results.iteritems():
            band = self.selectionbands[layer]
            band.setColor(QColor(255, 0, 0, 200))
            band.setIconSize(20)
            band.setWidth(2)
            band.setBrushStyle(Qt.NoBrush)
            band.reset(layer.geometryType())
            for feature in features:
                band.addGeometry(feature.geometry(), layer)

    def highlight_active_selection(self, layer, feature, features):
        self.clear_selection()
        self.highlight_selection({layer: features})
        self.currentfeatureband.setToGeometry(feature.geometry(), layer)

    def clear_selection(self):
        # Clear the main selection rubber band
        self.currentfeatureband.reset()
        # Clear the rest
        for band in self.selectionbands.itervalues():
            band.reset()

        self.editfeaturestack = []

    def queue_feature_for_edit(self, form, feature):
        def trigger_default_action():
            for action in self.projecttoolbar.actions():
                if action.property('dataentry') and action.isdefault:
                    action.trigger()
                    break

        self.editfeaturestack.append((form, feature))
        self.load_form(form)
        trigger_default_action()

    def clear_temp_objects(self):
        def clear_tool_band():
            """
            Clear the rubber band of the active tool if it has one
            """
            tool = self.canvas.mapTool()
            try:
                tool.clearBand()
            except AttributeError:
                # No clearBand method found, but that's cool.
                pass

        self.currentfeatureband.reset()
        clear_tool_band()


    def settings_updated(self, settings):
        self.actionGPS.updateGPSPort()
        gpslogging = settings.get('gpslogging', True)
        if self.gpslogging:
            self.gpslogging.logging = gpslogging

    def set_gps(self, gps, logging):
        self.gps = gps
        self.gpslogging = logging
        self.gps.gpsposition.connect(self.gps_update_canvas)
        self.gps.firstfix.connect(self.gps_first_fix)
        self.gps.gpsdisconnected.connect(self.gps_disconnected)

    def gps_update_canvas(self, position, gpsinfo):
        # Recenter map if we go outside of the 95% of the area
        if self.gpslogging.logging:
            self.gpsband.addPoint(position)
            self.gpsband.show()

        if roam.config.settings.get('gpscenter', True):
            if not self.lastgpsposition == position:
                self.lastposition = position
                rect = QgsRectangle(position, position)
                extentlimt = QgsRectangle(self.canvas.extent())
                extentlimt.scale(0.95)

                if not extentlimt.contains(position):
                    self.zoom_to_location(position)

        self.marker.show()
        self.marker.setCenter(position)

    def gps_first_fix(self, postion, gpsinfo):
        zoomtolocation = roam.config.settings.get('gpszoomonfix', True)
        if zoomtolocation:
            self.canvas.zoomScale(1000)
            self.zoom_to_location(postion)

    def zoom_to_location(self, position):
        rect = QgsRectangle(position, position)
        self.canvas.setExtent(rect)
        self.canvas.refresh()

    def gps_disconnected(self):
        self.marker.hide()

    def select_data_entry(self):
        def showformerror(form):
            pass

        def actions():
            for form in self.project.forms:
                action = form.createuiaction()
                valid, failreasons = form.valid
                if not valid:
                    roam.utils.warning("Form {} failed to load".format(form.label))
                    roam.utils.warning("Reasons {}".format(failreasons))
                    action.triggered.connect(partial(showformerror, form))
                else:
                    action.triggered.connect(partial(self.load_form, form))
                yield action

        formpicker = PickActionDialog(msg="Select data entry form")
        formpicker.addactions(actions())
        formpicker.exec_()

    def project_loaded(self, project):
        self.project = project
        self.actionPan.trigger()
        try:
            firstform = project.forms[0]
            self.load_form(firstform)
            self.dataentryselection.setVisible(True)
        except IndexError:
            self.dataentryselection.setVisible(False)

        # Enable the raster layers button only if the project contains a raster layer.
        layers = QgsMapLayerRegistry.instance().mapLayers().values()
        hasrasters = any(layer.type() == QgsMapLayer.RasterLayer for layer in layers)
        self.actionRaster.setEnabled(hasrasters)
        self.defaultextent = self.canvas.extent()
        roam.utils.info("Extent: {}".format(self.defaultextent.toString()))

        self.infoTool.selectionlayers = project.selectlayersmapping()

        self.canvas.freeze(False)
        self.canvas.refresh()

    def setMapTool(self, tool, *args):
        self.canvas.setMapTool(tool)

    def connectButtons(self):
        def connectAction(action, tool):
            action.toggled.connect(partial(self.setMapTool, tool))

        def cursor(name):
            pix = QPixmap(name)
            pix = pix.scaled(QSize(24,24))
            return QCursor(pix)

        self.zoomInTool = QgsMapToolZoom(self.canvas, False)
        self.zoomOutTool = QgsMapToolZoom(self.canvas, True)
        self.panTool = PanTool(self.canvas)
        self.infoTool = InfoTool(self.canvas)

        connectAction(self.actionZoom_In, self.zoomInTool)
        connectAction(self.actionZoom_Out, self.zoomOutTool)
        connectAction(self.actionPan, self.panTool)
        connectAction(self.actionInfo, self.infoTool)

        self.zoomInTool.setCursor(cursor(':/icons/in'))
        self.zoomOutTool.setCursor(cursor(':/icons/out'))
        self.infoTool.setCursor(cursor(':/icons/info'))

        self.actionRaster.triggered.connect(self.toggleRasterLayers)

        self.infoTool.infoResults.connect(RoamEvents.selectionchanged.emit)

        self.actionHome.triggered.connect(self.homeview)

    def homeview(self):
        """
        Zoom the mapview canvas to the extents the project was opened at i.e. the
        default extent.
        """
        self.canvas.setExtent(self.defaultextent)
        self.canvas.refresh()

    def load_form(self, form):
        self.clearCapatureTools()
        self.dataentryselection.setIcon(QIcon(form.icon))
        self.dataentryselection.setText(form.icontext)
        self.create_capture_buttons(form)

    def create_capture_buttons(self, form):
        tool = form.getMaptool()(self.canvas)
        for action in tool.actions:
            # Create the action here.
            if action.ismaptool:
                action.toggled.connect(partial(self.setMapTool, tool))

            # Set the action as a data entry button so we can remove it later.
            action.setProperty("dataentry", True)
            self.editgroup.addAction(action)
            self.layerbuttons.append(action)
            self.projecttoolbar.insertAction(self.topspaceraction, action)
            action.setChecked(action.isdefault)

        if hasattr(tool, 'geometryComplete'):
            add = partial(self.add_new_feature, form)
            tool.geometryComplete.connect(add)
        else:
            tool.finished.connect(self.openForm)
            tool.error.connect(partial(self.showUIMessage, form.label))

    def add_new_feature(self, form, geometry):
        """
        Add a new new feature to the given layer
        """
        # TODO Extract into function.
        # NOTE This function is doing too much, acts as add and also edit.
        layer = form.QGISLayer
        if layer.geometryType() in [QGis.WKBMultiLineString, QGis.WKBMultiPoint, QGis.WKBMultiPolygon]:
            geometry.convertToMultiType()

        try:
            form, feature = self.editfeaturestack.pop()
            self.editfeaturegeometry(form, feature, newgeometry=geometry)
            return
        except IndexError:
            pass

        layer = form.QGISLayer
        fields = layer.pendingFields()

        feature = QgsFeature(fields)
        feature.setGeometry(geometry)

        for index in xrange(fields.count()):
            pkindexes = layer.dataProvider().pkAttributeIndexes()
            if index in pkindexes and layer.dataProvider().name() == 'spatialite':
                continue

            value = layer.dataProvider().defaultValue(index)
            feature[index] = value

        RoamEvents.open_feature_form(form, feature, editmode=False)

    def editfeaturegeometry(self, form, feature, newgeometry):
        # TODO Extract into function.
        layer = form.QGISLayer
        layer.startEditing()
        feature.setGeometry(newgeometry)
        layer.updateFeature(feature)
        saved = layer.commitChanges()
        if not saved:
            map(roam.utils.error, layer.commitErrors())
        self.canvas.refresh()
        self.currentfeatureband.setToGeometry(feature.geometry(), layer)
        RoamEvents.editgeometry_complete.emit(form, feature)

    def clearCapatureTools(self):
        captureselected = False
        for action in self.projecttoolbar.actions():
            if action.objectName() == "capture" and action.isChecked():
                captureselected = True

            if action.property('dataentry'):
                self.projecttoolbar.removeAction(action)
        return captureselected

    def toggleRasterLayers(self):
        """
        Toggle all raster layers on or off.
        """
        if not self.canvaslayers:
            return

        #Freeze the canvas to save on UI refresh
        self.canvas.freeze()
        for layer in self.canvaslayers:
            if layer.layer().type() == QgsMapLayer.RasterLayer:
                layer.setVisible(not layer.isVisible())
                # Really!? We have to reload the whole layer set every time?
            # WAT?
        self.canvas.setLayerSet(self.canvaslayers)
        self.canvas.freeze(False)
        self.canvas.refresh()

    def cleanup(self):
        self.gpsband.reset()
        self.gpsband.hide()
        self.clear_selection()
        self.clear_temp_objects()
        self.clearCapatureTools()
        self.canvas.freeze()
        self.canvas.clear()
        self.canvas.freeze(False)
        for action in self.layerbuttons:
            self.editgroup.removeAction(action)
Example #38
0
class SelectDownloadExtentMapTool(QgsMapTool):
    def __init__(self, canvas, dialog):
        self.canvas = canvas
        self.dialog = dialog
        QgsMapTool.__init__(self, self.canvas)
        self.setCursor(Qt.CrossCursor)
        self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon)
        self.rubberBand.setColor(Qt.red)
        self.rubberBand.setWidth(1)
        self.reset()

    def reset(self):
        self.startPoint = self.endPoint = None
        self.isEmittingPoint = False
        self.rubberBand.reset(QGis.Polygon)

    def canvasPressEvent(self, e):
        self.startPoint = self.toMapCoordinates(e.pos())
        self.endPoint = self.startPoint
        self.isEmittingPoint = True
        self.showRect(self.startPoint, self.endPoint)

    def canvasReleaseEvent(self, e):
        self.isEmittingPoint = False
        self.dialog.setExtent(self.rectangle())
        self.dialog.showNormal()
        self.dialog.raise_()
        self.dialog.activateWindow()
        self.reset()

    def canvasMoveEvent(self, e):
        if not self.isEmittingPoint:
            return

        self.endPoint = self.toMapCoordinates(e.pos())
        self.showRect(self.startPoint, self.endPoint)

    def showRect(self, startPoint, endPoint):
        self.rubberBand.reset(QGis.Polygon)
        if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
            return

        point1 = QgsPoint(startPoint.x(), startPoint.y())
        point2 = QgsPoint(startPoint.x(), endPoint.y())
        point3 = QgsPoint(endPoint.x(), endPoint.y())
        point4 = QgsPoint(endPoint.x(), startPoint.y())

        self.rubberBand.addPoint(point1, False)
        self.rubberBand.addPoint(point2, False)
        self.rubberBand.addPoint(point3, False)
        self.rubberBand.addPoint(point4, True)  # true to update canvas
        self.rubberBand.show()

    def rectangle(self):
        if self.startPoint is None or self.endPoint is None:
            return None
        elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y(
        ) == self.endPoint.y():
            return None

        return QgsRectangle(self.startPoint, self.endPoint)
class RectangleMapTool(QgsMapToolEmitPoint):
    """
    Map tool that lets the user define the analysis extents.
    """
    rectangle_created = pyqtSignal()
    deactivated = pyqtSignal()

    def __init__(self, canvas):
        """Constructor for the map tool.

        :param canvas: Canvas that tool will interact with.
        :type canvas: QgsMapCanvas
        """
        self.canvas = canvas
        self.start_point = None
        self.end_point = None
        self.is_emitting_point = False

        QgsMapToolEmitPoint.__init__(self, self.canvas)

        self.rubber_band = QgsRubberBand(self.canvas, geometryType=QGis.Line)
        self.rubber_band.setColor(QColor(0, 0, 240, 100))
        # Needs QGIS 2.6
        # self.rubber_band.setFillColor(QColor(0, 0, 240, 0))
        self.rubber_band.setWidth(1)

        self.reset()

    def reset(self):
        """
        Clear the rubber band for the analysis extents.
        """
        self.start_point = self.end_point = None
        self.is_emitting_point = False
        self.rubber_band.reset(QGis.Polygon)

    def canvasPressEvent(self, e):
        """
        Handle canvas press events so we know when user is capturing the rect.

        :param e: A Qt event object.
        :type: QEvent
        """
        self.start_point = self.toMapCoordinates(e.pos())
        self.end_point = self.start_point
        self.is_emitting_point = True

        self.show_rectangle(self.start_point, self.end_point)

    def canvasReleaseEvent(self, e):
        """
        Handle canvas release events  has finished capturing e

        :param e: A Qt event object.
        :type: QEvent
        """
        _ = e
        self.is_emitting_point = False
        self.rectangle_created.emit()

    def canvasMoveEvent(self, e):
        """

        :param e:
        :return:
        """
        if not self.is_emitting_point:
            return

        self.end_point = self.toMapCoordinates(e.pos())
        self.show_rectangle(self.start_point, self.end_point)

    def show_rectangle(self, start_point, end_point):
        """
        Show the rectangle on the canvas.

        :param start_point: QGIS Point object representing the origin (
            top left).
        :type start_point: QgsPoint

        :param end_point: QGIS Point object representing the contra-origin (
            bottom right).
        :type end_point: QgsPoint

        :return:
        """
        self.rubber_band.reset(QGis.Polygon)
        if (start_point.x() == end_point.x() or
                start_point.y() == end_point.y()):
            return

        point1 = start_point
        point2 = QgsPoint(end_point.x(), start_point.y())
        point3 = end_point
        point4 = QgsPoint(start_point.x(), end_point.y())

        update_canvas = False
        self.rubber_band.addPoint(point1, update_canvas)
        self.rubber_band.addPoint(point2, update_canvas)
        self.rubber_band.addPoint(point3, update_canvas)
        self.rubber_band.addPoint(point4, update_canvas)
        # noinspection PyArgumentEqualDefault
        # no False so canvas will update
        # close the polygon otherwise it shows as a filled rect
        self.rubber_band.addPoint(point1)
        self.rubber_band.show()

    def rectangle(self):
        """
        Accessor for the rectangle.

        :return: A rectangle showing the designed extent.
        :rtype: QgsRectangle
        """
        if self.start_point is None or self.end_point is None:
            return None
        elif self.start_point.x() == self.end_point.x() or \
                self.start_point.y() == self.end_point.y():
            return None

        return QgsRectangle(self.start_point, self.end_point)

    def set_rectangle(self, rectangle):
        """
        Set the rectangle for the selection.
        :param rectangle:
        :return:
        """
        if rectangle == self.rectangle():
            return False

        if rectangle is None:
            self.reset()
        else:
            self.start_point = QgsPoint(
                rectangle.xMinimum(), rectangle.yMinimum())
            self.end_point = QgsPoint(
                rectangle.xMaximum(), rectangle.yMaximum())
            self.show_rectangle(self.start_point, self.end_point)
        return True

    def deactivate(self):
        """
        Disable the tool.
        """
        QgsMapTool.deactivate(self)
        self.deactivated.emit()
Example #40
0
class Qgis2threejsDialog(QDialog):

    def __init__(self, iface, objectTypeManager, pluginManager,
                 exportSettings=None, lastTreeItemData=None):
        QDialog.__init__(self, iface.mainWindow())
        self.iface = iface
        self.objectTypeManager = objectTypeManager
        self.pluginManager = pluginManager
        self._settings = exportSettings or {}
        self.lastTreeItemData = lastTreeItemData
        self.localBrowsingMode = True

        self.rb_quads = self.rb_point = None

        self.templateType = None
        self.currentItem = None
        self.currentPage = None

        # Set up the user interface from Designer.
        self.ui = ui = Ui_Qgis2threejsDialog()
        ui.setupUi(self)

        self.setWindowFlags(self.windowFlags() | Qt.WindowMinimizeButtonHint)

        # output html filename
        ui.lineEdit_OutputFilename.setText(
            self._settings.get("OutputFilename", ""))
        ui.lineEdit_OutputFilename.setPlaceholderText("[Temporary file]")

        # settings button
        icon = QIcon(os.path.join(tools.pluginDir(), "icons", "settings.png"))
        ui.toolButton_Settings.setIcon(icon)

        # popup menu displayed when settings button is pressed
        items = [["Load Settings...", self.loadSettings],
                 ["Save Settings As...", self.saveSettings],
                 [None, None],
                 ["Clear Settings", self.clearSettings],
                 [None, None],
                 ["Plugin Settings...", self.pluginSettings]]

        self.menu = QMenu()
        self.menu_actions = []
        for text, slot in items:
            if text:
                action = QAction(text, iface.mainWindow())
                action.triggered.connect(slot)
                self.menu.addAction(action)
                self.menu_actions.append(action)
            else:
                self.menu.addSeparator()

        ui.toolButton_Settings.setMenu(self.menu)
        ui.toolButton_Settings.setPopupMode(QToolButton.InstantPopup)

        # progress bar and message label
        ui.progressBar.setVisible(False)
        ui.label_MessageIcon.setVisible(False)

        # buttons
        ui.pushButton_Run.clicked.connect(self.run)
        ui.pushButton_Close.clicked.connect(self.reject)
        ui.pushButton_Help.clicked.connect(self.help)

        # set up map tool
        self.previousMapTool = None
        self.mapTool = RectangleMapTool(iface.mapCanvas())
        #self.mapTool = PointMapTool(iface.mapCanvas())

        # set up the template combo box
        self.initTemplateList()
        self.ui.comboBox_Template.currentIndexChanged.connect(
            self.currentTemplateChanged)

        # set up the properties pages
        self.pages = {}
        self.pages[ppages.PAGE_WORLD] = ppages.WorldPropertyPage(self)
        self.pages[ppages.PAGE_CONTROLS] = ppages.ControlsPropertyPage(self)
        self.pages[ppages.PAGE_DEM] = ppages.DEMPropertyPage(self)
        self.pages[ppages.PAGE_VECTOR] = ppages.VectorPropertyPage(self)
        container = ui.propertyPagesContainer
        for page in self.pages.itervalues():
            page.hide()
            container.addWidget(page)

        # build object tree
        self.topItemPages = {
            ObjectTreeItem.ITEM_WORLD: ppages.PAGE_WORLD,
            ObjectTreeItem.ITEM_CONTROLS: ppages.PAGE_CONTROLS,
            ObjectTreeItem.ITEM_DEM: ppages.PAGE_DEM}
        self.initObjectTree()
        self.ui.treeWidget.currentItemChanged.connect(
            self.currentObjectChanged)
        self.ui.treeWidget.itemChanged.connect(self.objectItemChanged)
        self.currentTemplateChanged()   # update item visibility

        ui.toolButton_Browse.clicked.connect(self.browseClicked)

        # iface.mapCanvas().mapToolSet.connect(self.mapToolSet)    # to show
        # button to enable own map tool

    def settings(self, clean=False):
        # save settings of current panel
        item = self.ui.treeWidget.currentItem()
        if item and self.currentPage:
            self.saveProperties(item, self.currentPage)

        # plugin version
        self._settings["PluginVersion"] = plugin_version

        # template and output html file path
        self._settings["Template"] = self.ui.comboBox_Template.currentText()
        self._settings[
            "OutputFilename"] = self.ui.lineEdit_OutputFilename.text()

        if not clean:
            return self._settings

        # clean up settings - remove layers that don't exist in the layer
        # registry
        registry = QgsMapLayerRegistry.instance()
        for itemId in [ObjectTreeItem.ITEM_OPTDEM, ObjectTreeItem.ITEM_POINT,
                       ObjectTreeItem.ITEM_LINE, ObjectTreeItem.ITEM_POLYGON]:
            parent = self._settings.get(itemId, {})
            for layerId in parent.keys():
                if registry.mapLayer(layerId) is None:
                    del parent[layerId]

        return self._settings

    def setSettings(self, settings):
        self._settings = settings

        # template and output html file path
        templateName = settings.get("Template")
        if templateName:
            cbox = self.ui.comboBox_Template
            index = cbox.findText(templateName)
            if index != -1:
                cbox.setCurrentIndex(index)

        filename = settings.get("OutputFilename")
        if filename:
            self.ui.lineEdit_OutputFilename.setText(filename)

        # update object tree
        self.ui.treeWidget.blockSignals(True)
        self.initObjectTree()
        self.ui.treeWidget.blockSignals(False)

        # update tree item visibility
        self.templateType = None
        self.currentTemplateChanged()

    def loadSettings(self):
        # file open dialog
        directory = QgsProject.instance().homePath()
        if not directory:
            directory = os.path.split(
                self.ui.lineEdit_OutputFilename.text())[0]
        if not directory:
            directory = QDir.homePath()
        filterString = "Settings files (*.qto3settings);;All files (*.*)"
        filename = QFileDialog.getOpenFileName(
            self, "Load Export Settings", directory, filterString)
        if not filename:
            return

        # load settings from file (.qto3settings)
        import json
        with open(filename) as f:
            settings = json.load(f)

        self.setSettings(settings)

    def saveSettings(self, filename=None):
        if not filename:
            # file save dialog
            directory = QgsProject.instance().homePath()
            if not directory:
                directory = os.path.split(
                    self.ui.lineEdit_OutputFilename.text())[0]
            if not directory:
                directory = QDir.homePath()
            filename = QFileDialog.getSaveFileName(
                self, "Save Export Settings", directory, "Settings files (*.qto3settings)")
            if not filename:
                return

            # append .qto3settings extension if filename doesn't have
            if os.path.splitext(filename)[1].lower() != ".qto3settings":
                filename += ".qto3settings"

        # save settings to file (.qto3settings)
        import codecs
        import json
        with codecs.open(filename, "w", "UTF-8") as f:
            json.dump(
                self.settings(True),
                f,
                ensure_ascii=False,
                indent=2,
                sort_keys=True)

        logMessage(u"Settings saved: {0}".format(filename))

    def clearSettings(self):
        if QMessageBox.question(self, "Qgis2threejs", "Are you sure to clear all export settings?",
                                QMessageBox.Ok | QMessageBox.Cancel) == QMessageBox.Ok:
            self.setSettings({})

    def pluginSettings(self):
        from settingsdialog import SettingsDialog
        dialog = SettingsDialog(self)
        if dialog.exec_():
            self.pluginManager.reloadPlugins()
            self.pages[ppages.PAGE_DEM].initLayerComboBox()

    def showMessageBar(self, text, level=QgsMessageBar.INFO):
        # from src/gui/qgsmessagebaritem.cpp
        if level == QgsMessageBar.CRITICAL:
            msgIcon = "/mIconCritical.png"
            bgColor = "#d65253"
        elif level == QgsMessageBar.WARNING:
            msgIcon = "/mIconWarn.png"
            bgColor = "#ffc800"
        else:
            msgIcon = "/mIconInfo.png"
            bgColor = "#e7f5fe"
        stylesheet = "QLabel {{ background-color:{0}; }}".format(bgColor)

        label = self.ui.label_MessageIcon
        label.setPixmap(QgsApplication.getThemeIcon(msgIcon).pixmap(24))
        label.setStyleSheet(stylesheet)
        label.setVisible(True)

        label = self.ui.label_Status
        label.setText(text)
        label.setStyleSheet(stylesheet)

    def clearMessageBar(self):
        self.ui.label_MessageIcon.setVisible(False)
        self.ui.label_Status.setText("")
        self.ui.label_Status.setStyleSheet(
            "QLabel { background-color: rgba(0, 0, 0, 0); }")

    def initTemplateList(self):
        cbox = self.ui.comboBox_Template
        cbox.clear()
        templateDir = QDir(tools.templateDir())
        for i, entry in enumerate(templateDir.entryList(["*.html", "*.htm"])):
            cbox.addItem(entry)

            config = tools.getTemplateConfig(entry)
            # get template type
            templateType = config.get("type", "plain")
            cbox.setItemData(i, templateType, Qt.UserRole)

            # set tool tip text
            desc = config.get("description", "")
            if desc:
                cbox.setItemData(i, desc, Qt.ToolTipRole)

        # select the template of the settings
        templatePath = self._settings.get("Template")

        # if no template setting, select the last used template
        if not templatePath:
            templatePath = QSettings().value(
                "/Qgis2threejs/lastTemplate", def_vals.template, type=unicode)

        if templatePath:
            index = cbox.findText(templatePath)
            if index != -1:
                cbox.setCurrentIndex(index)
            return index
        return -1

    def initObjectTree(self):
        tree = self.ui.treeWidget
        tree.clear()

        # add vector and raster layers into tree widget
        topItems = {}
        for id, name in zip(ObjectTreeItem.topItemIds,
                            ObjectTreeItem.topItemNames):
            item = QTreeWidgetItem(tree, [name])
            item.setData(0, Qt.UserRole, id)
            topItems[id] = item

        optDEMChecked = False
        for layer in self.iface.legendInterface().layers():
            parentId = ObjectTreeItem.parentIdByLayer(layer)
            if parentId is None:
                continue

            item = QTreeWidgetItem(topItems[parentId], [layer.name()])
            isVisible = self._settings.get(parentId, {}).get(layer.id(), {}).get(
                "visible", False)  # self.iface.legendInterface().isLayerVisible(layer)
            check_state = Qt.Checked if isVisible else Qt.Unchecked
            item.setData(0, Qt.CheckStateRole, check_state)
            item.setData(0, Qt.UserRole, layer.id())
            if parentId == ObjectTreeItem.ITEM_OPTDEM and isVisible:
                optDEMChecked = True

        for id, item in topItems.iteritems():
            if id != ObjectTreeItem.ITEM_OPTDEM or optDEMChecked:
                tree.expandItem(item)

        # disable additional DEM item which is selected as main DEM
        layerId = self._settings.get(
            ObjectTreeItem.ITEM_DEM,
            {}).get("comboBox_DEMLayer")
        if layerId:
            self.primaryDEMChanged(layerId)

    def saveProperties(self, item, page):
        properties = page.properties()
        parent = item.parent()
        if parent is None:
            # top level item
            self._settings[item.data(0, Qt.UserRole)] = properties
        else:
            # layer item
            parentId = parent.data(0, Qt.UserRole)
            if parentId not in self._settings:
                self._settings[parentId] = {}
            self._settings[parentId][item.data(0, Qt.UserRole)] = properties

    def setCurrentTreeItemByData(self, data):
        it = QTreeWidgetItemIterator(self.ui.treeWidget)
        while it.value():
            if it.value().data(0, Qt.UserRole) == data:
                self.ui.treeWidget.setCurrentItem(it.value())
                return True
            it += 1
        return False

    def currentTemplateChanged(self, index=None):
        cbox = self.ui.comboBox_Template
        templateType = cbox.itemData(cbox.currentIndex(), Qt.UserRole)
        if templateType == self.templateType:
            return

        # hide items unsupported by template
        tree = self.ui.treeWidget
        for i, id in enumerate(ObjectTreeItem.topItemIds):
            hidden = (templateType == "sphere" and id !=
                      ObjectTreeItem.ITEM_CONTROLS)
            tree.topLevelItem(i).setHidden(hidden)

        # set current tree item
        if templateType == "sphere":
            tree.setCurrentItem(
                tree.topLevelItem(
                    ObjectTreeItem.topItemIndex(
                        ObjectTreeItem.ITEM_CONTROLS)))
        # restore selection
        elif self.lastTreeItemData is None or not self.setCurrentTreeItemByData(self.lastTreeItemData):
            tree.setCurrentItem(tree.topLevelItem(ObjectTreeItem.topItemIndex(
                ObjectTreeItem.ITEM_DEM)))   # default selection for plain is DEM

        # display messages
        self.clearMessageBar()
        if templateType != "sphere":
            # show message if crs unit is degrees
            mapSettings = self.iface.mapCanvas().mapSettings(
            ) if QGis.QGIS_VERSION_INT >= 20300 else self.iface.mapCanvas().mapRenderer()
            if mapSettings.destinationCrs().mapUnits() in [QGis.Degrees]:
                self.showMessageBar(
                    "The unit of current CRS is degrees, so terrain may not appear well.",
                    QgsMessageBar.WARNING)

        self.templateType = templateType

    def currentObjectChanged(self, currentItem, previousItem):
        # save properties of previous item
        if previousItem and self.currentPage:
            self.saveProperties(previousItem, self.currentPage)

        self.currentItem = currentItem
        self.currentPage = None

        # hide text browser and all pages
        self.ui.textBrowser.hide()
        for page in self.pages.itervalues():
            page.hide()

        parent = currentItem.parent()
        if parent is None:
            topItemIndex = currentItem.data(0, Qt.UserRole)
            pageType = self.topItemPages.get(topItemIndex, ppages.PAGE_NONE)
            page = self.pages.get(pageType, None)
            if page is None:
                self.showDescription(topItemIndex)
                return

            page.setup(self._settings.get(topItemIndex))
            page.show()

        else:
            parentId = parent.data(0, Qt.UserRole)
            layerId = currentItem.data(0, Qt.UserRole)
            layer = QgsMapLayerRegistry.instance().mapLayer(unicode(layerId))
            if layer is None:
                return

            layerType = layer.type()
            if layerType == QgsMapLayer.RasterLayer:
                page = self.pages[ppages.PAGE_DEM]
                page.setup(
                    self._settings.get(
                        parentId,
                        {}).get(
                        layerId,
                        None),
                    layer,
                    False)
            elif layerType == QgsMapLayer.VectorLayer:
                page = self.pages[ppages.PAGE_VECTOR]
                page.setup(
                    self._settings.get(
                        parentId,
                        {}).get(
                        layerId,
                        None),
                    layer)
            else:
                return

            page.show()

        self.currentPage = page

    def objectItemChanged(self, item, column):
        parent = item.parent()
        if parent is None:
            return

        # checkbox of optional layer checked/unchecked
        if item == self.currentItem:
            if self.currentPage:
                # update enablement of property widgets
                self.currentPage.itemChanged(item)
        else:
            # select changed item
            self.ui.treeWidget.setCurrentItem(item)

            # set visible property
            #visible = item.data(0, Qt.CheckStateRole) == Qt.Checked
            #parentId = parent.data(0, Qt.UserRole)
            #layerId = item.data(0, Qt.UserRole)
            #self._settings.get(parentId, {}).get(layerId, {})["visible"] = visible

    def primaryDEMChanged(self, layerId):
        tree = self.ui.treeWidget
        parent = tree.topLevelItem(
            ObjectTreeItem.topItemIndex(
                ObjectTreeItem.ITEM_OPTDEM))
        tree.blockSignals(True)
        for i in range(parent.childCount()):
            item = parent.child(i)
            isPrimary = item.data(0, Qt.UserRole) == layerId
            item.setDisabled(isPrimary)
        tree.blockSignals(False)

    def showDescription(self, topItemIndex):
        fragment = {ObjectTreeItem.ITEM_OPTDEM: "additional-dem",
                    ObjectTreeItem.ITEM_POINT: "point",
                    ObjectTreeItem.ITEM_LINE: "line",
                    ObjectTreeItem.ITEM_POLYGON: "polygon"}.get(topItemIndex)

        url = "http://qgis2threejs.readthedocs.org/en/docs-release/ExportSettings.html"
        if fragment:
            url += "#" + fragment

        html = '<a href="{0}">Online Help</a> about this item'.format(url)
        self.ui.textBrowser.setHtml(html)
        self.ui.textBrowser.show()

    def numericFields(self, layer):
        # get attributes of a sample feature and create numeric field name list
        numeric_fields = []
        f = QgsFeature()
        layer.getFeatures().nextFeature(f)
        for field in f.fields():
            isNumeric = False
            try:
                float(f.attribute(field.name()))
                isNumeric = True
            except ValueError:
                pass
            if isNumeric:
                numeric_fields.append(field.name())
        return numeric_fields

    def mapTo3d(self):
        canvas = self.iface.mapCanvas()
        mapSettings = canvas.mapSettings(
        ) if QGis.QGIS_VERSION_INT >= 20300 else canvas.mapRenderer()

        world = self._settings.get(ObjectTreeItem.ITEM_WORLD, {})
        bs = float(world.get("lineEdit_BaseSize", def_vals.baseSize))
        ve = float(world.get("lineEdit_zFactor", def_vals.zExaggeration))
        vs = float(world.get("lineEdit_zShift", def_vals.zShift))

        return MapTo3D(mapSettings, bs, ve, vs)

    def progress(self, percentage=None, statusMsg=None):
        ui = self.ui
        if percentage is not None:
            ui.progressBar.setValue(percentage)
            if percentage == 100:
                ui.progressBar.setVisible(False)
                ui.label_Status.setText("")
            else:
                ui.progressBar.setVisible(True)

        if statusMsg is not None:
            ui.label_Status.setText(statusMsg)
            ui.label_Status.repaint()
        QgsApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    def run(self):
        self.endPointSelection()

        ui = self.ui
        filename = ui.lineEdit_OutputFilename.text()   # ""=Temporary file
        if filename and os.path.exists(filename):
            if QMessageBox.question(self, "Qgis2threejs", "Output file already exists. Overwrite it?",
                                    QMessageBox.Ok | QMessageBox.Cancel) != QMessageBox.Ok:
                return

        # export to web (three.js)
        export_settings = ExportSettings(
            self.pluginManager, self.localBrowsingMode)
        export_settings.loadSettings(self.settings())
        export_settings.setMapCanvas(self.iface.mapCanvas())

        err_msg = export_settings.checkValidity()
        if err_msg is not None:
            QMessageBox.warning(
                self,
                "Qgis2threejs",
                err_msg or "Invalid settings")
            return

        ui.pushButton_Run.setEnabled(False)
        ui.toolButton_Settings.setVisible(False)
        self.clearMessageBar()
        self.progress(0)

        if export_settings.exportMode == ExportSettings.PLAIN_MULTI_RES:
            # update quads and point on map canvas
            self.createRubberBands(
                export_settings.baseExtent,
                export_settings.quadtree())

        # export
        ret = exportToThreeJS(
            export_settings,
            self.iface.legendInterface(),
            self.objectTypeManager,
            self.progress)

        self.progress(100)
        ui.pushButton_Run.setEnabled(True)

        if not ret:
            ui.toolButton_Settings.setVisible(True)
            return

        self.clearRubberBands()

        # store last selections
        settings = QSettings()
        settings.setValue(
            "/Qgis2threejs/lastTemplate",
            export_settings.templatePath)
        settings.setValue(
            "/Qgis2threejs/lastControls",
            export_settings.controls)

        # open web browser
        if not tools.openHTMLFile(export_settings.htmlfilename):
            ui.toolButton_Settings.setVisible(True)
            return

        # close dialog
        QDialog.accept(self)

    def reject(self):
        # save properties of current object
        item = self.ui.treeWidget.currentItem()
        if item and self.currentPage:
            self.saveProperties(item, self.currentPage)

        self.endPointSelection()
        self.clearRubberBands()
        QDialog.reject(self)

    def help(self):
        url = "http://qgis2threejs.readthedocs.org/"

        import webbrowser
        webbrowser.open(url, new=2)    # new=2: new tab if possible

    def startPointSelection(self):
        canvas = self.iface.mapCanvas()
        if self.previousMapTool != self.mapTool:
            self.previousMapTool = canvas.mapTool()
        canvas.setMapTool(self.mapTool)
        self.pages[ppages.PAGE_DEM].toolButton_PointTool.setVisible(False)

    def endPointSelection(self):
        self.mapTool.reset()
        if self.previousMapTool is not None:
            self.iface.mapCanvas().setMapTool(self.previousMapTool)

    def mapToolSet(self, mapTool):
        return
        # TODO: unstable
        if mapTool != self.mapTool and self.currentPage is not None:
            if self.currentPage.pageType == ppages.PAGE_DEM and self.currentPage.isPrimary:
                self.currentPage.toolButton_PointTool.setVisible(True)

    def createRubberBands(self, baseExtent, quadtree):
        self.clearRubberBands()
        # create quads with rubber band
        self.rb_quads = QgsRubberBand(self.iface.mapCanvas(), QGis.Line)
        self.rb_quads.setColor(Qt.blue)
        self.rb_quads.setWidth(1)

        quads = quadtree.quads()
        for quad in quads:
            geom = baseExtent.subrectangle(quad.rect).geometry()
            self.rb_quads.addGeometry(geom, None)
        self.log("Quad count: %d" % len(quads))

        if not quadtree.focusRect:
            return

        # create a point with rubber band
        if quadtree.focusRect.width() == 0 or quadtree.focusRect.height() == 0:
            npt = quadtree.focusRect.center()
            self.rb_point = QgsRubberBand(self.iface.mapCanvas(), QGis.Point)
            self.rb_point.setColor(Qt.red)
            self.rb_point.addPoint(baseExtent.point(npt))

    def clearRubberBands(self):
        # clear quads and point
        if self.rb_quads:
            self.iface.mapCanvas().scene().removeItem(self.rb_quads)
            self.rb_quads = None
        if self.rb_point:
            self.iface.mapCanvas().scene().removeItem(self.rb_point)
            self.rb_point = None

    def browseClicked(self):
        directory = os.path.split(self.ui.lineEdit_OutputFilename.text())[0]
        if not directory:
            directory = QDir.homePath()
        filename = QFileDialog.getSaveFileName(
            self,
            self.tr("Output filename"),
            directory,
            "HTML file (*.html *.htm)",
            options=QFileDialog.DontConfirmOverwrite)
        if not filename:
            return

        # append .html extension if filename doesn't have either .html or .htm
        if filename[-5:].lower() != ".html" and filename[-4:].lower() != ".htm":
            filename += ".html"

        self.ui.lineEdit_OutputFilename.setText(filename)

    def log(self, msg):
        if debug_mode:
            qDebug(msg)
class RectangleMapTool(QgsMapToolEmitPoint):

    rectangleCreated = pyqtSignal()
    deactivated = pyqtSignal()

    def __init__(self, canvas):
        self.canvas = canvas
        QgsMapToolEmitPoint.__init__(self, self.canvas)

        self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
        self.rubberBand.setColor(QColor(255, 0, 0, 100))
        self.rubberBand.setWidth(2)

        self.reset()

    def reset(self):
        self.startPoint = self.endPoint = None
        self.isEmittingPoint = False
        self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)

    def canvasPressEvent(self, e):
        self.startPoint = self.toMapCoordinates(e.pos())
        self.endPoint = self.startPoint
        self.isEmittingPoint = True

        self.showRect(self.startPoint, self.endPoint)

    def canvasReleaseEvent(self, e):
        self.isEmittingPoint = False
        if self.rectangle() is not None:
            self.rectangleCreated.emit()

    def canvasMoveEvent(self, e):
        if not self.isEmittingPoint:
            return

        self.endPoint = self.toMapCoordinates(e.pos())
        self.showRect(self.startPoint, self.endPoint)

    def showRect(self, startPoint, endPoint):
        self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)
        if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
            return

        point1 = QgsPointXY(startPoint.x(), startPoint.y())
        point2 = QgsPointXY(startPoint.x(), endPoint.y())
        point3 = QgsPointXY(endPoint.x(), endPoint.y())
        point4 = QgsPointXY(endPoint.x(), startPoint.y())

        self.rubberBand.addPoint(point1, False)
        self.rubberBand.addPoint(point2, False)
        self.rubberBand.addPoint(point3, False)
        # True to update canvas
        self.rubberBand.addPoint(point4, True)
        self.rubberBand.show()

    def rectangle(self):
        if self.startPoint is None or self.endPoint is None:
            return None
        elif self.startPoint.x() == self.endPoint.x() or \
                self.startPoint.y() == self.endPoint.y():
            return None

        return QgsRectangle(self.startPoint, self.endPoint)

    def setRectangle(self, rect):
        if rect == self.rectangle():
            return False

        if rect is None:
            self.reset()
        else:
            self.startPoint = QgsPointXY(rect.xMaximum(), rect.yMaximum())
            self.endPoint = QgsPointXY(rect.xMinimum(), rect.yMinimum())
            self.showRect(self.startPoint, self.endPoint)
        return True

    def deactivate(self):
        QgsMapTool.deactivate(self)
        self.deactivated.emit()
Example #42
0
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
from qgis.core import Qgis
from qgis.gui import QgsMapToolEmitPoint, QgsRubberBand

previousMapTool = iface.mapCanvas().mapTool()
myMapTool = QgsMapToolEmitPoint(iface.mapCanvas())

# create the polygon rubber band associated to the current canvas
myRubberBand = QgsRubberBand(iface.mapCanvas(), Qgis.Polygon)
# set rubber band style
color = QColor("red")
color.setAlpha(50)
myRubberBand.setColor(color)


def showCoordinates(currentPos):
    if myRubberBand and myRubberBand.numberOfVertices():
        myRubberBand.removeLastPoint()
        myRubberBand.addPoint(currentPos)


iface.mapCanvas().xyCoordinates.connect(showCoordinates)


def manageClick(currentPos, clickedButton):
    if clickedButton == Qt.LeftButton:
        myRubberBand.addPoint(currentPos)
    # terminate rubber band editing session
    if clickedButton == Qt.RightButton:
        # remove showCoordinates map canvas callback