Пример #1
0
    def runTestForLayer(self, layer, testname):
        tempdir = tempfile.mkdtemp()

        layer = QgsVectorLayer(layer, 'Layer', 'ogr')
        QgsProject.instance().addMapLayer(layer)
        self.iface.mapCanvas().setExtent(layer.extent())

        geom = next(layer.getFeatures()).geometry()

        highlight = QgsHighlight(self.iface.mapCanvas(), geom, layer)
        color = QColor(Qt.red)
        highlight.setColor(color)
        highlight.setWidth(2)
        color.setAlpha(50)
        highlight.setFillColor(color)
        highlight.show()

        image = QImage(QSize(400, 400), QImage.Format_ARGB32)
        image.fill(Qt.white)
        painter = QPainter()
        painter.begin(image)
        self.iface.mapCanvas().render(painter)
        painter.end()
        control_image = os.path.join(tempdir, 'highlight_{}.png'.format(testname))
        image.save(control_image)
        checker = QgsRenderChecker()
        checker.setControlPathPrefix("highlight")
        checker.setControlName("expected_highlight_{}".format(testname))
        checker.setRenderedImage(control_image)
        self.assertTrue(checker.compareImages("highlight_{}".format(testname)))
        shutil.rmtree(tempdir)
class Settings():
    def __init__(self):
        self.readSettings()

    def readSettings(self):
        '''Load the user selected settings. The settings are retained even when
        the user quits QGIS.'''
        qset = QSettings()
        self.guessNames = int(qset.value('/ShapeTools/GuessNames', 2))
        self.maxSegLength = float(qset.value('/ShapeTools/MaxSegLength',
                                             20.0))  # In km
        self.maxSegments = int(qset.value('/ShapeTools/MaxSegments', 1000))
        self.mtAzMode = int(qset.value('/ShapeTools/MtAzMode', 0))
        color = qset.value('ShapeTools/RubberBandColor', '#dea743')
        self.rubberBandColor = QColor(color)
        value = int(qset.value('ShapeTools/RubberBandOpacity', 192))
        self.rubberBandColor.setAlpha(value)
        color = qset.value('ShapeTools/MeasureLineColor', '#000000')
        self.measureLineColor = QColor(color)
        color = qset.value('ShapeTools/MeasureTextColor', '#000000')
        self.measureTextColor = QColor(color)
        acronym = qset.value('ShapeTools/Ellipsoid', 'WGS84')
        self.setEllipsoid(acronym)

    def setEllipsoid(self, acronym):
        if not ellipsoids.valid(acronym):
            acronym = 'WGS84'
        geod = ellipsoids.ellipsoid(acronym)
        self.ellipseAcronym = acronym
        self.ellipseDescription = ellipsoids.ellipsoidDescription(acronym)
Пример #3
0
 def canvasPressEvent(self, e):
     '''
     override, remember feature on click and move marker (create one if not
     drawn yet)
     '''
     if self._picked_feature is None:
         features = QgsMapToolIdentify(self.canvas).identify(
             e.pos().x(),
             e.pos().y(), self._layers,
             QgsMapToolIdentify.TopDownStopAtFirst)
         if len(features) == 0:
             return
         feature = features[0].mFeature
         self._picked_feature = feature.id()
     # there is a feature -> drag it
     self._dragging = True
     self.canvas.setCursor(self.drag_cursor)
     # not marked yet -> mark position
     if not self._marker:
         color = QColor(0, 0, 255)
         color.setAlpha(100)
         self._marker = QgsVertexMarker(self.canvas)
         self._marker.setColor(color)
         self._marker.setIconSize(10)
         self._marker.setIconType(QgsVertexMarker.ICON_CIRCLE)
         self._marker.setPenWidth(10)
     point = self.toMapCoordinates(e.pos())
     self._marker.setCenter(point)
Пример #4
0
 def customRender(self, capa):
     if self.params.colorContorn is None:
         self.params.colorContorn = self.params.colorBase
     total = self.params.numCategories
     alpha = mv.MAP_ALPHA_INI
     maxAlpha = (255 - mv.MAP_ALPHA_FIN)
     step = round((maxAlpha - alpha) / (total - 1))
     color = QColor(self.params.colorBase)
     decimals = self.params.maxDecimals(self.params.rangsCategories)
     categories = []
     for i, r in enumerate(self.params.rangsCategories):
         color.setAlpha(alpha)
         alpha = min(alpha + step, maxAlpha)
         if self.params.simbol is None:
             symbol = QgsSymbol.defaultSymbol(capa.geometryType())
         else:
             symbol = self.params.simbol.clone()
         self.setStrokeSymbology(symbol, self.params.colorContorn)
         symbol.setColor(color)
         f0 = self.params.numRang(r[0])
         f1 = self.params.numRang(r[1])
         label = QvApp().locale.toString(f0, 'f', decimals) + ' - ' + \
             QvApp().locale.toString(f1, 'f', decimals)
         category = QgsRendererRange(f0, f1, symbol, label)
         categories.append(category)
     renderer = QgsGraduatedSymbolRenderer(self.params.campCalculat,
                                           categories)
     renderer.setMode(QgsGraduatedSymbolRenderer.Custom)
     # renderer.setClassAttribute(str(decimals))
     capa.setRenderer(renderer)
     capa.setMapTipTemplate(self.params.calcTip())
     capa.triggerRepaint()
     return renderer
Пример #5
0
    def runTestForLayer(self, layer, testname):
        tempdir = tempfile.mkdtemp()

        layer = QgsVectorLayer(layer, 'Layer', 'ogr')
        QgsProject.instance().addMapLayer(layer)
        self.iface.mapCanvas().setExtent(layer.extent())

        geom = next(layer.getFeatures()).geometry()

        highlight = QgsHighlight(self.iface.mapCanvas(), geom, layer)
        color = QColor(Qt.red)
        highlight.setColor(color)
        highlight.setWidth(2)
        color.setAlpha(50)
        highlight.setFillColor(color)
        highlight.show()

        image = QImage(QSize(400, 400), QImage.Format_ARGB32)
        image.fill(Qt.white)
        painter = QPainter()
        painter.begin(image)
        self.iface.mapCanvas().render(painter)
        painter.end()
        control_image = os.path.join(tempdir, 'highlight_{}.png'.format(testname))
        image.save(control_image)
        checker = QgsRenderChecker()
        checker.setControlPathPrefix("highlight")
        checker.setControlName("expected_highlight_{}".format(testname))
        checker.setRenderedImage(control_image)
        self.assertTrue(checker.compareImages("highlight_{}".format(testname)))
        shutil.rmtree(tempdir)
Пример #6
0
    def highlight_feature(self, canvas_extent=CanvasExtent.Fixed):
        if self.canvas is None or not self.feature.isValid():
            return

        geom = self.feature.geometry()

        if geom is None:
            return

        if canvas_extent == CanvasExtent.Scale:
            feature_bounding_box = geom.boundingBox()
            feature_bounding_box = self.canvas.mapSettings(
            ).layerToMapCoordinates(self.layer, feature_bounding_box)
            extent = self.canvas.extent()
            if not extent.contains(feature_bounding_box):
                extent.combineExtentWith(feature_bounding_box)
                extent.scale(1.1)
                self.canvas.setExtent(extent)
                self.canvas.refresh()

        elif canvas_extent == CanvasExtent.Pan:
            centroid = geom.centroid()
            center = centroid.asPoint()

            center = self.canvas.mapSettings().layerToMapCoordinates(
                self.layer, center)
            self.canvas.zoomByFactor(1.0,
                                     center)  # refresh is done in this method

        # highlight
        self.delete_highlight()
        self.highlight = QgsHighlight(self.canvas, geom, self.layer)

        settings = QSettings()
        color = QColor(
            settings.value("/Map/highlight/color",
                           Qgis.DEFAULT_HIGHLIGHT_COLOR.name()))
        alpha = int(
            settings.value("/Map/highlight/colorAlpha",
                           Qgis.DEFAULT_HIGHLIGHT_COLOR.alpha()))
        buffer = 2 * float(
            settings.value("/Map/highlight/buffer",
                           Qgis.DEFAULT_HIGHLIGHT_BUFFER_MM))
        min_width = 2 * float(
            settings.value("/Map/highlight/min_width",
                           Qgis.DEFAULT_HIGHLIGHT_MIN_WIDTH_MM))

        self.highlight.setColor(color)  # sets also fill with default alpha
        color.setAlpha(alpha)
        self.highlight.setFillColor(color)  # sets fill with alpha
        self.highlight.setBuffer(buffer)
        self.highlight.setMinWidth(min_width)
        self.highlight.setWidth(4.0)
        self.highlight.show()

        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.delete_highlight)
        self.timer.start(3000)
Пример #7
0
    class AniObject(QObject):
        def __init__(self, band):
            super(CurrentSelection.AniObject, self).__init__()
            self.color = QColor()

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

        @alpha.setter
        def alpha(self, value):
            self.color.setAlpha(value)
Пример #8
0
    def canvasMoveEvent(self, event):
        if self.rb and not all([self.p1, self.p2, self.p3]):
            self.canvas.scene().removeItem(self.rb)
        if self.p1 and not self.p2:
            self.rb = QgsRubberBand(self.canvas, False)
            points = [
                self.p1,
                self.toLayerCoordinates(self.layer, event.pos())
            ]
            points = [QgsPoint(pt) for pt in points]
            self.rb.setToGeometry(QgsGeometry.fromPolyline(points), None)
            self.rb.setColor(QColor(0, 128, 255))
            self.rb.setWidth(1)
        elif self.p1 and self.p2 and not self.p3:
            self.rb = QgsRubberBand(self.canvas, False)
            p0 = self.toLayerCoordinates(self.layer, event.pos())
            x0 = p0.x()
            x1 = self.p1.x()
            x2 = self.p2.x()
            y0 = p0.y()
            y1 = self.p1.y()
            y2 = self.p2.y()
            dist = (abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) /
                    np.sqrt((y2 - y1)**2 + (x2 - x1)**2))

            a = np.array([self.p1.x(), self.p1.y()])
            b = np.array([self.p2.x(), self.p2.y()])
            ab = b - a
            self.seclength = np.linalg.norm(ab)
            self.midpoint = a + ab / 2
            self.width = dist / 2
            ab0 = ab / self.seclength
            self.ab0N = np.array([-ab0[1], ab0[0]])

            c1 = a + dist * self.ab0N
            c2 = b + dist * self.ab0N
            c3 = b - dist * self.ab0N
            c4 = a - dist * self.ab0N
            self.rbPoints = [c1, c2, c3, c4]
            points = [[
                QgsPointXY(c1[0], c1[1]),
                QgsPointXY(c2[0], c2[1]),
                QgsPointXY(c3[0], c3[1]),
                QgsPointXY(c4[0], c4[1])
            ]]
            self.rb.setToGeometry(QgsGeometry.fromPolygonXY(points), None)
            self.rb.setColor(QColor(0, 128, 255))
            fc = QColor(0, 128, 255)
            fc.setAlpha(128)
            self.rb.setFillColor(fc)
            self.rb.setWidth(1)
        else:
            pass
Пример #9
0
    def setHighlight(self, ly, vertex):
        if self.highlight:
            self.highlight.hide()
            self.highlight = None
        if vertex:
            color = QColor(255, 0, 100, 255)
            lv = vertex + [vertex[0]]
            g = QgsGeometry.fromPolyline(lv).convertToType(2)

            print(g.asWkt(3))
            self.highlight = QgsHighlight(self.iface.mapCanvas(), g, ly)
            self.highlight.setColor(color)
            self.highlight.setWidth(5)
            color.setAlpha(50)
            self.highlight.setFillColor(color)
            self.highlight.show()
Пример #10
0
 def start_new_polygon(self):
     # set rubber band style
     color = QColor("red")
     color.setAlpha(40)
     # create the main polygon rubber band
     self.rubber_band = QgsRubberBand(
         self.navigation_dialog.render_widget.canvas,
         QgsWkbTypes.PolygonGeometry)
     self.rubber_band.setColor(color)
     self.rubber_band.setWidth(3)
     # create the mouse/tmp polygon rubber band, this is main rubber band + current mouse position
     self.aux_rubber_band = QgsRubberBand(
         self.navigation_dialog.render_widget.canvas,
         QgsWkbTypes.PolygonGeometry)
     self.aux_rubber_band.setColor(color)
     self.aux_rubber_band.setWidth(3)
    def __init__(self):
        self.iface = iface

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

        self.rb = QgsRubberBand(self.iface.mapCanvas(), QGisGeometryType.Point)
        self.rb.setColor(QColor('magenta'))
        self.rb.setIconSize(12)

        self.features_rb = QgsRubberBand(self.iface.mapCanvas(), QGisGeometryType.Point)
        magenta_transp = QColor('#3388ff')
        magenta_transp.setAlpha(120)
        self.features_rb.setColor(magenta_transp)
        self.features_rb.setIconSize(12)
        self.features_rb.setWidth(2)
Пример #12
0
class Settings():
    def __init__(self):
        self.readSettings()

    def readSettings(self):
        '''Load the user selected settings. The settings are retained even when
        the user quits QGIS.'''
        qset = QSettings()
        self.geomXName = qset.value('/ShapeTools/GeomXName', 'geom_x')
        self.geomYName = qset.value('/ShapeTools/GeomYName', 'geom_y')
        self.maxSegLength = float(qset.value('/ShapeTools/MaxSegLength',
                                             20.0))  # In km
        self.maxSegments = int(qset.value('/ShapeTools/MaxSegments', 1000))
        self.mtAzMode = int(qset.value('/ShapeTools/MtAzMode', 0))
        self.measureSignificantDigits = int(
            qset.value('/ShapeTools/MeasureSignificantDigits', 2))
        self.saveToLayerSignificantDigits = int(
            qset.value('/ShapeTools/SaveToLayerSignificantDigits', 2))
        color = qset.value('/ShapeTools/RubberBandColor', '#dea743')
        self.rubberBandColor = QColor(color)
        value = int(qset.value('/ShapeTools/RubberBandOpacity', 192))
        self.rubberBandColor.setAlpha(value)
        color = qset.value('/ShapeTools/MeasureLineColor', '#000000')
        self.measureLineColor = QColor(color)
        color = qset.value('/ShapeTools/MeasureTextColor', '#000000')
        self.measureTextColor = QColor(color)
        acronym = qset.value('/ShapeTools/Ellipsoid', 'WGS84')
        self.setEllipsoid(acronym)

    def getGeomNames(self, names=[]):
        index = 1
        name_x = self.geomXName
        names = set(names)
        while name_x in names:
            name_x = '{}{}'.format(self.geomXName, index)
            index += 1
        name_y = self.geomYName
        while name_y in names:
            name_y = '{}{}'.format(self.geomYName, index)
            index += 1
        return (name_x, name_y)

    def setEllipsoid(self, acronym):
        if not ellipsoids.valid(acronym):
            acronym = 'WGS84'
        self.ellipseAcronym = acronym
        self.ellipseDescription = ellipsoids.ellipsoidDescription(acronym)
Пример #13
0
    def test_feature_transformation(self):
        poly_shp = os.path.join(TEST_DATA_DIR, 'polys.shp')
        layer = QgsVectorLayer(poly_shp, 'Layer', 'ogr')

        sub_symbol = QgsFillSymbol.createSimple({
            'color': '#8888ff',
            'outline_style': 'no'
        })

        sym = QgsFillSymbol()
        buffer_layer = QgsGeometryGeneratorSymbolLayer.create(
            {'geometryModifier': 'buffer($geometry, -0.4)'})
        buffer_layer.setSymbolType(QgsSymbol.Fill)
        buffer_layer.setSubSymbol(sub_symbol)
        sym.changeSymbolLayer(0, buffer_layer)
        layer.setRenderer(QgsSingleSymbolRenderer(sym))

        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)
        self.assertEqual(canvas.width(), 600)
        self.assertEqual(canvas.height(), 400)

        canvas.setLayers([layer])
        canvas.setExtent(QgsRectangle(-11960254, 4247568, -11072454, 4983088))
        canvas.show()

        # need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
        while not canvas.isDrawing():
            app.processEvents()
        canvas.waitWhileRendering()

        feature = layer.getFeature(1)
        self.assertTrue(feature.isValid())

        highlight = QgsHighlight(canvas, feature, layer)
        color = QColor(Qt.red)
        highlight.setColor(color)
        color.setAlpha(50)
        highlight.setFillColor(color)
        highlight.show()
        highlight.show()

        self.assertTrue(
            self.canvasImageCheck('highlight_transform', 'highlight_transform',
                                  canvas))
Пример #14
0
    def define_polygon(self):
        # clean the aux rubber band
        self.aux_rubber_band.reset(QgsWkbTypes.PolygonGeometry)
        self.aux_rubber_band = None
        # adjust the color
        color = QColor("red")
        color.setAlpha(80)
        self.rubber_band.setColor(color)
        self.rubber_band.setWidth(3)
        # save
        new_feature = QgsFeature()
        new_feature.setGeometry(self.rubber_band.asGeometry())
        self.navigation_dialog.aoi_drawn.append(self.rubber_band)
        #
        self.navigation_dialog.DeleteAllAOI.setEnabled(True)

        self.start_new_polygon()
Пример #15
0
 def __init__(self, cad):
     QgsMapTool.__init__(self, cad.render_widget.canvas)
     self.cad = cad
     # set rubber band style
     color = QColor("red")
     color.setAlpha(70)
     # create the main polygon rubber band
     self.rubber_band = QgsRubberBand(cad.render_widget.canvas,
                                      QgsWkbTypes.PolygonGeometry)
     self.rubber_band.setColor(color)
     self.rubber_band.setWidth(3)
     # create the mouse/tmp polygon rubber band, this is main rubber band + current mouse position
     self.tmp_rubber_band = QgsRubberBand(cad.render_widget.canvas,
                                          QgsWkbTypes.PolygonGeometry)
     self.tmp_rubber_band.setColor(color)
     self.tmp_rubber_band.setWidth(3)
     self.tmp_rubber_band.setLineStyle(Qt.DotLine)
Пример #16
0
 def __init__(self, canvas, parent=None):
     super(ScaleBarItem, self).__init__(parent)
     self.canvas = canvas
     self.realsize = 100
     black = QColor(Qt.black)
     black.setAlpha(150)
     white = QColor(Qt.white)
     white.setAlpha(150)
     blackpen = QPen(black, 4)
     whitepen = QPen(white, 8)
     self.pens = [whitepen, blackpen]
     self.whitepen = QPen(white, 1)
     self.blackbrush = QBrush(black)
     self.ticksize = 10
     self.fontsize = 15
     self.font = QFont()
     self.font.setPointSize(self.fontsize)
     self.font.setStyleHint(QFont.Times, QFont.PreferAntialias)
     self.font.setBold(True)
     self.metrics = QFontMetrics(self.font)
Пример #17
0
    def visible_aoi(self):
        # first clean all rubber bands
        [rubber_band.reset() for rubber_band in self.rubber_bands]
        [rubber_band.reset() for rubber_band in self.tmp_rubber_bands]
        self.rubber_bands = []
        self.tmp_rubber_bands = []

        if self.VisibleAOI.isChecked() and self.aoi_features is not None:
            for feat in self.aoi_features.getFeatures():
                color = QColor("red")
                color.setAlpha(70)
                rubber_band = QgsRubberBand(self.canvas,
                                            QgsWkbTypes.PolygonGeometry)
                rubber_band.setToGeometry(feat.geometry())
                rubber_band.setColor(color)
                rubber_band.setWidth(3)
                self.rubber_bands.append(rubber_band)
                tmp_rubber_band = QgsRubberBand(self.canvas,
                                                QgsWkbTypes.PolygonGeometry)
                tmp_rubber_band.setToGeometry(feat.geometry())
                tmp_rubber_band.setColor(color)
                tmp_rubber_band.setWidth(3)
                tmp_rubber_band.setLineStyle(Qt.DotLine)
                self.tmp_rubber_bands.append(tmp_rubber_band)
Пример #18
0
class QdrawSettings(QWidget):
    """Window used to change settings (transparency/color)"""
    settingsChanged = pyqtSignal()

    def __init__(self):
        QWidget.__init__(self)

        self.setWindowTitle(self.tr('Qdraw - Settings'))
        self.setFixedSize(320, 100)
        self.center()

        # default color
        self.color = QColor(60, 151, 255, 255)

        self.sld_opacity = QSlider(Qt.Horizontal, self)
        self.sld_opacity.setRange(0, 255)
        self.sld_opacity.setValue(255)
        self.sld_opacity.tracking = True
        self.sld_opacity.valueChanged.connect(self.handler_opacitySliderValue)
        self.lbl_opacity = QLabel(self.tr('Opacity') + ': 100%', self)

        self.dlg_color = QColorDialog(self)
        btn_chColor = QPushButton(self.tr('Change the drawing color'), self)
        btn_chColor.clicked.connect(self.handler_chColor)

        vbox = QVBoxLayout()
        vbox.addWidget(self.lbl_opacity)
        vbox.addWidget(self.sld_opacity)
        vbox.addWidget(btn_chColor)
        self.setLayout(vbox)

    def tr(self, message):
        return QCoreApplication.translate('Qdraw', message)

    def handler_opacitySliderValue(self, val):
        self.color.setAlpha(val)
        self.lbl_opacity.setText(
            self.tr('Opacity') + ': ' + str(int((float(val) / 255) * 100)) +
            '%')
        self.settingsChanged.emit()

    def handler_chColor(self):
        color = self.dlg_color.getColor(self.color)
        if color.isValid():
            color.setAlpha(self.color.alpha())
            self.color = color
            self.settingsChanged.emit()
            self.close()

    def getColor(self):
        return self.color

    def center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def closeEvent(self, e):
        self.clear()
        e.accept()

    def clear(self):
        return
Пример #19
0
class QdrawSettings(QWidget):
    """Window used to change settings (transparency/color)"""
    settingsChanged = pyqtSignal()

    def __init__(self):
        QWidget.__init__(self)

        self.setWindowTitle(self.tr('Qdraw - Settings'))
        self.setFixedSize(320, 100)
        self.center()

        # default color
        self.color = QColor(60, 151, 255, 255)

        self.sld_opacity = QSlider(Qt.Horizontal, self)
        self.sld_opacity.setRange(0, 255)
        self.sld_opacity.setValue(255)
        self.sld_opacity.tracking = True
        self.sld_opacity.valueChanged.connect(self.handler_opacitySliderValue)
        self.lbl_opacity = QLabel(self.tr('Opacity') + ': 100%', self)

        self.dlg_color = QColorDialog(self)
        btn_chColor = QPushButton(self.tr('Change the drawing color'), self)
        btn_chColor.clicked.connect(self.handler_chColor)

        vbox = QVBoxLayout()
        vbox.addWidget(self.lbl_opacity)
        vbox.addWidget(self.sld_opacity)
        vbox.addWidget(btn_chColor)
        self.setLayout(vbox)

    def tr(self, message):
        return QCoreApplication.translate('Qdraw', message)

    def handler_opacitySliderValue(self, val):
        self.color.setAlpha(val)
        self.lbl_opacity.setText(
            self.tr('Opacity')+': '+str(int((float(val) / 255) * 100))+'%')
        self.settingsChanged.emit()

    def handler_chColor(self):
        color = self.dlg_color.getColor(self.color)
        if color.isValid():
            color.setAlpha(self.color.alpha())
            self.color = color
            self.settingsChanged.emit()
            self.close()

    def getColor(self):
        return self.color

    def center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def closeEvent(self, e):
        self.clear()
        e.accept()

    def clear(self):
        return
Пример #20
0
class LineMapTool(MapTool, QgsMapToolEmitPoint):
    '''
    draw a line on the map (connected, multiple sections)

    Attributes
    ----------
    drawn : pyqtSignal
        emitted after double click or right click on the map canvas, emits the
        drawn line
    '''
    drawn = pyqtSignal(QgsGeometry)
    wkbtype = QgsWkbTypes.LineGeometry

    def __init__(self,
                 ui_element: QWidget,
                 canvas: QgsMapCanvas = None,
                 color: Union[str, int] = None,
                 draw_markers=False,
                 line_width: int = 2,
                 line_style: int = Qt.SolidLine,
                 snap_geometry: QgsGeometry = None,
                 target_epsg: int = 25832):
        '''
        Parameters
        ----------
        ui_element : QWidget
            clickable UI element, clicking it will activate/deactivate this
            tool
        canvas : QgsMapCanvas, optional
            the map canvas the tool will work on, defaults to the map canvas of
            the QGIS UI
        color : int or str, optional
            color description, sets color of line and markers while
            drawing, defaults to blue
        draw_markers : bool, optional
            draw markers between segments of the line, defaults to no markers
        line_width : int, optional
            width of drawn lines in pixels, defaults to 2 pixels
        line_style : int, optional
            style of drawn lines (e.g. Qt.DashDotLine), defaults to solid line
        snap_geometry : QgsGeometry, optional
            snap drawn lines to outline of given geometry, defaults to no
            snapping
        target_epsg : int, optional
            projection of emitted geometry after drawing as epsg code,
            defaults to 25832
        '''
        self.canvas = canvas
        MapTool.__init__(self, ui_element, self.canvas)
        QgsMapToolEmitPoint.__init__(self, canvas=self.canvas)
        self.rubberband = QgsRubberBand(self.canvas, self.wkbtype)
        self.color = QColor(color) if color else QColor(0, 0, 255)
        self.rubberband.setColor(self.color)
        self.color.setAlpha(100)
        self.rubberband.setFillColor(self.color)
        self.rubberband.setLineStyle(line_style)
        self.rubberband.setWidth(line_width)

        self.snap_geometry = self.set_snap_geometry(snap_geometry)
        self.draw_markers = draw_markers
        if self.draw_markers:
            # auto points on outline should but doesn't work:
            #self.drawing_lines.setIcon(QgsRubberBand.ICON_CIRCLE)
            #self.drawing_lines.setIconSize(8)

            # drawing markers manually instead
            self.markers = []

        self._drawing = False
        self._moving = False

        # marker for showing snapped point on move
        self._move_marker = QgsVertexMarker(self.canvas)
        self._move_marker.setColor(self.color)
        self._move_marker.setIconType(QgsVertexMarker.ICON_CIRCLE)
        self._move_marker.setIconSize(10)
        self._move_marker.setPenWidth(3)

        self.reset()

    def set_snap_geometry(self, geom: QgsGeometry):
        '''
        snap lines to outline of given geometry

        Parameters
        ----------
        snap_geometry : QgsGeometry
            geometry to snap lines to
        '''
        if not geom:
            return
        if SHAPELY_LOADED:
            self.snap_geometry = wkt.loads(geom.asWkt()).boundary
        # alternative for MacOS
        else:
            self.snap_geometry = QgsCurvePolygon()
            self.snap_geometry.fromWkt(geom.asWkt())

    def reset(self):
        '''
        reset drawing
        '''
        scene = self.canvas.scene()
        if self.draw_markers:
            for m in self.markers:
                scene.removeItem(m)
            self.markers = []
        self._moving = False
        self._drawing = False
        self.rubberband.reset(self.wkbtype)

    def canvasDoubleClickEvent(self, e):
        '''
        override, emit line on double click
        '''
        if self._moving:
            self.rubberband.removeLastPoint()
        geom = self.rubberband.asGeometry()
        self.drawn.emit(self.transform_from_map(geom))
        self.reset()

    def _snap(self, point: QgsPoint) -> QgsPointXY:
        '''
        snap point to snap-geometry
        '''
        point = self.transform_from_map(point)
        if SHAPELY_LOADED:
            p = geometry.Point(point.x(), point.y())
            np = nearest_points(self.snap_geometry, p)[0]
            p = QgsPointXY(np.x, np.y)
        # alternative for MacOS
        else:
            closest = QgsGeometryUtils.closestPoint(
                self.snap_geometry, QgsPoint(point.x(), point.y()))
            p = QgsPointXY(closest.x(), closest.y())
        p = self.transform_to_map(p)
        return p

    def canvasPressEvent(self, e):
        '''
        override, finish line segment when map is clicked
        '''
        if (e.button() == Qt.RightButton):
            if self._moving:
                self.rubberband.removeLastPoint()
            geom = self.rubberband.asGeometry()
            self.drawn.emit(self.transform_from_map(geom))
            self.reset()
            return
        self._moving = False
        self._drawing = True
        point = self.toMapCoordinates(e.pos())
        if self.snap_geometry:
            point = self._snap(point)
        self.rubberband.addPoint(point, True)
        if self.draw_markers:
            marker = QgsVertexMarker(self.canvas)
            marker.setCenter(point)
            marker.setColor(self.color)
            marker.setIconSize(8)
            marker.setIconType(QgsVertexMarker.ICON_CIRCLE)
            marker.setPenWidth(4)
            self.markers.append(marker)

    def canvasMoveEvent(self, e):
        '''
        override, draw connecting line to last segment when moving mouse
        '''
        if not self.snap_geometry and not self._drawing:
            return
        point = self.toMapCoordinates(e.pos())
        if self.snap_geometry:
            point = self._snap(point)
        if self.snap_geometry:
            self._move_marker.setCenter(point)
        if self._drawing:
            #self.rubberBand.removeLastPoint()
            if self._moving:
                self.rubberband.removeLastPoint()
            self.rubberband.addPoint(point, True)
            self._moving = True

    def disconnect(self, **kwargs):
        '''
        override, 'remove' marker
        '''
        if self._move_marker:
            #scene = self.canvas.scene()
            #scene.removeItem(self._move_marker)
            # workaround: if removed from scene marker won't appear any more
            # set it somewhere it can't be seen
            self._move_marker.setCenter(QgsPointXY(0, 0))
        super().disconnect(**kwargs)
Пример #21
0
    def generate(self, writer, parameters, context, feedback):
        feedback.setProgress(1)

        extent = self.parameterAsExtent(parameters, self.EXTENT, context)
        self.min_zoom = self.parameterAsInt(parameters, self.ZOOM_MIN, context)
        self.max_zoom = self.parameterAsInt(parameters, self.ZOOM_MAX, context)
        dpi = self.parameterAsInt(parameters, self.DPI, context)
        self.tile_format = self.formats[self.parameterAsEnum(
            parameters, self.TILE_FORMAT, context)]
        transparent = self.parameterAsBool(parameters, self.TRANSPARENT,
                                           context)
        quality = self.parameterAsInt(parameters, self.QUALITY, context)
        self.metatilesize = self.parameterAsInt(parameters, self.METATILESIZE,
                                                context)
        try:
            tile_width = self.parameterAsInt(parameters, self.TILE_WIDTH,
                                             context)
            tile_height = self.parameterAsInt(parameters, self.TILE_HEIGHT,
                                              context)
        except AttributeError:
            # for mbtiles we don't have such settings
            tile_width = 256
            tile_height = 256

        wgs_crs = QgsCoordinateReferenceSystem('EPSG:4326')
        dest_crs = QgsCoordinateReferenceSystem('EPSG:3857')

        project = context.project()
        src_to_wgs = QgsCoordinateTransform(project.crs(), wgs_crs,
                                            context.transformContext())
        wgs_to_dest = QgsCoordinateTransform(wgs_crs, dest_crs,
                                             context.transformContext())

        settings = QgsMapSettings()
        settings.setOutputImageFormat(QImage.Format_ARGB32_Premultiplied)
        settings.setDestinationCrs(dest_crs)
        settings.setLayers(self.layers)
        settings.setOutputDpi(dpi)
        canvas_red = QgsProject.instance().readNumEntry(
            'Gui', '/CanvasColorRedPart', 255)[0]
        canvas_green = QgsProject.instance().readNumEntry(
            'Gui', '/CanvasColorGreenPart', 255)[0]
        canvas_blue = QgsProject.instance().readNumEntry(
            'Gui', '/CanvasColorBluePart', 255)[0]
        color = QColor(canvas_red, canvas_green, canvas_blue, 255)
        if self.tile_format == 'PNG' and transparent:
            color.setAlpha(0)
        settings.setBackgroundColor(color)

        # disable partial labels (they would be cut at the edge of tiles)
        labeling_engine_settings = settings.labelingEngineSettings()
        labeling_engine_settings.setFlag(
            QgsLabelingEngineSettings.UsePartialCandidates, False)
        settings.setLabelingEngineSettings(labeling_engine_settings)

        self.wgs_extent = src_to_wgs.transformBoundingBox(extent)
        self.wgs_extent = [
            self.wgs_extent.xMinimum(),
            self.wgs_extent.yMinimum(),
            self.wgs_extent.xMaximum(),
            self.wgs_extent.yMaximum()
        ]

        metatiles_by_zoom = {}
        metatiles_count = 0
        for zoom in range(self.min_zoom, self.max_zoom + 1):
            metatiles = get_metatiles(self.wgs_extent, zoom, self.metatilesize)
            metatiles_by_zoom[zoom] = metatiles
            metatiles_count += len(metatiles)

        lab_buffer_px = 100
        progress = 0

        tile_params = {
            'format': self.tile_format,
            'quality': quality,
            'width': tile_width,
            'height': tile_height,
            'min_zoom': self.min_zoom,
            'max_zoom': self.max_zoom,
            'extent': self.wgs_extent,
        }
        writer.set_parameters(tile_params)

        for zoom in range(self.min_zoom, self.max_zoom + 1):
            feedback.pushConsoleInfo('Generating tiles for zoom level: %s' %
                                     zoom)

            for i, metatile in enumerate(metatiles_by_zoom[zoom]):
                if feedback.isCanceled():
                    break

                size = QSize(tile_width * metatile.rows(),
                             tile_height * metatile.columns())
                extent = QgsRectangle(*metatile.extent())
                settings.setExtent(wgs_to_dest.transformBoundingBox(extent))
                settings.setOutputSize(size)

                image = QImage(size, QImage.Format_ARGB32_Premultiplied)
                image.fill(Qt.transparent)
                dpm = settings.outputDpi() / 25.4 * 1000
                image.setDotsPerMeterX(dpm)
                image.setDotsPerMeterY(dpm)
                painter = QPainter(image)
                job = QgsMapRendererCustomPainterJob(settings, painter)
                job.renderSynchronously()
                painter.end()

                # For analysing metatiles (labels, etc.)
                # metatile_dir = os.path.join(output_dir, str(zoom))
                # os.makedirs(metatile_dir, exist_ok=True)
                # image.save(os.path.join(metatile_dir, 'metatile_%s.png' % i))

                for r, c, tile in metatile.tiles:
                    tile_img = image.copy(tile_width * r, tile_height * c,
                                          tile_width, tile_height)
                    writer.write_tile(tile, tile_img)

                progress += 1
                feedback.setProgress(100 * (progress / metatiles_count))

        writer.close()
Пример #22
0
 def calcColorsGradient(self, colorBase):
     colorIni = QColor(colorBase)
     colorIni.setAlpha(mv.MAP_ALPHA_INI)
     colorFi = QColor(colorBase)
     colorFi.setAlpha(255 - mv.MAP_ALPHA_FIN)
     return colorIni, colorFi