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)
def exportAsSvg(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As SVG'), '', self.tr('SVG files (*.svg *.SVG)')) if not filename: return if not filename.lower().endswith('.svg'): filename += '.svg' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) svgRect = QRectF(0, 0, totalRect.width(), totalRect.height()) svg = QSvgGenerator() svg.setFileName(filename) svg.setSize(QSize(totalRect.width(), totalRect.height())) svg.setViewBox(svgRect) svg.setTitle(self.model.displayName()) painter = QPainter(svg) self.scene.render(painter, svgRect, totalRect) painter.end() self.bar.pushMessage("", self.tr("Model was correctly exported as SVG"), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def testRenderRegion(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a guide, to ensure it is not included in export g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) # get width/height, create image and render the composition to it size = QSize(560, 509) output_image = QImage(size, QImage.Format_RGB32) output_image.setDotsPerMeterX(self.dots_per_meter) output_image.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) exporter = QgsLayoutExporter(l) exporter.renderRegion(painter, QRectF(5, 10, 110, 100)) painter.end() rendered_file_path = os.path.join(self.basetestpath, 'test_renderregion.png') output_image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('renderregion', 'renderregion', rendered_file_path))
def testLayout(self, page=0, pixelDiff=0): if self.layout is None: myMessage = "Layout not valid" return False, myMessage # load expected image self.setControlName("expected_" + self.test_name) # get width/height, create image and render the composition to it outputImage = QImage(self.size, QImage.Format_RGB32) outputImage.setDotsPerMeterX(self.dots_per_meter) outputImage.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(outputImage) p = QPainter(outputImage) self.layout.exporter().renderPage(p, page) p.end() renderedFilePath = QDir.tempPath() + QDir.separator() + QFileInfo(self.test_name).baseName() + "_rendered.png" outputImage.save(renderedFilePath, "PNG") self.setRenderedImage(renderedFilePath) testResult = self.runTest(self.test_name, pixelDiff) return testResult, self.report()
def renderGeometry(self, symbol, geom, buffer=20): f = QgsFeature() f.setGeometry(geom) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() extent = geom.get().boundingBox() # buffer extent by 10% if extent.width() > 0: extent = extent.buffered((extent.height() + extent.width()) / buffer) else: extent = extent.buffered(buffer / 2) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI context.expressionContext().setFeature(f) painter.begin(image) try: image.fill(QColor(0, 0, 0)) symbol.startRender(context) symbol.renderFeature(f, context) symbol.stopRender(context) finally: painter.end() return image
def testSimpleLineWithOffset(self): """ test that rendering a polygon with simple line symbol with offset results in closed line""" layer = QgsSimpleLineSymbolLayer() layer.setOffset(-1) symbol = QgsFillSymbol() symbol.changeSymbolLayer(0, layer) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() geom = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0))') f = QgsFeature() f.setGeometry(geom) extent = geom.geometry().boundingBox() # buffer extent by 10% extent = extent.buffer((extent.height() + extent.width()) / 20.0) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) image.fill(QColor(255, 255, 255)) symbol.startRender(context) symbol.renderFeature(f, context) symbol.stopRender(context) painter.end() self.assertTrue(self.imageCheck('symbol_layer', 'fill_simpleline_offset', image))
def testRenderLineLayerDisabled(self): """ test that rendering a line symbol with disabled layer works""" layer = QgsSimpleLineSymbolLayer() layer.setEnabled(False) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, layer) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() geom = QgsGeometry.fromWkt('LineString (0 0,3 4,4 3)') f = QgsFeature() f.setGeometry(geom) extent = geom.constGet().boundingBox() # buffer extent by 10% extent = extent.buffered((extent.height() + extent.width()) / 20.0) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) image.fill(QColor(255, 255, 255)) symbol.startRender(context) symbol.renderFeature(f, context) symbol.stopRender(context) painter.end() self.assertTrue(self.imageCheck('symbol_layer', 'symbollayer_disabled', image))
def testRenderPage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) # get width/height, create image and render the composition to it size = QSize(1122, 794) output_image = QImage(size, QImage.Format_RGB32) output_image.setDotsPerMeterX(self.dots_per_meter) output_image.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) exporter = QgsLayoutExporter(l) # valid page exporter.renderPage(painter, 0) painter.end() rendered_file_path = os.path.join(self.basetestpath, 'test_renderpage.png') output_image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('renderpage', 'renderpage', rendered_file_path))
def exportAsPdf(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As PDF'), '', self.tr('PDF files (*.pdf *.PDF)')) if not filename: return if not filename.lower().endswith('.pdf'): filename += '.pdf' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) printerRect = QRectF(0, 0, totalRect.width(), totalRect.height()) printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel) printer.setFullPage(True) painter = QPainter(printer) self.scene.render(painter, printerRect, totalRect) painter.end() self.bar.pushMessage("", "Model was correctly exported as PDF", level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def _get_composer_image(self, width, height, dpi): image = QImage(QSize(width, height), self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing) ) self._c.renderPage(p, 0) p.end() # image = self._c.printPageAsRaster(0) # """:type: QImage""" if image.isNull(): return False, '' filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' return res, filepath
def renderMap(self): rendererContext = self.context if rendererContext.painter().device().logicalDpiX() != int(self.outputDpi): printScale = 25.4 / self.outputDpi # OL DPI to printer pixels rendererContext.painter().scale(printScale, printScale) # render OpenLayers to image painter = QPainter(self.img) self.page.mainFrame().render(painter) painter.end() if self.img.size() != self.targetSize: targetWidth = self.targetSize.width() targetHeight = self.targetSize.height() # scale using QImage for better quality debug(" scale image: %i x %i -> %i x %i" % ( self.img.width(), self.img.height(), targetWidth, targetHeight), 3) self.img = self.img.scaled(targetWidth, targetHeight, Qt.KeepAspectRatio, Qt.SmoothTransformation) # save current state self.page.lastExtent = rendererContext.extent() self.page.lastViewPortSize = rendererContext.painter().viewport().size() self.page.lastLogicalDpi = rendererContext.painter().device().logicalDpiX() self.page.lastOutputDpi = self.outputDpi self.page.lastMapUnitsPerPixel = rendererContext.mapToPixel().mapUnitsPerPixel()
def testFromQPainter(self): """ test QgsRenderContext.fromQPainter """ # no painter c = QgsRenderContext.fromQPainter(None) self.assertFalse(c.painter()) # assuming 88 dpi as fallback self.assertAlmostEqual(c.scaleFactor(), 88 / 25.4, 3) # no painter destination p = QPainter() c = QgsRenderContext.fromQPainter(p) self.assertEqual(c.painter(), p) self.assertEqual(c.testFlag(QgsRenderContext.Antialiasing), False) self.assertAlmostEqual(c.scaleFactor(), 88 / 25.4, 3) im = QImage(1000, 600, QImage.Format_RGB32) dots_per_m = 300 / 25.4 * 1000 # 300 dpi to dots per m im.setDotsPerMeterX(dots_per_m) im.setDotsPerMeterY(dots_per_m) p = QPainter(im) p.setRenderHint(QPainter.Antialiasing) c = QgsRenderContext.fromQPainter(p) self.assertEqual(c.painter(), p) self.assertEqual(c.testFlag(QgsRenderContext.Antialiasing), True) self.assertAlmostEqual(c.scaleFactor(), dots_per_m / 1000, 3) # scaleFactor should be pixels/mm
def exportAsPdf(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As PDF'), '', self.tr('PDF files (*.pdf *.PDF)')) if not filename: return if not filename.lower().endswith('.pdf'): filename += '.pdf' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) printerRect = QRectF(0, 0, totalRect.width(), totalRect.height()) printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel) printer.setFullPage(True) painter = QPainter(printer) self.scene.render(painter, printerRect, totalRect) painter.end() self.bar.pushMessage("", self.tr("Successfully exported model as PDF to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def exportAsSvg(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As SVG'), '', self.tr('SVG files (*.svg *.SVG)')) if not filename: return if not filename.lower().endswith('.svg'): filename += '.svg' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) svgRect = QRectF(0, 0, totalRect.width(), totalRect.height()) svg = QSvgGenerator() svg.setFileName(filename) svg.setSize(QSize(totalRect.width(), totalRect.height())) svg.setViewBox(svgRect) svg.setTitle(self.model.displayName()) painter = QPainter(svg) self.scene.render(painter, svgRect, totalRect) painter.end() self.bar.pushMessage("", self.tr("Successfully exported model as SVG to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def testRenderMarkerLayerDisabled(self): """ test that rendering a marker symbol with disabled layer works""" layer = QgsSimpleMarkerSymbolLayer() layer.setEnabled(False) symbol = QgsMarkerSymbol() symbol.changeSymbolLayer(0, layer) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() geom = QgsGeometry.fromWkt('Point (1 2)') f = QgsFeature() f.setGeometry(geom) extent = QgsRectangle(0, 0, 4, 4) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) image.fill(QColor(255, 255, 255)) symbol.startRender(context) symbol.renderFeature(f, context) symbol.stopRender(context) painter.end() self.assertTrue(self.imageCheck('symbol_layer', 'symbollayer_disabled', image))
def testCustomPainterRenderer(self): """ run test suite on QgsMapRendererCustomPainterJob""" im = QImage(200, 200, QImage.Format_RGB32) p = QPainter(im) def create_job(settings): return QgsMapRendererCustomPainterJob(settings, p) self.runRendererChecks(create_job) p.end()
def _svg_to_png(svg_file_path, rendered_file_path, width): svgr = QSvgRenderer(svg_file_path) height = width / svgr.viewBoxF().width() * svgr.viewBoxF().height() image = QImage(width, height, QImage.Format_ARGB32) image.fill(Qt.transparent) p = QPainter(image) p.setRenderHint(QPainter.Antialiasing, False) svgr.render(p) p.end() res = image.save(rendered_file_path, 'png') if not res: os.unlink(rendered_file_path)
def image(self): width = (self.xmax - self.xmin + 1) * self.TILE_SIZE height = (self.ymax - self.ymin + 1) * self.TILE_SIZE image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) p = QPainter(image) for tile in list(self.tiles.values()): if not tile.data: continue x = tile.x - self.xmin y = tile.y - self.ymin rect = QRect(x * self.TILE_SIZE, y * self.TILE_SIZE, self.TILE_SIZE, self.TILE_SIZE) timg = QImage() timg.loadFromData(tile.data) p.drawImage(rect, timg) return image
def exportAsImage(self): filename = unicode(QFileDialog.getSaveFileName(self, self.tr('Save Model As Image'), '', self.tr('PNG files (*.png *.PNG)'))) if not filename: return if not filename.lower().endswith('.png'): filename += '.png' totalRect = QRectF(0, 0, 1, 1) for item in self.scene.items(): totalRect = totalRect.united(item.sceneBoundingRect()) totalRect.adjust(-10, -10, 10, 10) img = QImage(totalRect.width(), totalRect.height(), QImage.Format_ARGB32_Premultiplied) img.fill(Qt.white) painter = QPainter() painter.setRenderHint(QPainter.Antialiasing) painter.begin(img) self.scene.render(painter, totalRect, totalRect) painter.end() img.save(filename)
def exportAsImage(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As Image'), '', self.tr('PNG files (*.png *.PNG)')) if not filename: return if not filename.lower().endswith('.png'): filename += '.png' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) imgRect = QRectF(0, 0, totalRect.width(), totalRect.height()) img = QImage(totalRect.width(), totalRect.height(), QImage.Format_ARGB32_Premultiplied) img.fill(Qt.white) painter = QPainter() painter.setRenderHint(QPainter.Antialiasing) painter.begin(img) self.scene.render(painter, imgRect, totalRect) painter.end() img.save(filename) self.bar.pushMessage("", self.tr("Successfully exported model as image to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def renderGeometry(self, geom): f = QgsFeature() f.setGeometry(geom) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() extent = geom.get().boundingBox() # buffer extent by 10% if extent.width() > 0: extent = extent.buffered((extent.height() + extent.width()) / 20.0) else: extent = extent.buffered(10) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) try: image.fill(QColor(0, 0, 0)) if geom.type() == QgsWkbTypes.PolygonGeometry: self.fill_symbol.startRender(context) self.fill_symbol.renderFeature(f, context) self.fill_symbol.stopRender(context) elif geom.type() == QgsWkbTypes.LineGeometry: self.line_symbol.startRender(context) self.line_symbol.renderFeature(f, context) self.line_symbol.stopRender(context) elif geom.type() == QgsWkbTypes.PointGeometry: self.marker_symbol.startRender(context) self.marker_symbol.renderFeature(f, context) self.marker_symbol.stopRender(context) else: self.fail("Unknown type: " + geom.type()) finally: painter.end() return image
def exportAsImage(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As Image'), '', self.tr('PNG files (*.png *.PNG)')) if not filename: return if not filename.lower().endswith('.png'): filename += '.png' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) imgRect = QRectF(0, 0, totalRect.width(), totalRect.height()) img = QImage(totalRect.width(), totalRect.height(), QImage.Format_ARGB32_Premultiplied) img.fill(Qt.white) painter = QPainter() painter.setRenderHint(QPainter.Antialiasing) painter.begin(img) self.scene.render(painter, imgRect, totalRect) painter.end() img.save(filename) self.bar.pushMessage("", "Model was correctly exported as image", level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def _get_composer_svg_image(self, width, height, dpi): # from qgscomposer.cpp, QgsComposer::on_mActionExportAsSVG_triggered, # near end of function svgpath = getTempfilePath('svg') temp_size = os.path.getsize(svgpath) svg_g = QSvgGenerator() # noinspection PyArgumentList svg_g.setTitle(QgsProject.instance().title()) svg_g.setFileName(svgpath) svg_g.setSize(QSize(width, height)) svg_g.setViewBox(QRect(0, 0, width, height)) svg_g.setResolution(dpi) sp = QPainter(svg_g) self._c.renderPage(sp, 0) sp.end() if temp_size == os.path.getsize(svgpath): return False, '' image = QImage(width, height, self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) svgr = QSvgRenderer(svgpath) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing) ) p.setRenderHint(QPainter.TextAntialiasing) svgr.render(p) p.end() filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' # TODO: remove .svg file as well? return res, filepath
def renderTile(self, x, y, feedback, make_trans): """ Render one tile :param x: The x index of the current tile :param y: The y index of the current tile """ if make_trans: background_color = QColor(255, 255, 255, 0) self.image.fill(background_color.rgba()) else: background_color = QColor(255, 255, 255) self.image.fill(background_color.rgb()) painter = QPainter(self.image) self.settings.setExtent(QgsRectangle( self.extent.xMinimum() + x * self.mupp * self.tile_size, self.extent.yMaximum() - (y + 1) * self.mupp * self.tile_size, self.extent.xMinimum() + (x + 1) * self.mupp * self.tile_size, self.extent.yMaximum() - y * self.mupp * self.tile_size)) job = QgsMapRendererCustomPainterJob(self.settings, painter) job.renderSynchronously() painter.end() # Needs not to be deleted or Windows will kill it too early... tmpfile = tempfile.NamedTemporaryFile(suffix='.png', delete=False) try: self.image.save(tmpfile.name) src_ds = osgeo.gdal.Open(tmpfile.name) self.dataset.WriteRaster(x * self.tile_size, y * self.tile_size, self.tile_size, self.tile_size, src_ds.ReadRaster(0, 0, self.tile_size, self.tile_size)) except Exception as e: feedback.reportError(str(e)) finally: del src_ds tmpfile.close() os.unlink(tmpfile.name)
def imageCheck(self, name, reference_image, image): self.report += "<h2>Render {}</h2>\n".format(name) temp_dir = QDir.tempPath() + '/' file_name = temp_dir + 'svg_' + name + ".png" output_image = QImage(image.size(), QImage.Format_RGB32) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) painter.drawImage(0, 0, image) painter.end() output_image.save(file_name, "PNG") checker = QgsRenderChecker() checker.setControlPathPrefix("svg_cache") checker.setControlName("expected_" + reference_image) checker.setRenderedImage(file_name) checker.setColorTolerance(2) result = checker.compareImages(name, 20) self.report += checker.report() print((self.report)) return result
def qt_svg_to_png_renderer(impact_report, component): """Render SVG into PNG. :param impact_report: ImpactReport contains data about the report that is going to be generated. :type impact_report: safe.report.impact_report.ImpactReport :param component: Contains the component metadata and context for rendering the output. :type component: safe.report.report_metadata.QgisComposerComponentsMetadata :return: Whatever type of output the component should be. .. versionadded:: 4.0 """ context = component.context filepath = context['filepath'] width = component.extra_args['width'] height = component.extra_args['height'] image_format = QImage.Format_ARGB32 qimage = QImage(width, height, image_format) qimage.fill(0x00000000) renderer = QSvgRenderer(filepath) painter = QPainter(qimage) renderer.render(painter) # Should call painter.end() so that QImage is not used painter.end() # in case output folder not specified if impact_report.output_folder is None: impact_report.output_folder = mkdtemp(dir=temp_dir()) output_path = impact_report.component_absolute_output_path( component.key) qimage.save(output_path) component.output = output_path return component.output
def __signal_pbSaveImg_clicked(self, cheked): if type(self.__fileNameImg) == tuple: self.__fileNameImg = self.__fileNameImg[0] fileName = QFileDialog.getSaveFileName(self, QApplication.translate( "OpenLayersOverviewWidget", "Save image"), self.__fileNameImg, QApplication.translate( "OpenLayersOverviewWidget", "Image(*.jpg)")) if not fileName == '': self.__fileNameImg = fileName else: return img = QImage(self.webViewMap.page().mainFrame().contentsSize(), QImage.Format_ARGB32_Premultiplied) imgPainter = QPainter() imgPainter.begin(img) self.webViewMap.page().mainFrame().render(imgPainter) imgPainter.end() img.save(fileName[0], "JPEG")
def testSimpleLineWithCustomDashPattern(self): """ test that rendering a simple line symbol with custom dash pattern""" layer = QgsSimpleLineSymbolLayer(QColor(0, 0, 0)) layer.setWidth(0.5) layer.setCustomDashVector([2, 5]) layer.setUseCustomDashPattern(True) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, layer) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() geom = QgsGeometry.fromWkt('LineString (0 0, 10 0, 10 10, 0 10, 0 0)') f = QgsFeature() f.setGeometry(geom) extent = geom.constGet().boundingBox() # buffer extent by 10% extent = extent.buffered((extent.height() + extent.width()) / 20.0) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) image.fill(QColor(255, 255, 255)) symbol.startRender(context) symbol.renderFeature(f, context) symbol.stopRender(context) painter.end() self.assertTrue(self.imageCheck('symbol_layer_simpleline_customdashpattern', 'simpleline_customdashpattern', image))
def renderAnnotation(self, annotation, offset): image = QImage(600, 400, QImage.Format_RGB32) image.fill(QColor(0, 0, 0, 0)) QgsRenderChecker.drawBackground(image) painter = QPainter() ms = QgsMapSettings() ms.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) extent = QgsRectangle(0, 5, 40, 30) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) painter.translate(offset.x(), offset.y()) annotation.render(context) painter.end() return image
def __init__(self, element, model, controls, scene=None): super(ModelerGraphicItem, self).__init__(None) self.controls = controls self.model = model self.scene = scene self.element = element if isinstance(element, QgsProcessingModelParameter): svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'input.svg')) self.picture = QPicture() painter = QPainter(self.picture) svg.render(painter) self.pixmap = None paramDef = self.model.parameterDefinition(element.parameterName()) if paramDef: self.text = paramDef.description() else: self.text = 'Error ({})'.format(element.parameterName()) elif isinstance(element, QgsProcessingModelOutput): # Output name svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'output.svg')) self.picture = QPicture() painter = QPainter(self.picture) svg.render(painter) self.pixmap = None self.text = element.name() else: if element.algorithm().svgIconPath(): svg = QSvgRenderer(element.algorithm().svgIconPath()) size = svg.defaultSize() self.picture = QPicture() painter = QPainter(self.picture) painter.scale(16 / size.width(), 16 / size.width()) svg.render(painter) self.pixmap = None else: self.pixmap = element.algorithm().icon().pixmap(15, 15) self.text = element.description() self.arrows = [] self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setZValue(1000) if controls: svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg')) picture = QPicture() painter = QPainter(picture) svg.render(painter) pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, ModelerGraphicItem.BOX_HEIGHT / 2 - FlatButtonGraphicItem.HEIGHT / 2) self.editButton = FlatButtonGraphicItem(picture, pt, self.editElement) self.editButton.setParentItem(self) svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'delete.svg')) picture = QPicture() painter = QPainter(picture) svg.render(painter) pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, FlatButtonGraphicItem.HEIGHT / 2 - ModelerGraphicItem.BOX_HEIGHT / 2) self.deleteButton = FlatButtonGraphicItem(picture, pt, self.removeElement) self.deleteButton.setParentItem(self) if isinstance(element, QgsProcessingModelChildAlgorithm): alg = element.algorithm() if [a for a in alg.parameterDefinitions() if not a.isDestination()]: pt = self.getLinkPointForParameter(-1) pt = QPointF(0, pt.y()) if controls: self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.parametersCollapsed()) self.inButton.setParentItem(self) if alg.outputDefinitions(): pt = self.getLinkPointForOutput(-1) pt = QPointF(0, pt.y()) if controls: self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsCollapsed()) self.outButton.setParentItem(self)
def paintEvent(self, paint_event): painter = QPainter(self) painter.translate(self.sizeHint().width(), self.sizeHint().height()) painter.rotate(270) painter.drawText(0, 0, self.text())
def paintEvent(self, event): self.updatePosition() painter = QPainter(self) painter.fillRect(self.rect(), Qt.transparent) painter.setRenderHint(QPainter.Antialiasing, True) if self.mCurrentCounter > self.mNumberOfLines: self.mCurrentCounter = 0 painter.setPen(Qt.NoPen) for i in range(self.mNumberOfLines): painter.save() painter.translate(self.mInnerRadius + self.mLineLength, self.mInnerRadius + self.mLineLength) rotateAngle = 360.0 * i / self.mNumberOfLines painter.rotate(rotateAngle) painter.translate(self.mInnerRadius, 0) distance = self.lineCountDistanceFromPrimary( i, self.mCurrentCounter, self.mNumberOfLines) color = self.currentLineColor(distance, self.mNumberOfLines, self.mTrailFadePercentage, self.mMinimumTrailOpacity, self.mColor) painter.setBrush(color) painter.drawRoundedRect( QRect(0, -self.mLineWidth // 2, self.mLineLength, self.mLineLength), self.mRoundness, Qt.RelativeSize) painter.restore()
def paintEvent(self, ev): sz = self.size() l = 0.5 * min(sz.width(), sz.height()) painter = QPainter(self) painter.setPen(Qt.NoPen) painter.setRenderHint(QPainter.Antialiasing, True) for i in range(0, self.ticks): painter.save() painter.translate(0.5 * sz.width(), 0.5 * sz.height()) painter.rotate((360. * i) / self.ticks) painter.translate(0.4 * l, 0) k = float(self.ticks + (i - self.counter)) % self.ticks / self.ticks painter.setBrush(QColor(0, 0, 0, 255 * (0.9 * k + 0.1))) painter.drawRoundedRect(QRect(0, -0.1 * l, 0.6 * l, 0.2 * l), 0.15 * l, 0.1 * l) painter.restore()
def update_summary_sheet(self,lyr=None, force=None): ''' Creates a summary sheet with thumbnail, layer metadata and online view link ''' #create a layer snapshot and upload it to google drive if not lyr: lyr = self.lyr mapbox_style = self.service_sheet.sheet_cell('settings!A5') if not mapbox_style: logger("migrating mapbox style") self.service_sheet.set_style_mapbox(self.layer_style_to_json(self.lyr)) if not force and not self.dirty and not self.restyled: return if self.restyled: self.service_sheet.set_style_qgis(self.layer_style_to_xml(self.lyr)) self.service_sheet.set_style_sld(self.SLD_to_xml(self.lyr)) self.service_sheet.set_style_mapbox(self.layer_style_to_json(self.lyr)) self.saveMetadataState() canvas = QgsMapCanvas() canvas.resize(QSize(600,600)) canvas.setCanvasColor(Qt.white) canvas.setExtent(lyr.extent()) canvas.setLayers([lyr]) canvas.refresh() canvas.update() settings = canvas.mapSettings() settings.setLayers([lyr]) job = QgsMapRendererParallelJob(settings) job.start() job.waitForFinished() image = job.renderedImage() transparent_image = QImage(image.width(), image.height(), QImage.Format_ARGB32) transparent_image.fill(Qt.transparent) p = QPainter(transparent_image) mask = image.createMaskFromColor(QColor(255, 255, 255).rgb(), Qt.MaskInColor) p.setClipRegion(QRegion(QBitmap(QPixmap.fromImage(mask)))) p.drawPixmap(0, 0, QPixmap.fromImage(image)) p.end() tmp_path = os.path.join(self.parent.plugin_dir,self.service_sheet.name+".png") transparent_image.save(tmp_path,"PNG") image_istances = self.service_drive.list_files(mimeTypeFilter='image/png',filename=self.service_sheet.name+".png") for imagename, image_props in image_istances.items(): self.service_drive.delete_file(image_props['id']) result = self.service_drive.upload_image(tmp_path) self.service_drive.add_permission(result['id'],'anyone','reader') webLink = result['webContentLink'] #'https://drive.google.com/uc?export=view&id='+result['id'] logger("webLink:" + webLink) canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) worldfile = QgsMapSettingsUtils.worldFileContent(settings) lonlat_min = self.transformToWGS84(QgsPointXY(canvas.extent().xMinimum(), canvas.extent().yMinimum())) lonlat_max = self.transformToWGS84(QgsPointXY(canvas.extent().xMaximum(), canvas.extent().yMaximum())) keymap_extent = [lonlat_min.x(),lonlat_min.y(),lonlat_max.x(),lonlat_max.y()] os.remove(tmp_path) #update layer metadata summary_id = self.service_sheet.add_sheet('summary', no_grid=True) appPropsUpdate = [ ["keymap",webLink], ["worldfile",pack(worldfile)], ["keymap_extent", json.dumps(keymap_extent)] ] res = self.service_sheet.update_appProperties(self.spreadsheet_id,appPropsUpdate) self.saveMetadataState(metadata=self.get_layer_metadata()) self.parent.public_db.setKey(self.spreadsheet_id, dict(self.get_layer_metadata()+appPropsUpdate),only_update=True) #merge cells to visualize snapshot and aaply image snapshot request_body = { 'requests': [{ 'mergeCells': { "range": { "sheetId": summary_id, "startRowIndex": 9, "endRowIndex": 32, "startColumnIndex": 0, "endColumnIndex": 9, }, "mergeType": 'MERGE_ALL' } }] } self.service_sheet.service.spreadsheets().batchUpdate(spreadsheetId=self.spreadsheet_id, body=request_body).execute() self.service_sheet.set_sheet_cell('summary!A10','=IMAGE("%s",3)' % webLink) permissions = self.service_drive.file_property(self.spreadsheet_id,'permissions') for permission in permissions: if permission['type'] == 'anyone': public = True break else: public = False if public: update_range = 'summary!A9:B9' update_body = { "range": update_range, "values": [['public link', "https://enricofer.github.io/gdrive_provider/weblink/converter.html?spreadsheet_id="+self.spreadsheet_id]] } self.service_sheet.service.spreadsheets().values().update(spreadsheetId=self.spreadsheet_id,range=update_range, body=update_body, valueInputOption='USER_ENTERED').execute() #hide worksheets except summary sheets = self.service_sheet.get_sheets() #self.service_sheet.toggle_sheet('summary', sheets['summary'], hidden=None) for sheet_name,sheet_id in sheets.items(): if not sheet_name == 'summary': self.service_sheet.toggle_sheet(sheet_name, sheet_id, hidden=True)
def drawMagnifierOnVideo(widget, dragPos, source, painter): ''' Draw Magnifier on Video ''' oldTransform = painter.transform() painter.setTransform(oldTransform) painter.setBrush(DrawToolBar.transparent_brush) dim = min(widget.width(), widget.height()) magnifierSize = min(MAX_MAGNIFIER, dim * 2 / 3) radius = magnifierSize / 2 ring = radius - 15 box = QSize(magnifierSize, magnifierSize) center = dragPos - QPoint(0, radius) center += QPoint(0, radius / 2) corner = center - QPoint(radius, radius) xy = center * MAX_FACTOR - QPoint(radius, radius) # only set the dimension to the magnified portion zoomPixmap = QPixmap(box) zoomPixmap.fill(Qt.black) painter_p = QPainter(zoomPixmap) painter_p.setRenderHint(QPainter.HighQualityAntialiasing) painter_p.translate(-xy) painter_p.scale(MAX_FACTOR, MAX_FACTOR) painter_p.drawImage(widget.surface.videoRect(), source, widget.surface.sourceRect()) painter_p.end() clipPath = QPainterPath() center = QPointF(center) # Shape Type if TYPE_MAGNIFIER == 0: # Square clipPath.addRect(center.x(), center.y(), magnifierSize, magnifierSize) clipPath.translate(-radius, -radius) else: # Circle clipPath.addEllipse(center, ring, ring) painter.setClipPath(clipPath) painter.drawPixmap(corner, zoomPixmap) painter.setPen(DrawToolBar.glass_pen) painter.drawPath(clipPath) return
def toSpriteSheet(allSprites): if allSprites: height = spriteSize width = spriteSize * len(allSprites) img = QImage(width, height, QImage.Format_ARGB32) img.fill(QColor(Qt.transparent)) img2x = QImage(width * 2, height * 2, QImage.Format_ARGB32) img2x.fill(QColor(Qt.transparent)) painter = QPainter(img) painter.begin(img) painter2x = QPainter(img2x) painter2x.begin(img2x) spritesheet = { NO_ICON: { "width": 0, "height": 0, "x": 0, "y": 0, "pixelRatio": 1 } } spritesheet2x = { NO_ICON: { "width": 0, "height": 0, "x": 0, "y": 0, "pixelRatio": 1 } } x = 0 for name, _sprites in allSprites.items(): s = _sprites["image"] s2x = _sprites["image2x"] painter.drawImage(x, 0, s) painter2x.drawImage(x * 2, 0, s2x) spritesheet[name] = { "width": s.width(), "height": s.height(), "x": x, "y": 0, "pixelRatio": 1 } spritesheet2x[name] = { "width": s2x.width(), "height": s2x.height(), "x": x * 2, "y": 0, "pixelRatio": 2 } x += s.width() painter.end() painter2x.end() folder = "/Users/ddd/delme/" img.save(os.path.join(folder, "spriteSheet.png")) img2x.save(os.path.join(folder, "*****@*****.**")) with open(os.path.join(folder, "spriteSheet.json"), 'w') as f: json.dump(spritesheet, f) with open(os.path.join(folder, "*****@*****.**"), 'w') as f: json.dump(spritesheet2x, f) return { "img": img, "img2x": img2x, "json": json.dumps(spritesheet), "json2x": json.dumps(spritesheet2x) } return None
def testRenderLayerWithReferenceScale(self): layer = QgsAnnotationLayer( 'test', QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext())) layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertTrue(layer.isValid()) item = QgsAnnotationPolygonItem( QgsPolygon( QgsLineString([ QgsPoint(12, 13), QgsPoint(14, 13), QgsPoint(14, 15), QgsPoint(12, 13) ]))) item.setSymbol( QgsFillSymbol.createSimple({ 'color': '200,100,100', 'outline_color': 'black', 'outline_width': '2' })) item.setZIndex(3) i1_id = layer.addItem(item) item = QgsAnnotationLineItem( QgsLineString( [QgsPoint(11, 13), QgsPoint(12, 13), QgsPoint(12, 15)])) item.setSymbol( QgsLineSymbol.createSimple({ 'color': '#ffff00', 'line_width': '3' })) item.setZIndex(2) i2_id = layer.addItem(item) item = QgsAnnotationMarkerItem(QgsPoint(12, 13)) item.setSymbol( QgsMarkerSymbol.createSimple({ 'color': '100,200,200', 'size': '6', 'outline_color': 'black' })) item.setZIndex(1) i3_id = layer.addItem(item) settings = QgsMapSettings() settings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326')) settings.setExtent(QgsRectangle(10, 10, 18, 18)) settings.setOutputSize(QSize(300, 300)) settings.setFlag(QgsMapSettings.Antialiasing, False) rc = QgsRenderContext.fromMapSettings(settings) layer.item(i1_id).setUseSymbologyReferenceScale(True) layer.item(i1_id).setSymbologyReferenceScale(rc.rendererScale() * 2) # note item 3 has use symbology reference scale set to false, so should be ignored layer.item(i2_id).setUseSymbologyReferenceScale(False) layer.item(i2_id).setSymbologyReferenceScale(rc.rendererScale() * 2) layer.item(i3_id).setUseSymbologyReferenceScale(True) layer.item(i3_id).setSymbologyReferenceScale(rc.rendererScale() * 2) image = QImage(200, 200, QImage.Format_ARGB32) image.setDotsPerMeterX(int(96 / 25.4 * 1000)) image.setDotsPerMeterY(int(96 / 25.4 * 1000)) image.fill(QColor(255, 255, 255)) painter = QPainter(image) rc.setPainter(painter) try: renderer = layer.createMapRenderer(rc) renderer.render() finally: painter.end() self.assertTrue( self.imageCheck('layer_render_reference_scale', 'layer_render_reference_scale', image)) # also check details of rendered items item_details = renderer.takeRenderedItemDetails() self.assertEqual([i.layerId() for i in item_details], [layer.id()] * 3) self.assertCountEqual([i.itemId() for i in item_details], [i1_id, i2_id, i3_id]) self.assertEqual( [i.boundingBox() for i in item_details if i.itemId() == i1_id][0], QgsRectangle(12, 13, 14, 15)) self.assertEqual( [i.boundingBox() for i in item_details if i.itemId() == i2_id][0], QgsRectangle(11, 13, 12, 15)) self.assertEqual([ i.boundingBox().toString(1) for i in item_details if i.itemId() == i3_id ][0], '11.4,12.4 : 12.6,13.6')
def testReprojectionErrorsWhileRendering(self): # WKT of a polygon which causes reprojection errors while rendering # (apologies for the ridiculously complex wkt, but I can't find a way to reproduce with simplifiction) wkt = 'MultiPolygon (((16.93392988400009358 42.77094147300012139, 16.88493899800005238 42.72939687700012712, ' \ '16.80298912900011032 42.76349518400014915, 16.85816491000014139 42.78400299700011544, ' \ '16.93392988400009358 42.77094147300012139)),((17.38200931100010393 42.79783763200002511, ' \ '17.65894616000011297 42.74298737200008702, 17.74887129000009622 42.69456614800010641, ' \ '17.32374108200008322 42.79083893400003547, 17.38200931100010393 42.79783763200002511)),' \ '((16.768565300000148 42.97223541900014254, 17.03207441500009622 42.98261139500014849, ' \ '17.13184655000009116 42.96954987200014386, 17.20020592500009116 42.92177969000012183, ' \ '16.85141035200010151 42.90070221600008438, 16.65544681100004709 42.92625560099999404, ' \ '16.70679772200014668 42.96954987200014386, 16.63168379000003938 42.98261139500014849, ' \ '16.768565300000148 42.97223541900014254)),((17.05567467500011958 43.02895742400001211, ' \ '17.24024498800011429 43.02277252800014651, 17.74146569100011561 42.83926015800001608, ' \ '17.70736738400009358 42.88703034100014122, 17.65334906206413734 42.8909283361407887, ' \ '17.70158573400010482 42.91950022500007833, 17.81175988700005064 42.909862570000044, ' \ '17.85847538200005147 42.81697418200012351, 18.22413781700009849 42.62807098500009317, ' \ '18.43735477700010961 42.55921213800017711, 18.4371480710000526 42.4934022020000981, ' \ '18.49642988400009358 42.41632721600008438, 18.23894290500010129 42.55906810100005089, ' \ '18.21753991000014139 42.6201032570001388, 18.07601972700010151 42.65131256700003348, ' \ '18.0432235040000819 42.70205312700007028, 17.90162194100014403 42.75189850500014188, ' \ '17.8928328790000819 42.79083893400003547, 17.72095787900005348 42.8262393250000315, ' \ '17.7618921230000808 42.77871328300012976, 17.74870853000004445 42.77204010600017625, ' \ '17.21387780000011958 42.98261139500014849, 17.04615319100011561 42.9950625670000619, ' \ '17.00163821700004974 43.05149974200010377, 17.05567467500011958 43.02895742400001211)),' \ '((16.19467207100007045 43.07440827000000638, 16.254893425000148 43.06854889500006323, ' \ '16.08716881600014403 43.01146067900008063, 16.04883873800011429 43.06517161700004692, ' \ '16.19467207100007045 43.07440827000000638)),((16.56275475400011032 43.22898997600010773, ' \ '16.65951582100009887 43.21596914300012315, 16.72771243600001867 43.16461823100003414, ' \ '17.19336998800014271 43.12726471600016964, 16.67017662900013875 43.12547435099999404, ' \ '16.37159264400014536 43.19550202000006323, 16.49642988400006516 43.21808502800014651, ' \ '16.58326256600014403 43.18866608300005794, 16.52051842500006273 43.22898997600010773, ' \ '16.56275475400011032 43.22898997600010773)),((16.80681399800010922 43.34247467700005529, ' \ '16.89234459700011826 43.31220123900006058, 16.84620201900008851 43.27338288000005662, ' \ '16.62826582100012729 43.26373932500008834, 16.50074303500014139 43.28424713700003679, ' \ '16.42188561300008587 43.31757233300011478, 16.40577233200011165 43.33270905200011214, ' \ '16.45346113400009358 43.35317617400009738, 16.42628014400008851 43.39411041900011412, ' \ '16.44703209700008983 43.39484284100014122, 16.80681399800010922 43.34247467700005529)),' \ '((16.29818769600012729 43.40363190300011809, 16.30274498800008587 43.38727448100009099, ' \ '16.39144941500012465 43.34638092700005529, 16.348643425000148 43.33869049700003018, ' \ '16.20045006600014403 43.40704987200003018, 16.29818769600012729 43.40363190300011809)),' \ '((16.33415774800010922 43.50153229400014254, 16.3752547540000819 43.49017975500008504, ' \ '16.21143639400008851 43.49005768400009231, 16.26441491000014139 43.51288483300011478, ' \ '16.33415774800010922 43.50153229400014254)),((15.67888431100004709 43.64801666900014254, ' \ '15.74040774800010922 43.62750885600009099, 15.67204837300002396 43.63743724200010377, ' \ '15.60377037900013875 43.67470937700007028, 15.67888431100004709 43.64801666900014254)),' \ '((15.36736087300005238 43.79010651200015047, 15.39568118600007551 43.7724063170000619, ' \ '15.22779381600014403 43.87445709800014981, 15.24073326900014536 43.88076406500009341, ' \ '15.36736087300005238 43.79010651200015047)),((15.44271894600009887 43.89907461100013109, ' \ '15.35865319100014403 43.91937897300014981, 15.26124108200011165 44.01105377800003282, ' \ '15.38404381600008719 43.9701602230000077, 15.44271894600009887 43.89907461100013109)),' \ '((15.22575931100010393 44.06622955900014915, 15.25440514400008851 44.01788971600014122, ' \ '15.12183678500014139 44.09223053600005926, 15.06251061300008587 44.16193268400012073, ' \ '15.22575931100010393 44.06622955900014915)),((14.83545983200014007 44.15102773600013109, ' \ '14.85726972700010151 44.15204498900000374, 14.86915123800014271 44.14052969000006499, ' \ '14.83521569100008719 44.14166901200009363, 14.81983483200014007 44.15302155199999845, ' \ '14.82243899800005238 44.16868724200004692, 14.83545983200014007 44.15102773600013109)),' \ '((14.98511803500011297 44.09096914300012315, 15.21680748800008587 43.91278717700008372, ' \ '15.13331139400011693 43.92121002800003282, 15.19450931100004709 43.87262604400017096, ' \ '15.10661868600007551 43.92544179900015422, 14.84961998800014271 44.17560455900014915, ' \ '14.98511803500011297 44.09096914300012315)),((14.765961134000122 44.26504140800015819, ' \ '14.74854576900014536 44.26166413000014188, 14.73959394600012729 44.28017812700015554, ' \ '14.79167728000007287 44.27252838700003679, 14.765961134000122 44.26504140800015819)),' \ '((14.66138756600011561 44.30866120000014519, 14.6407983730000808 44.31183502800003282, ' \ '14.59506269600007045 44.34711334800006455, 14.643565300000148 44.32575104400011412, ' \ '14.66138756600011561 44.30866120000014519)),((14.81120853000004445 44.35004303600000242, ' \ '14.75619550900009358 44.36399974200004692, 14.76343834700008983 44.41535065300017493, ' \ '14.80323326900008851 44.40550364800004957, 14.81120853000004445 44.35004303600000242)),' \ '((14.27116946700002131 44.61253489800004957, 14.23259524800005238 44.62604401200012205, ' \ '14.2657983730000808 44.67951080900003547, 14.28044681100007551 44.67755768400009231, ' \ '14.27116946700002131 44.61253489800004957)),((14.84522545700008322 44.60053131700011875, ' \ '14.93824303500014139 44.59414297100001079, 15.07553144600007045 44.48407623900006058, ' \ '14.91114342500011958 44.54547760600014783, 15.04802493600004709 44.43943919500001982, ' \ '15.09669030000009116 44.41518789300000947, 15.04151451900014536 44.47662995000008834, ' \ '15.25440514400008851 44.34003327000000638, 15.165049675000148 44.36737702000006323, ' \ '15.22022545700008322 44.3127302100001117, 15.13086998800008587 44.33258698100003414, ' \ '15.17237389400014536 44.29913971600016964, 15.12875410200007309 44.31199778900018771, ' \ '15.08920332100009887 44.37421295800000109, 15.11719811300014271 44.38719310099999404, ' \ '15.04900149800010922 44.39468008000015686, 14.89747155000009116 44.49091217699999845, ' \ '14.91863040500010129 44.50454336100013109, 14.87696373800011429 44.55975983300005794, ' \ '14.73365319100008719 44.70319245000014519, 14.84522545700008322 44.60053131700011875)),' \ '((14.41000410200010151 44.60097890800001608, 14.52662194100011561 44.50372955900012073, ' \ '14.53435306100010393 44.48407623900006058, 14.42261803500008455 44.57387929900009738, ' \ '14.36304772200014668 44.57343170800000109, 14.38257897200014668 44.60325755399999537, ' \ '14.33578535200007309 44.71678294500010509, 14.39747155000009116 44.6856143250000315, ' \ '14.41000410200010151 44.60097890800001608)),((14.75326582100007045 44.84585195500012844, ' \ '14.74048912900011032 44.82050202000000638, 14.82243899800005238 44.77142975500005662, ' \ '14.84961998800014271 44.70319245000014519, 14.65788821700004974 44.79877350500014188, ' \ '14.7268172540000819 44.79877350500014188, 14.6858016290000819 44.8471540390000456, ' \ '14.75326582100007045 44.84585195500012844)),((14.47103925900006516 44.95392487200003018, ' \ '14.45191491000008455 44.79877350500014188, 14.47217858200011165 44.7079531920000619, ' \ '14.53435306100010393 44.63426341400010244, 14.51335696700007816 44.618841864000089, ' \ '14.42790774800005238 44.65656159100014122, 14.29420006600008719 44.9086367860001161, ' \ '14.30152428500011297 44.94342682500014519, 14.38738040500004445 44.90900299700003018, ' \ '14.39031009200004974 44.96039459800012139, 14.41138756600008719 44.95636627800014651, ' \ '14.27849368600004709 45.1133487000000315, 14.29957116000014139 45.16233958499999801, ' \ '14.35621178500014139 45.16925690300008966, 14.387705925000148 45.03904857000013351, ' \ '14.47103925900006516 44.95392487200003018)),((14.56332441500012465 45.24974192900008063, ' \ '14.62378991000011297 45.17548248900006058, 14.59742272200011826 45.16644928600005926, ' \ '14.66529381600011561 45.16181061400011743, 14.66529381600011561 45.08734772300006455, ' \ '14.74048912900011032 45.07306549700014386, 14.81495201900008851 44.97748444200009033, ' \ '14.70639082100009887 44.9467227230000077, 14.62891686300014271 44.97817617400004053, ' \ '14.62086022200008983 45.04559967700011214, 14.61695397200008983 45.02464427300007799, ' \ '14.51050866000014139 45.03217194200011875, 14.43873131600014403 45.07050202000006323, ' \ '14.4670516290000819 45.12409088700015047, 14.53012129000009622 45.13483307500014519, ' \ '14.53435306100010393 45.23753489800002114, 14.56332441500012465 45.24974192900008063)),' \ '((16.36947066200013978 46.54057118800012915, 16.63767134600004738 46.47447703100009164, ' \ '16.75508020000012266 46.38187286400001597, 16.83765913900006694 46.38187286400001597, ' \ '16.88923221800007468 46.29216257800014489, 17.05294315600005461 46.15346303300005104, ' \ '17.20859257000006437 46.11656606000003933, 17.27587528500004055 46.01202463800002818, ' \ '17.31680301900004793 45.99765859000002877, 17.29013798000011093 45.98463612900009423, ' \ '17.40620324700006449 45.94365671800015605, 17.59110152100009827 45.93621531200012953, ' \ '17.65652388500006964 45.84541982000014571, 17.80917606600013414 45.81441396100005647, ' \ '17.85806197100004056 45.77172922800004073, 18.21121870900006456 45.78537180600012846, ' \ '18.40438521300006869 45.74180857400001798, 18.57347049900010916 45.81668772400014689, ' \ '18.6556360270001278 45.90758656800015558, 18.7755253500000947 45.88283355700004051, ' \ '18.90130578600007993 45.93120269800006383, 18.87288374800004931 45.89523590100002082, ' \ '18.90699019400011593 45.86795074500018643, 18.85531376100007606 45.85735707600009903, ' \ '18.84497847500006174 45.8157058720000947, 18.96848514800012708 45.66873809800016204, ' \ '18.90357954900008508 45.57308502200005762, 18.94171675700005153 45.53892689999999277, ' \ '19.01809452300011571 45.56740061400002162, 19.10625451700005328 45.51164174500017623, ' \ '19.00961958800010621 45.49867095900005154, 19.00300500400010151 45.45536611000007099, ' \ '19.03742150900006891 45.42229319300010104, 18.97592655400006834 45.39495636000008005, ' \ '19.09199182100007874 45.34999786400005917, 19.12475467900009107 45.29811472600006539, ' \ '19.36308638500014467 45.24824696900010679, 19.40783817500010855 45.20313344400013023, ' \ '19.39068160000005037 45.16933705700016333, 19.22593713300008744 45.16194732700016345, ' \ '19.12186079900010327 45.195795390000157, 19.13767378700009658 45.14603098600004216, ' \ '19.04486291500009543 45.13724599300006446, 19.08227665200013234 45.08494944300004192, ' \ '19.0872375890000967 44.97710072800013847, 19.13167932100006396 44.95317454000003465, ' \ '19.06667036900009293 44.90568389900012392, 18.99142948400006503 44.9149339800001286, ' \ '19.01582076000008215 44.86563466400004074, 18.88962691200009658 44.86119049100013001, ' \ '18.78338016700013213 44.91374542300012251, 18.79175174900009893 45.00154368100008639, ' \ '18.73831831900008638 45.0159097290000858, 18.68405806500004473 45.08479441400000098, ' \ '18.64871138500012648 45.06267689999999959, 18.61667199700013953 45.09766184500010411, ' \ '18.54959598800010667 45.09476796500011631, 18.51703983500007666 45.05585561200003042, ' \ '18.23788374800011525 45.15745147700012296, 18.15365116400005263 45.0975584930001645, ' \ '18.00347945100011771 45.1493382780000303, 17.83573775200005684 45.0644338990000648, ' \ '17.68473921700012852 45.1639627080000281, 17.48185754400009273 45.11440500900012296, ' \ '17.49622359200009214 45.1416901650001563, 17.44775109900012922 45.13430043600014585, ' \ '17.44330692500011537 45.16205068000009248, 17.38243208800008688 45.1396231090000839, ' \ '17.26895064300006766 45.18954254200015441, 17.24548954300007608 45.15538442000017483, ' \ '17.18709517400012032 45.14856313100001728, 17.0363033440001459 45.23047027600007652, ' \ '17.00829471800011561 45.21615590500009318, 17.00829471800011561 45.24416453100009505, ' \ '16.94731652900014751 45.23568959600000028, 16.9243721930001243 45.28452382500016427, ' \ '16.81171757000004163 45.18122263700009, 16.52894413300009546 45.22225372400005483, ' \ '16.38921106000003647 45.11683380099999852, 16.31624393700010955 45.00123362300008978, ' \ '16.12152714000009723 45.09616322900008356, 16.02044803900011516 45.213933818000001, ' \ '15.79234826700013627 45.18980092400012438, 15.76361617000014803 44.97555043600003444, ' \ '15.7308533120001357 44.92723297200008403, 15.77343469200010873 44.84501576800015243, ' \ '15.71607385200013596 44.80320953400008932, 15.72847619600008784 44.76910308800002269, ' \ '15.80568078600006743 44.69665273000013883, 15.88877648900006534 44.72424794500012979, ' \ '15.96897831200004703 44.63924021400013942, 16.02830285600006732 44.62471913700009907, ' \ '16.04473596200011798 44.58937245700018082, 16.00608199000004106 44.54100331600012908, ' \ '16.11646285000011858 44.52146962500013672, 16.15966434700004584 44.41610138000002905, ' \ '16.13827030500004867 44.37760243800015303, 16.20286584400008678 44.35977406800010669, ' \ '16.18756962000011868 44.28241444999999032, 16.21578495300011014 44.20815541600011045, ' \ '16.32688928200008149 44.08237498000012522, 16.50103885900011846 43.99271637000008184, ' \ '16.67859908100004418 43.8406843060001421, 16.71260217300007866 43.77151540100005889, ' \ '17.03051558500007445 43.54847991900005866, 17.27050093600007585 43.46321380700000248, ' \ '17.28993127500007176 43.3034302780000786, 17.44206669100009321 43.15243174300015028, ' \ '17.6284119050001209 43.04657257100008394, 17.66272505700004558 42.96569895500012137, ' \ '17.63450972400008254 42.950402731000068, 17.51563561300008587 42.95888906500012183, ' \ '17.47087649800005238 43.01341380400010905, 17.50196373800014271 43.03099192900005221, ' \ '17.43360436300014271 43.01740143400009231, 17.46021569100011561 43.03099192900005221, ' \ '17.42611738400009358 43.06517161700004692, 17.4045516290000819 43.05149974200010377, ' \ '17.31625410200012993 43.12726471600016964, 17.11394290500004445 43.21320221600008438, ' \ '16.88062584700011826 43.40595123900006058, 16.62582441500009622 43.44904205900009231, ' \ '16.52466881600011561 43.51080963700009363, 16.39144941500012465 43.51080963700009363, ' \ '16.47339928500008455 43.5381533870001789, 16.43384850400013875 43.54975006700000506, ' \ '16.11768639400008851 43.52448151200003679, 16.17237389400014536 43.4896914730000077, ' \ '16.11312910200004467 43.47890859600009605, 15.95948326900011693 43.50397370000008834, ' \ '15.987315300000148 43.54490794500010509, 15.92530358200011165 43.55857982000004824, ' \ '15.91895592500009116 43.62872955900012073, 15.96631920700011165 43.64118073100003414, ' \ '15.90479576900014536 43.64801666900014254, 15.95297285200010151 43.65086497599999404, ' \ '15.95045006600008719 43.68854401200015047, 15.70630944100008719 43.76341380400005221, ' \ '15.6174422540000819 43.82550690300017493, 15.66309655000009116 43.81297435099999404, ' \ '15.67888431100004709 43.81928131700011875, 15.45508873800014271 43.92804596600014122, ' \ '15.14454186300011429 44.19546133000015686, 15.15219160200012993 44.23529694200014717, ' \ '15.11036217500011958 44.26434967700011214, 15.14063561300011429 44.28245677300013483, ' \ '15.17660566500009622 44.24994538000005662, 15.20777428500008455 44.27277252800014651, ' \ '15.19809004000012465 44.30166250200007028, 15.295258009000122 44.25067780199999845, ' \ '15.30274498800008587 44.29913971600016964, 15.26124108200011165 44.33258698100003414, ' \ '15.42448978000001603 44.26797109600006763, 15.52865644600009887 44.27179596600008438, ' \ '15.30795332100009887 44.35439687700007028, 15.00733483200014007 44.56972890800012976, ' \ '14.883799675000148 44.7236188820001388, 14.883799675000148 44.86147695500012844, 14.92164147200008983 ' \ '44.95880768400009231, 14.85279381600011561 45.09365469000000815, 14.65788821700004974 ' \ '45.19660065300017493, 14.57081139400008851 45.29364655200011214, 14.31153405000009116 ' \ '45.34398021000005485, 14.23259524800005238 45.14935944200000506, 14.17937259200007816 ' \ '45.13450755400005221, 14.19312584700008983 45.10561758000012844, 14.14389082100007045 ' \ '45.05939362200003018, 14.151377800000148 44.97748444200009033, 14.06885826900014536 ' \ '44.94953034100014122, 14.08383222700007309 44.9863955750000315, 14.04029381600014403 ' \ '45.03896719000015025, 14.0756942070000548 44.98371002800003282, 14.02051842500011958 ' \ '44.90110911700004692, 13.97266686300011429 44.90110911700004692, 13.99301191500009622 ' \ '44.88129303600014453, 13.97266686300011429 44.82664622599999404, 14.00001061300008587 ' \ '44.81305573100003414, 13.89014733200011165 44.83348216400010244, 13.91797936300014271 ' \ '44.77826569200009033, 13.90316816500009622 44.77240631700014717, 13.89698326900011693 ' \ '44.81305573100003414, 13.78711998800014271 44.87506745000008834, 13.84229576900008851 ' \ '44.88812897300006455, 13.79460696700010658 44.89496491100008768, 13.77409915500007287 ' \ '44.96381256700014717, 13.6232202480000808 45.07306549700014386, 13.61255944100014403 ' \ '45.11786530199999845, 13.72624759200004974 45.13450755400005221, 13.5959578790000819 ' \ '45.14541250200001343, 13.57545006600011561 45.26487864800007799, 13.60271243600001867 ' \ '45.28534577000012007, 13.57545006600011561 45.30646393400006389, 13.60954837300005238 ' \ '45.32013580900017757, 13.54127037900013875 45.34613678600005926, 13.50709069100014403 ' \ '45.51190827000000638, 13.62901778100007277 45.45898346000016943, 13.75929406800014476 ' \ '45.46316925100011019, 13.88900191200011136 45.42363678000005223, 13.98263960800005634 ' \ '45.47531321200001742, 13.97189091000012695 45.5142255660000643, 14.09291711400010172 ' \ '45.47391794800002174, 14.21869755100007637 45.49717234400004884, 14.37279667100006009 ' \ '45.47784535800009564, 14.4689148350000778 45.52559438100014688, 14.49857710800012001 ' \ '45.59618438800005435, 14.58094934100009255 45.66780792200010808, 14.66848921700008646 ' \ '45.53396596300005683, 14.79716353300005949 45.46518463200006011, 14.88160282300009385 ' \ '45.46978383400001178, 14.9226339110000481 45.51494903600017494, 15.13926151500010064 ' \ '45.43004465799999991, 15.32519331800011742 45.45283396399999276, 15.36136682100004691 ' \ '45.48203114900003641, 15.29666792800006192 45.52295888300012905, 15.2685559480001416 ' \ '45.60166208900012919, 15.37376916500011248 45.64021270800010655, 15.25501672300006817 ' \ '45.72346344000011698, 15.42906294700014769 45.77529490200011253, 15.45128381300008868 ' \ '45.81513743100013869, 15.67607629400006886 45.84169911700014666, 15.65943648300003588 ' \ '45.88882802400014782, 15.69798710100010908 46.0362092080000167, 15.58988000500005455 ' \ '46.11351715100001059, 15.62284956800010605 46.19170359400006021, 16.01920780400010358 ' \ '46.29882883700007312, 16.05961877400008575 46.33231516600015709, 16.0579651280001201 ' \ '46.37753204400003426, 16.2756262620000598 46.37316538500006402, 16.23490523300009158 ' \ '46.4933389280001137, 16.36947066200013978 46.54057118800012915))) ' geom = QgsGeometry.fromWkt(wkt) f = QgsFeature() f.setGeometry(geom) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() crs = QgsCoordinateReferenceSystem.fromProj4( '+proj=ortho +lat_0=36.5 +lon_0=-118.8 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs' ) self.assertTrue(crs.isValid()) ms.setDestinationCrs(crs) ms.setExtent(QgsRectangle(1374999.8, 3912610.7, 4724462.5, 6505499.6)) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI ct = QgsCoordinateTransform(QgsCoordinateReferenceSystem('epsg:4326'), crs, QgsProject.instance()) self.assertTrue(ct.isValid()) context.setCoordinateTransform(ct) context.setExtent( ct.transformBoundingBox(ms.extent(), QgsCoordinateTransform.ReverseTransform)) fill_symbol = QgsFillSymbol.createSimple({ 'color': '#ffffff', 'outline_color': '#ffffff', 'outline_width': '10' }) painter.begin(image) try: image.fill(QColor(0, 0, 0)) fill_symbol.startRender(context) fill_symbol.renderFeature(f, context) fill_symbol.stopRender(context) finally: painter.end() assert self.imageCheck('Reprojection errors polygon', 'reprojection_errors_polygon', image) #also test linestring linestring = QgsGeometry(geom.constGet().boundary()) f.setGeometry(linestring) line_symbol = QgsLineSymbol.createSimple({ 'color': '#ffffff', 'outline_width': '10' }) image = QImage(200, 200, QImage.Format_RGB32) painter.begin(image) try: image.fill(QColor(0, 0, 0)) line_symbol.startRender(context) line_symbol.renderFeature(f, context) line_symbol.stopRender(context) finally: painter.end() assert self.imageCheck('Reprojection errors linestring', 'reprojection_errors_linestring', image)
def __init__(self, element, model, controls, scene=None): super(ModelerGraphicItem, self).__init__(None) self.controls = controls self.model = model self.scene = scene self.element = element if isinstance(element, QgsProcessingModelParameter): svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'input.svg')) self.picture = QPicture() painter = QPainter(self.picture) svg.render(painter) self.pixmap = None paramDef = self.model.parameterDefinition(element.parameterName()) if paramDef: self.text = paramDef.description() else: self.text = 'Error ({})'.format(element.parameterName()) elif isinstance(element, QgsProcessingModelOutput): # Output name svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'output.svg')) self.picture = QPicture() painter = QPainter(self.picture) svg.render(painter) self.pixmap = None self.text = element.name() else: if element.algorithm().svgIconPath(): svg = QSvgRenderer(element.algorithm().svgIconPath()) size = svg.defaultSize() self.picture = QPicture() painter = QPainter(self.picture) painter.scale(16 / size.width(), 16 / size.width()) svg.render(painter) self.pixmap = None else: self.pixmap = element.algorithm().icon().pixmap(15, 15) self.text = element.description() self.arrows = [] self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setZValue(1000) if controls: svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg')) picture = QPicture() painter = QPainter(picture) svg.render(painter) pt = QPointF( ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, ModelerGraphicItem.BOX_HEIGHT / 2 - FlatButtonGraphicItem.HEIGHT / 2) self.editButton = FlatButtonGraphicItem(picture, pt, self.editElement) self.editButton.setParentItem(self) svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'delete.svg')) picture = QPicture() painter = QPainter(picture) svg.render(painter) pt = QPointF( ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, FlatButtonGraphicItem.HEIGHT / 2 - ModelerGraphicItem.BOX_HEIGHT / 2) self.deleteButton = FlatButtonGraphicItem(picture, pt, self.removeElement) self.deleteButton.setParentItem(self) if isinstance(element, QgsProcessingModelChildAlgorithm): alg = element.algorithm() if [ a for a in alg.parameterDefinitions() if not a.isDestination() ]: pt = self.getLinkPointForParameter(-1) pt = QPointF(0, pt.y()) if controls: self.inButton = FoldButtonGraphicItem( pt, self.foldInput, self.element.parametersCollapsed()) self.inButton.setParentItem(self) if alg.outputDefinitions(): pt = self.getLinkPointForOutput(-1) pt = QPointF(0, pt.y()) if controls: self.outButton = FoldButtonGraphicItem( pt, self.foldOutput, self.element.outputsCollapsed()) self.outButton.setParentItem(self)
def _get_layout_pdf_image(self, width, height, dpi): pdfpath = getTempfilePath('pdf') temp_size = os.path.getsize(pdfpath) p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(pdfpath) p.setPaperSize( QSizeF(self._c.pageCollection().page(0).sizeWithUnits().width(), self._c.pageCollection().page(0).sizeWithUnits().height()), QPrinter.Millimeter) p.setFullPage(True) p.setColorMode(QPrinter.Color) p.setResolution(self._c.renderContext().dpi()) pdf_p = QPainter(p) # page_mm = p.pageRect(QPrinter.Millimeter) # page_px = p.pageRect(QPrinter.DevicePixel) # self._c.render(pdf_p, page_px, page_mm) exporter = QgsLayoutExporter(self._c) exporter.renderPage(pdf_p, 0) pdf_p.end() if temp_size == os.path.getsize(pdfpath): return False, '' filepath = getTempfilePath('png') # Poppler (pdftocairo or pdftoppm): # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase # muPDF (mudraw): # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf if PDFUTIL.strip().endswith('pdftocairo'): filebase = os.path.join( os.path.dirname(filepath), os.path.splitext(os.path.basename(filepath))[0]) call = [ PDFUTIL, '-png', '-singlefile', '-r', str(dpi), '-x', '0', '-y', '0', '-W', str(width), '-H', str(height), pdfpath, filebase ] elif PDFUTIL.strip().endswith('mudraw'): call = [ PDFUTIL, '-c', 'rgba', '-r', str(dpi), '-w', str(width), '-h', str(height), # '-b', '8', '-o', filepath, pdfpath ] else: return False, '' qDebug("_get_layout_pdf_image call: {0}".format(' '.join(call))) res = False try: subprocess.check_call(call) res = True except subprocess.CalledProcessError as e: qDebug("_get_layout_pdf_image failed!\n" "cmd: {0}\n" "returncode: {1}\n" "message: {2}".format(e.cmd, e.returncode, e.message)) if not res: os.unlink(filepath) filepath = '' return res, filepath
def _get_layout_svg_image(self, width, height, dpi): svgpath = getTempfilePath('svg') temp_size = os.path.getsize(svgpath) svg_g = QSvgGenerator() # noinspection PyArgumentList svg_g.setTitle(QgsProject.instance().title()) svg_g.setFileName(svgpath) svg_g.setSize(QSize(width, height)) svg_g.setViewBox(QRect(0, 0, width, height)) svg_g.setResolution(dpi) sp = QPainter(svg_g) exporter = QgsLayoutExporter(self._c) exporter.renderPage(sp, 0) sp.end() if temp_size == os.path.getsize(svgpath): return False, '' image = QImage(width, height, self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) svgr = QSvgRenderer(svgpath) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing)) p.setRenderHint(QPainter.TextAntialiasing) svgr.render(p) p.end() filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' # TODO: remove .svg file as well? return res, filepath
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)] 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) if self.tile_format == 'PNG': settings.setBackgroundColor(QColor(Qt.transparent)) 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, 4) metatiles_by_zoom[zoom] = metatiles metatiles_count += len(metatiles) lab_buffer_px = 100 progress = 0 tile_params = { 'format': self.tile_format, 'quality': 75, '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) if hasattr(settings, 'setLabelBoundaryGeometry'): label_area = QgsRectangle(settings.extent()) lab_buffer = label_area.width() * (lab_buffer_px / size.width()) label_area.set( label_area.xMinimum() + lab_buffer, label_area.yMinimum() + lab_buffer, label_area.xMaximum() - lab_buffer, label_area.yMaximum() - lab_buffer ) settings.setLabelBoundaryGeometry(QgsGeometry.fromRect(label_area)) 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()
def paintEvent(self, event): # based on # http://qt.gitorious.org/qt/qt/blobs/master/src/gui/widgets/qslider.cpp painter = QPainter(self) style = self.style() opt = QStyleOptionSlider() self.initStyleOption(opt) groove_rect = style.subControlRect(style.CC_Slider, opt, QStyle.SC_SliderGroove, self) handle_rect = style.subControlRect(style.CC_Slider, opt, QStyle.SC_SliderHandle, self) slider_space = style.pixelMetric(style.PM_SliderSpaceAvailable, opt) range_x1 = style.sliderPositionFromValue(self.minimum(), self.maximum(), self._low, slider_space) range_x2 = style.sliderPositionFromValue(self.minimum(), self.maximum(), self._high, slider_space) range_height = 4 groove_rect = QRectF( groove_rect.x(), handle_rect.center().y() - (range_height / 2), groove_rect.width(), range_height, ) range_rect = QRectF( groove_rect.x() + (handle_rect.width() / 2) + range_x1, handle_rect.center().y() - (range_height / 2), range_x2 - range_x1, range_height, ) if style.metaObject().className() != "QMacStyle": # Paint groove for Fusion and Windows styles cur_brush = painter.brush() cur_pen = painter.pen() painter.setBrush(QBrush(QColor(169, 169, 169))) painter.setPen(Qt.NoPen) # painter.drawRect(groove_rect) painter.drawRoundedRect(groove_rect, groove_rect.height() / 2, groove_rect.height() / 2) painter.setBrush(cur_brush) painter.setPen(cur_pen) cur_brush = painter.brush() cur_pen = painter.pen() # painter.setBrush(QBrush(QColor(18, 141, 148))) # painter.setPen(Qt.NoPen) painter.drawRect(range_rect) painter.setBrush(cur_brush) painter.setPen(cur_pen) for i, value in enumerate([self._low, self._high]): opt = QStyleOptionSlider() self.initStyleOption(opt) # Only draw the groove for the first slider so it doesn't get drawn # on top of the existing ones every time # if i == 0: # opt.subControls = QStyle.SC_SliderGroove | \ # QStyle.SC_SliderHandle # else: opt.subControls = QStyle.SC_SliderHandle if self.tickPosition() != self.NoTicks: opt.subControls |= QStyle.SC_SliderTickmarks if self.isSliderDown(): opt.state |= QStyle.State_Sunken else: opt.state |= QStyle.State_Active if self.pressed_control: opt.activeSubControls = self.pressed_control else: opt.activeSubControls = self.hover_control opt.sliderPosition = value opt.sliderValue = value style.drawComplexControl(QStyle.CC_Slider, opt, painter, self)
def genIcon(self): TECName = self.profile['TECName'] svgName = os.path.join(os.path.dirname(__file__), TECName + '_' + self.name + '.svg') pix = QSvgGenerator() pix.setFileName(svgName) pix.setSize(QSize(200, 100)) painter = QPainter() painter.begin(pix) painter.setPen(Qt.NoPen) # Paint the background before draw the legend line.(Essential!!) painter.fillRect(QRect(0, 0, 200, 100), Qt.white) painter.setPen(QPen(self.color, self.width * 3, self.lineStyle)) # Draw icon painter.drawLine(QLine(0, 50, 200, 50)) painter.end() pixmap = QPixmap(svgName) icon = QIcon(pixmap) self.icoName = svgName self.setIcon(icon)
def processAlgorithm(self, parameters, context, feedback): feedback.setProgress(1) extent = self.parameterAsExtent(parameters, self.EXTENT, context) min_zoom = self.parameterAsInt(parameters, self.ZOOM_MIN, context) max_zoom = self.parameterAsInt(parameters, self.ZOOM_MAX, context) dpi = self.parameterAsInt(parameters, self.DPI, context) tile_format = self.formats[self.parameterAsEnum(parameters, self.TILE_FORMAT, context)] output_format = self.outputs[self.parameterAsEnum(parameters, self.OUTPUT_FORMAT, context)] if output_format == 'Directory': output_dir = self.parameterAsString(parameters, self.OUTPUT_DIRECTORY, context) if not output_dir: raise QgsProcessingException(self.tr('You need to specify output directory.')) else: # MBTiles output_file = self.parameterAsString(parameters, self.OUTPUT_FILE, context) if not output_file: raise QgsProcessingException(self.tr('You need to specify output filename.')) 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) if tile_format == 'PNG': settings.setBackgroundColor(QColor(Qt.transparent)) wgs_extent = src_to_wgs.transformBoundingBox(extent) wgs_extent = [wgs_extent.xMinimum(), wgs_extent.yMinimum(), wgs_extent.xMaximum(), wgs_extent.yMaximum()] metatiles_by_zoom = {} metatiles_count = 0 for zoom in range(min_zoom, max_zoom + 1): metatiles = get_metatiles(wgs_extent, zoom, 4) metatiles_by_zoom[zoom] = metatiles metatiles_count += len(metatiles) lab_buffer_px = 100 progress = 0 tile_params = { 'format': tile_format, 'quality': 75, 'width': tile_width, 'height': tile_height } if output_format == 'Directory': writer = DirectoryWriter(output_dir, tile_params) else: writer = MBTilesWriter(output_file, tile_params, wgs_extent, min_zoom, max_zoom) for zoom in range(min_zoom, max_zoom + 1): feedback.pushConsoleInfo('Generating tiles for zoom level: %s' % zoom) for i, metatile in enumerate(metatiles_by_zoom[zoom]): size = QSize(tile_width * metatile.rows(), tile_height * metatile.columns()) extent = QgsRectangle(*metatile.extent()) settings.setExtent(wgs_to_dest.transformBoundingBox(extent)) settings.setOutputSize(size) label_area = QgsRectangle(settings.extent()) lab_buffer = label_area.width() * (lab_buffer_px / size.width()) label_area.set( label_area.xMinimum() + lab_buffer, label_area.yMinimum() + lab_buffer, label_area.xMaximum() - lab_buffer, label_area.yMaximum() - lab_buffer ) settings.setLabelBoundaryGeometry(QgsGeometry.fromRect(label_area)) 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.writeTile(tile, tile_img) progress += 1 feedback.setProgress(100 * (progress / metatiles_count)) writer.close() results = {} if output_format == 'Directory': results['OUTPUT_DIRECTORY'] = output_dir else: # MBTiles results['OUTPUT_FILE'] = output_file return results
def saveSpritesSheet(icons, folder): sprites = {} for iconPath, sl in icons.items(): iconName = os.path.splitext(os.path.basename(iconPath))[0] sprites[iconName] = saveSymbolLayerSprite(sl) if sprites: height = max([s.height() for s, s2x in sprites.values()]) width = sum([s.width() for s, s2x in sprites.values()]) img = QImage(width, height, QImage.Format_ARGB32) img.fill(QColor(Qt.transparent)) img2x = QImage(width * 2, height * 2, QImage.Format_ARGB32) img2x.fill(QColor(Qt.transparent)) painter = QPainter(img) painter.begin(img) painter2x = QPainter(img2x) painter2x.begin(img2x) spritesheet = { NO_ICON: { "width": 0, "height": 0, "x": 0, "y": 0, "pixelRatio": 1 } } spritesheet2x = { NO_ICON: { "width": 0, "height": 0, "x": 0, "y": 0, "pixelRatio": 1 } } x = 0 for name, _sprites in sprites.items(): s, s2x = _sprites painter.drawImage(x, 0, s) painter2x.drawImage(x * 2, 0, s2x) spritesheet[name] = { "width": s.width(), "height": s.height(), "x": x, "y": 0, "pixelRatio": 1 } spritesheet2x[name] = { "width": s2x.width(), "height": s2x.height(), "x": x * 2, "y": 0, "pixelRatio": 2 } x += s.width() painter.end() painter2x.end() img.save(os.path.join(folder, "spriteSheet.png")) img2x.save(os.path.join(folder, "*****@*****.**")) with open(os.path.join(folder, "spriteSheet.json"), 'w') as f: json.dump(spritesheet, f) with open(os.path.join(folder, "*****@*****.**"), 'w') as f: json.dump(spritesheet2x, f)
def testRenderWithTransform(self): layer = QgsAnnotationLayer( 'test', QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext())) self.assertTrue(layer.isValid()) item = QgsAnnotationPolygonItem( QgsPolygon( QgsLineString([ QgsPoint(11.5, 13), QgsPoint(12, 13), QgsPoint(12, 13.5), QgsPoint(11.5, 13) ]))) item.setSymbol( QgsFillSymbol.createSimple({ 'color': '200,100,100', 'outline_color': 'black', 'outline_width': '2' })) item.setZIndex(1) layer.addItem(item) item = QgsAnnotationLineItem( QgsLineString( [QgsPoint(11, 13), QgsPoint(12, 13), QgsPoint(12, 15)])) item.setSymbol( QgsLineSymbol.createSimple({ 'color': '#ffff00', 'line_width': '3' })) item.setZIndex(2) layer.addItem(item) item = QgsAnnotationMarkerItem(QgsPoint(12, 13)) item.setSymbol( QgsMarkerSymbol.createSimple({ 'color': '100,200,200', 'size': '6', 'outline_color': 'black' })) item.setZIndex(3) layer.addItem(item) layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) settings = QgsMapSettings() settings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857')) settings.setExtent(QgsRectangle(1250958, 1386945, 1420709, 1532518)) settings.setOutputSize(QSize(300, 300)) settings.setFlag(QgsMapSettings.Antialiasing, False) rc = QgsRenderContext.fromMapSettings(settings) rc.setCoordinateTransform( QgsCoordinateTransform(layer.crs(), settings.destinationCrs(), QgsProject.instance())) image = QImage(200, 200, QImage.Format_ARGB32) image.setDotsPerMeterX(96 / 25.4 * 1000) image.setDotsPerMeterY(96 / 25.4 * 1000) image.fill(QColor(255, 255, 255)) painter = QPainter(image) rc.setPainter(painter) try: renderer = layer.createMapRenderer(rc) renderer.render() finally: painter.end() self.assertTrue( self.imageCheck('layer_render_transform', 'layer_render_transform', image))
def BurnDrawingsImage(source, overlay): ''' Burn drawings into image @type source: QImage @param source: Original Image @type overlay: QImage @param overlay: Drawings image @return: QImage ''' base = source.scaled(overlay.size(), Qt.IgnoreAspectRatio) p = QPainter() p.setRenderHint(QPainter.HighQualityAntialiasing) p.begin(base) p.setCompositionMode(QPainter.CompositionMode_SourceOut) p.drawImage(0, 0, overlay) p.end() # Restore size base = base.scaled(source.size(), Qt.IgnoreAspectRatio) return base
def paintEvent(self, event): painter = QPainter() painter.begin(self) painter.setRenderHint(QPainter.Antialiasing) painter.fillRect(event.rect(), QBrush(QColor(255, 255, 255, 127))) painter.setPen(QPen(Qt.NoPen)) for i in range(6): if (self.counter / 5) % 6 == i: painter.setBrush(QBrush(QColor(127 + (self.counter % 5) * 32, 127, 127))) else: painter.setBrush(QBrush(QColor(127, 127, 127))) painter.drawEllipse( self.width() / 2 + 30 * math.cos(2 * math.pi * i / 6.0) - 10, self.height() / 2 + 30 * math.sin(2 * math.pi * i / 6.0) - 10, 20, 20) painter.end()
def paintEvent(self, event): """ @type event: QPaintEvent @param event: @return: """ if not self.surface.isActive(): return self.painter = QPainter(self) self.painter.setRenderHint(QPainter.HighQualityAntialiasing) region = event.region() self.painter.fillRect(region.boundingRect(), self.brush) # Background painter color try: self.surface.paint(self.painter) SetImageSize(self.currentFrame().width(), self.currentFrame().height()) except Exception: None # Prevent draw on video if not started or finished if self.parent.player.position() == 0: self.painter.end() return self.gt = GetGCPGeoTransform() # Draw On Video draw.drawOnVideo(self.drawPtPos, self.drawLines, self.drawPolygon, self.drawMeasureDistance, self.drawMeasureArea, self.drawCesure, self.painter, self.surface, self.gt) # Draw On Video Object tracking test if self._interaction.objectTracking and self._isinit: frame = convertQImageToMat(self.currentFrame()) offset = self.surface.videoRect() # Update tracker result = resize(frame, (offset.width(), offset.height())) ok, bbox = self.tracker.update(result) # Draw bounding box if ok: # check negative values x = bbox[0] + offset.x() y = bbox[1] + offset.y() if vut.IsPointOnScreen(x, y, self.surface): self.painter.setPen(self.blue_Pen) self.painter.drawRect(x, y, bbox[2], bbox[3]) # Get Track object center xc = x + (bbox[2] / 2) yc = y + (bbox[3] / 2) p = QPoint(xc, yc) Longitude, Latitude, _ = vut.GetPointCommonCoords( p, self.surface) # Draw Rubber Band on canvas self.Track_Canvas_RubberBand.addPoint(QgsPointXY(Longitude, Latitude)) else: self._isinit = False del self.tracker # Magnifier Glass if self._interaction.magnifier and not self.dragPos.isNull(): draw.drawMagnifierOnVideo(self, self.dragPos, self.currentFrame(), self.painter) # Stamp On Video if self._interaction.stamp: draw.drawStampOnVideo(self, self.painter) self.painter.end() return
def test_layout_exports(self): """Test mask effects in a layout export at 300 dpi""" # modify labeling settings label_settings = self.polys_layer.labeling().settings() fmt = label_settings.format() # enable a mask fmt.mask().setEnabled(True) fmt.mask().setSize(4.0) # and mask other symbol layers underneath fmt.mask().setMaskedSymbolLayers([ # the black part of roads QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)), # the black jets QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)), QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))]) # add an outer glow effect to the mask blur = QgsOuterGlowEffect.create({"enabled": "1", "blur_level": "6.445", "blur_unit": "MM", "opacity": "1", "spread": "0.6", "spread_unit": "MM", "color1": "0,0,255,255", "draw_mode": "2" }) fmt.mask().setPaintEffect(blur) label_settings.setFormat(fmt) self.polys_layer.labeling().setSettings(label_settings) layout = QgsLayout(QgsProject.instance()) page = QgsLayoutItemPage(layout) page.setPageSize(QgsLayoutSize(50, 33)) layout.pageCollection().addPage(page) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(1, 1, 48, 32)) map.setFrameEnabled(True) layout.addLayoutItem(map) map.setExtent(self.lines_layer.extent()) map.setLayers([self.points_layer, self.lines_layer, self.polys_layer]) image = QImage(591, 591, QImage.Format_RGB32) image.setDotsPerMeterX(int(300 / 25.3 * 1000)) image.setDotsPerMeterY(int(300 / 25.3 * 1000)) image.fill(0) p = QPainter(image) exporter = QgsLayoutExporter(layout) exporter.renderPage(p, 0) p.end() tmp = getTempfilePath('png') image.save(tmp) control_name = "layout_export" self.checker.setControlName(control_name) self.checker.setRenderedImage(tmp) res = self.checker.compareImages(control_name) self.report += self.checker.report() self.assertTrue(res)
class VideoWidget(QVideoWidget): def __init__(self, parent=None): ''' Constructor ''' super().__init__(parent) self.surface = VideoWidgetSurface(self) self.setAttribute(Qt.WA_OpaquePaintEvent) self.Tracking_Video_RubberBand = QRubberBand(QRubberBand.Rectangle, self) self.Censure_RubberBand = QRubberBand(QRubberBand.Rectangle, self) color_blue = QColor(Qt.blue) color_black = QColor(Qt.black) color_amber = QColor(252, 215, 108) pal_blue = QPalette() pal_blue.setBrush(QPalette.Highlight, QBrush(color_blue)) self.Tracking_Video_RubberBand.setPalette(pal_blue) pal_black = QPalette() pal_black.setBrush(QPalette.Highlight, QBrush(color_black)) self.Censure_RubberBand.setPalette(pal_black) self._interaction = InteractionState() self._filterSatate = FilterState() self._isinit = False self._MGRS = False self.gt = None self.drawCesure = [] self.poly_coordinates, self.drawPtPos, self.drawLines, self.drawMeasureDistance, self.drawMeasureArea, self.drawPolygon = [], [], [], [], [], [] # Draw Polygon Canvas Rubberband self.poly_Canvas_RubberBand = QgsRubberBand( iface.mapCanvas(), True) # Polygon type # set rubber band style self.poly_Canvas_RubberBand.setColor(color_amber) self.poly_Canvas_RubberBand.setWidth(3) # Tracking Canvas Rubberband self.Track_Canvas_RubberBand = QgsRubberBand( iface.mapCanvas(), QgsWkbTypes.LineGeometry) # set rubber band style self.Track_Canvas_RubberBand.setColor(color_blue) self.Track_Canvas_RubberBand.setWidth(5) # Cursor Canvas Rubberband self.Cursor_Canvas_RubberBand = QgsRubberBand( iface.mapCanvas(), QgsWkbTypes.PointGeometry) self.Cursor_Canvas_RubberBand.setWidth(4) self.Cursor_Canvas_RubberBand.setColor(QColor(255, 100, 100, 250)) self.Cursor_Canvas_RubberBand.setIcon(QgsRubberBand.ICON_FULL_DIAMOND) self.parent = parent.parent() palette = self.palette() palette.setColor(QPalette.Background, Qt.transparent) self.setPalette(palette) self.origin, self.dragPos = QPoint(), QPoint() self.tapTimer = QBasicTimer() self.brush = QBrush(color_black) self.blue_Pen = QPen(color_blue, 3) def removeLastLine(self): ''' Remove Last Line Objects ''' if self.drawLines: try: if self.drawLines[-1][3] == "mouseMoveEvent": del self.drawLines[-1] # Remove mouseMoveEvent element except Exception: None for pt in range(len(self.drawLines) - 1, -1, -1): del self.drawLines[pt] try: if self.drawLines[pt - 1][0] is None: break except Exception: None self.UpdateSurface() AddDrawLineOnMap(self.drawLines) return def removeLastSegmentLine(self): ''' Remove Last Segment Line Objects ''' try: if self.drawLines[-1][3] == "mouseMoveEvent": del self.drawLines[-1] # Remove mouseMoveEvent element except Exception: None if self.drawLines: if self.drawLines[-1][0] is None: del self.drawLines[-1] del self.drawLines[-1] self.UpdateSurface() AddDrawLineOnMap(self.drawLines) return def removeAllLines(self): ''' Resets Line List ''' if self.drawLines: self.drawLines = [] self.UpdateSurface() # Clear all Layer RemoveAllDrawLineOnMap() def ResetDrawMeasureDistance(self): ''' Resets Measure Distance List ''' self.drawMeasureDistance = [] def ResetDrawMeasureArea(self): ''' Resets Measure Area List ''' self.drawMeasureArea = [] def removeAllCensure(self): ''' Remove All Censure Objects ''' if self.drawCesure: self.drawCesure = [] self.UpdateSurface() def removeLastCensured(self): ''' Remove Last Censure Objects ''' if self.drawCesure: del self.drawCesure[-1] self.UpdateSurface() def removeLastPoint(self): ''' Remove All Point Drawer Objects ''' if self.drawPtPos: del self.drawPtPos[-1] self.UpdateSurface() RemoveLastDrawPointOnMap() return def removeAllPoint(self): ''' Remove All Point Drawer Objects ''' if self.drawPtPos: self.drawPtPos = [] self.UpdateSurface() # Clear all Layer RemoveAllDrawPointOnMap() return def removeAllPolygon(self): ''' Remove All Polygon Drawer Objects ''' if self.drawPolygon: self.drawPolygon = [] self.UpdateSurface() # Clear all Layer RemoveAllDrawPolygonOnMap() def removeLastPolygon(self): ''' Remove Last Polygon Drawer Objects ''' if self.drawPolygon: try: if self.drawPolygon[-1][3] == "mouseMoveEvent": del self.drawPolygon[-1] # Remove mouseMoveEvent element except Exception: None for pt in range(len(self.drawPolygon) - 1, -1, -1): del self.drawPolygon[pt] try: if self.drawPolygon[pt - 1][0] is None: break except Exception: None self.UpdateSurface() # remove last index layer RemoveLastDrawPolygonOnMap() def keyPressEvent(self, event): '''Exit fullscreen :type event: QKeyEvent :param event: :return: ''' if event.key() == Qt.Key_Escape and self.isFullScreen(): self.setFullScreen(False) event.accept() elif event.key() == Qt.Key_Enter and event.modifiers() & Qt.Key_Alt: self.setFullScreen(not self.isFullScreen()) event.accept() else: super().keyPressEvent(event) def mouseDoubleClickEvent(self, event): """ Mouse double click event :type event: QMouseEvent :param event: :return: """ if GetImageHeight() == 0: return if(not vut.IsPointOnScreen(event.x(), event.y(), self.surface)): return if self.gt is not None and self._interaction.lineDrawer: self.drawLines.append([None, None, None]) return if self.gt is not None and self._interaction.measureDistance: self.drawMeasureDistance.append([None, None, None]) return if self.gt is not None and self._interaction.measureArea: self.drawMeasureArea.append([None, None, None]) return if self.gt is not None and self._interaction.polygonDrawer: ok = AddDrawPolygonOnMap(self.poly_coordinates) # Prevent invalid geometry (Polygon with 2 points) if not ok: return self.drawPolygon.append([None, None, None]) # Empty RubberBand for _ in range(self.poly_Canvas_RubberBand.numberOfVertices()): self.poly_Canvas_RubberBand.removeLastPoint() # Empty List self.poly_coordinates = [] return self.UpdateSurface() self.setFullScreen(not self.isFullScreen()) event.accept() def videoSurface(self): ''' Return video Surface ''' return self.surface def UpdateSurface(self): ''' Update Video Surface only is is stopped or paused ''' if self.parent.playerState in (QMediaPlayer.StoppedState, QMediaPlayer.PausedState): self.update() QApplication.processEvents() def sizeHint(self): ''' This property holds the recommended size for the widget ''' return self.surface.surfaceFormat().sizeHint() def currentFrame(self): ''' Return current frame QImage ''' return self.surface.image def SetInvertColor(self, value): '''Set Invert color filter @type value: bool @param value: @return: ''' self._filterSatate.invertColorFilter = value def SetObjectTracking(self, value): '''Set Object Tracking @type value: bool @param value: @return: ''' self._interaction.objectTracking = value def SetMeasureDistance(self, value): '''Set measure Distance @type value: bool @param value: @return: ''' self._interaction.measureDistance = value def SetMeasureArea(self, value): '''Set measure Area @type value: bool @param value: @return: ''' self._interaction.measureArea = value def SetHandDraw(self, value): '''Set Hand Draw @type value: bool @param value: @return: ''' self._interaction.HandDraw = value def SetCensure(self, value): '''Set Censure Video Parts @type value: bool @param value: @return: ''' self._interaction.censure = value def SetMGRS(self, value): '''Set MGRS Cursor Coordinates @type value: bool @param value: @return: ''' self._MGRS = value def SetGray(self, value): '''Set gray scale @type value: bool @param value: @return: ''' self._filterSatate.grayColorFilter = value def SetMirrorH(self, value): '''Set Horizontal Mirror @type value: bool @param value: @return: ''' self._filterSatate.MirroredHFilter = value def SetNDVI(self, value): '''Set NDVI @type value: bool @param value: @return: ''' self._filterSatate.NDVI = value def SetEdgeDetection(self, value): '''Set Canny Edge filter @type value: bool @param value: @return: ''' self._filterSatate.edgeDetectionFilter = value def SetAutoContrastFilter(self, value): '''Set Automatic Contrast filter @type value: bool @param value: @return: ''' self._filterSatate.contrastFilter = value def SetMonoFilter(self, value): '''Set mono filter @type value: bool @param value: @return: ''' self._filterSatate.monoFilter = value def RestoreFilters(self): ''' Remove and restore all video filters ''' self._filterSatate.clear() def RestoreDrawer(self): ''' Remove and restore all Drawer Options ''' self._interaction.clear() # Magnifier Glass self.dragPos = QPoint() self.tapTimer.stop() def RemoveCanvasRubberbands(self): ''' Remove Canvas Rubberbands ''' self.poly_Canvas_RubberBand.reset() self.Track_Canvas_RubberBand.reset(QgsWkbTypes.LineGeometry) self.Cursor_Canvas_RubberBand.reset(QgsWkbTypes.PointGeometry) def paintEvent(self, event): """ @type event: QPaintEvent @param event: @return: """ if not self.surface.isActive(): return self.painter = QPainter(self) self.painter.setRenderHint(QPainter.HighQualityAntialiasing) region = event.region() self.painter.fillRect(region.boundingRect(), self.brush) # Background painter color try: self.surface.paint(self.painter) SetImageSize(self.currentFrame().width(), self.currentFrame().height()) except Exception: None # Prevent draw on video if not started or finished if self.parent.player.position() == 0: self.painter.end() return self.gt = GetGCPGeoTransform() # Draw On Video draw.drawOnVideo(self.drawPtPos, self.drawLines, self.drawPolygon, self.drawMeasureDistance, self.drawMeasureArea, self.drawCesure, self.painter, self.surface, self.gt) # Draw On Video Object tracking test if self._interaction.objectTracking and self._isinit: frame = convertQImageToMat(self.currentFrame()) offset = self.surface.videoRect() # Update tracker result = resize(frame, (offset.width(), offset.height())) ok, bbox = self.tracker.update(result) # Draw bounding box if ok: # check negative values x = bbox[0] + offset.x() y = bbox[1] + offset.y() if vut.IsPointOnScreen(x, y, self.surface): self.painter.setPen(self.blue_Pen) self.painter.drawRect(x, y, bbox[2], bbox[3]) # Get Track object center xc = x + (bbox[2] / 2) yc = y + (bbox[3] / 2) p = QPoint(xc, yc) Longitude, Latitude, _ = vut.GetPointCommonCoords( p, self.surface) # Draw Rubber Band on canvas self.Track_Canvas_RubberBand.addPoint(QgsPointXY(Longitude, Latitude)) else: self._isinit = False del self.tracker # Magnifier Glass if self._interaction.magnifier and not self.dragPos.isNull(): draw.drawMagnifierOnVideo(self, self.dragPos, self.currentFrame(), self.painter) # Stamp On Video if self._interaction.stamp: draw.drawStampOnVideo(self, self.painter) self.painter.end() return def resizeEvent(self, _): """ @type _: QMouseEvent @param _: @return: """ self.surface.updateVideoRect() self.update() # Magnifier Glass if self._interaction.magnifier and not self.dragPos.isNull(): draw.drawMagnifierOnVideo(self, self.dragPos, self.currentFrame(), self.painter) # QApplication.processEvents() def AddMoveEventValue(self, values, Longitude, Latitude, Altitude): """ Remove and Add move value for fluid drawing @type values: list @param values: Points list @type Longitude: float @param Longitude: Longitude value @type Latitude: float @param Latitude: Latitude value @type Altitude: float @param Altitude: Altitude value """ for idx, pt in enumerate(values): if pt[-1] == "mouseMoveEvent": del values[idx] values.append([Longitude, Latitude, Altitude, "mouseMoveEvent"]) self.UpdateSurface() def mouseMoveEvent(self, event): """ @type event: QMouseEvent @param event: @return: """ # Magnifier mouseMoveEvent # Magnifier can move on black screen for show image borders if self._interaction.magnifier: if event.buttons(): self.dragPos = event.pos() self.UpdateSurface() # check if the point is on picture (not in black borders) if(not vut.IsPointOnScreen(event.x(), event.y(), self.surface)): self.setCursor(QCursor(Qt.ArrowCursor)) self.Cursor_Canvas_RubberBand.reset(QgsWkbTypes.PointGeometry) return # Prevent draw on video if not started or finished if self.parent.player.position() == 0: return # Mouser cursor drawing if self._interaction.pointDrawer or self._interaction.polygonDrawer or self._interaction.lineDrawer or self._interaction.measureDistance or self._interaction.measureArea or self._interaction.censure or self._interaction.objectTracking: self.setCursor(QCursor(Qt.CrossCursor)) # Cursor Coordinates if self.gt is not None: Longitude, Latitude, Altitude = vut.GetPointCommonCoords( event, self.surface) tr = QgsCoordinateTransform( QgsCoordinateReferenceSystem( 'EPSG:4326' ), iface.mapCanvas().mapSettings().destinationCrs(), QgsProject.instance().transformContext() ) mapPt = tr.transform( QgsPointXY(Longitude, Latitude) ) vertices = self.Cursor_Canvas_RubberBand.numberOfVertices() if vertices > 0: self.Cursor_Canvas_RubberBand.removePoint(0, True, 0) self.Cursor_Canvas_RubberBand.movePoint( mapPt, 0) else: self.Cursor_Canvas_RubberBand.addPoint( mapPt ) if self._MGRS: try: mgrsCoords = mgrs.toMgrs(Latitude, Longitude) except Exception: mgrsCoords = "" txt = "<span style='font-size:9pt; font-weight:normal;'>" + \ ("%s" % mgrsCoords) + "</span>" else: txt = "<span style='font-size:10pt; font-weight:bold;'>Lon : </span>" txt += "<span style='font-size:9pt; font-weight:normal;'>" + \ ("%.3f" % Longitude) + "</span>" txt += "<span style='font-size:10pt; font-weight:bold;'> Lat : </span>" txt += "<span style='font-size:9pt; font-weight:normal;'>" + \ ("%.3f" % Latitude) + "</span>" if hasElevationModel(): txt += "<span style='font-size:10pt; font-weight:bold;'> Alt : </span>" txt += "<span style='font-size:9pt; font-weight:normal;'>" + \ ("%.0f" % Altitude) + "</span>" else: txt += "<span style='font-size:10pt; font-weight:bold;'> Alt : </span>" txt += "<span style='font-size:9pt; font-weight:normal;'>-</span>" self.parent.lb_cursor_coord.setText(txt) # Polygon drawer mouseMoveEvent if self._interaction.polygonDrawer: self.AddMoveEventValue(self.drawPolygon, Longitude, Latitude, Altitude) # Line drawer mouseMoveEvent if self._interaction.lineDrawer: self.AddMoveEventValue(self.drawLines, Longitude, Latitude, Altitude) # Measure Distance drawer mouseMoveEvent if self._interaction.measureDistance and self.drawMeasureDistance: self.AddMoveEventValue(self.drawMeasureDistance, Longitude, Latitude, Altitude) # Measure Area drawer mouseMoveEvent if self._interaction.measureArea and self.drawMeasureArea: self.AddMoveEventValue(self.drawMeasureArea, Longitude, Latitude, Altitude) else: self.parent.lb_cursor_coord.setText("<span style='font-size:10pt; font-weight:bold;'>Lon :</span>" + "<span style='font-size:9pt; font-weight:normal;'>-</span>" + "<span style='font-size:10pt; font-weight:bold;'> Lat :</span>" + "<span style='font-size:9pt; font-weight:normal;'>-</span>" + "<span style='font-size:10pt; font-weight:bold;'> Alt :</span>" + "<span style='font-size:9pt; font-weight:normal;'>-</span>") if not event.buttons(): return # Object tracking rubberband if not self.Tracking_Video_RubberBand.isHidden(): self.Tracking_Video_RubberBand.setGeometry( QRect(self.origin, event.pos()).normalized()) # Censure rubberband if not self.Censure_RubberBand.isHidden(): self.Censure_RubberBand.setGeometry( QRect(self.origin, event.pos()).normalized()) def timerEvent(self, _): """ Time Event (Magnifier method)""" if not self._interaction.magnifier: self.activateMagnifier() def mousePressEvent(self, event): """ @type event: QMouseEvent @param event: @return: """ if GetImageHeight() == 0: return # Prevent draw on video if not started or finished if self.parent.player.position() == 0: return if event.button() == Qt.LeftButton: # Magnifier Glass if self._interaction.magnifier: self.dragPos = event.pos() self.tapTimer.stop() self.tapTimer.start(10, self) if(not vut.IsPointOnScreen(event.x(), event.y(), self.surface)): return # point drawer if self.gt is not None and self._interaction.pointDrawer: Longitude, Latitude, Altitude = vut.GetPointCommonCoords( event, self.surface) pointIndex = len(self.drawPtPos) + 1 AddDrawPointOnMap(pointIndex, Longitude, Latitude, Altitude) self.drawPtPos.append([Longitude, Latitude, Altitude]) # polygon drawer if self.gt is not None and self._interaction.polygonDrawer: Longitude, Latitude, Altitude = vut.GetPointCommonCoords( event, self.surface) self.poly_Canvas_RubberBand.addPoint(QgsPointXY(Longitude, Latitude)) self.poly_coordinates.extend(QgsPointXY(Longitude, Latitude)) self.drawPolygon.append([Longitude, Latitude, Altitude]) # line drawer if self.gt is not None and self._interaction.lineDrawer: Longitude, Latitude, Altitude = vut.GetPointCommonCoords( event, self.surface) self.drawLines.append([Longitude, Latitude, Altitude]) AddDrawLineOnMap(self.drawLines) self.origin = event.pos() # Object Tracking Interaction if self._interaction.objectTracking: self.Tracking_Video_RubberBand.setGeometry( QRect(self.origin, QSize())) self.Tracking_Video_RubberBand.show() # Censure Interaction if self._interaction.censure: self.Censure_RubberBand.setGeometry( QRect(self.origin, QSize())) self.Censure_RubberBand.show() # Measure Distance drawer if self.gt is not None and self._interaction.measureDistance: Longitude, Latitude, Altitude = vut.GetPointCommonCoords( event, self.surface) self.drawMeasureDistance.append([Longitude, Latitude, Altitude]) # Measure Distance drawer if self.gt is not None and self._interaction.measureArea: Longitude, Latitude, Altitude = vut.GetPointCommonCoords( event, self.surface) self.drawMeasureArea.append([Longitude, Latitude, Altitude]) # if not called, the paint event is not triggered. self.UpdateSurface() def activateMagnifier(self): """ Activate Magnifier Glass """ self.tapTimer.stop() self.UpdateSurface() def SetMagnifier(self, value): """Set Magnifier Glass @type value: bool @param value: """ self._interaction.magnifier = value # We avoid that the second time we activate the tool, save the previous position. # Always keep the same behavior of the tool if not value: self.dragPos = QPoint() self.tapTimer.stop() def SetStamp(self, value): """Set Stamp @type value: bool @param value: """ self._interaction.stamp = value def SetPointDrawer(self, value): """Set Point Drawer @type value: bool @param value: """ self._interaction.pointDrawer = value def SetLineDrawer(self, value): """Set Line Drawer @type value: bool @param value: """ self._interaction.lineDrawer = value def SetPolygonDrawer(self, value): """Set Polygon Drawer @type value: bool @param value: """ self._interaction.polygonDrawer = value def mouseReleaseEvent(self, _): """ @type event: QMouseEvent @param event: @return: """ # Prevent draw on video if not started or finished if self.parent.player.position() == 0: return # Censure Draw Interaction if self._interaction.censure: geom = self.Censure_RubberBand.geometry() self.Censure_RubberBand.hide() self.drawCesure.append([geom]) # Object Tracking Interaction if self._interaction.objectTracking: geom = self.Tracking_Video_RubberBand.geometry() offset = self.surface.videoRect() bbox = (geom.x() - offset.x(), geom.y() - offset.y(), geom.width(), geom.height()) img = self.currentFrame() frame = convertQImageToMat(img) # Remo rubberband on canvas and video self.Tracking_Video_RubberBand.hide() self.Track_Canvas_RubberBand.reset() self.tracker = TrackerMOSSE_create() result = resize(frame, (offset.width(), offset.height())) try: ok = self.tracker.init(result, bbox) except Exception: return if ok: self._isinit = True # Get Traker center xc = bbox[0] + (geom.width() / 2) yc = bbox[1] + (geom.height() / 2) p = QPoint(xc, yc) Longitude, Latitude, _ = vut.GetPointCommonCoords( p, self.surface) # Draw Rubber Band on canvas self.Track_Canvas_RubberBand.addPoint(QgsPointXY(Longitude, Latitude)) else: self._isinit = False def leaveEvent(self, _): """ @type _: QEvent @param _: @return: """ # Remove coordinates label value self.parent.lb_cursor_coord.setText("") # Change cursor self.setCursor(QCursor(Qt.ArrowCursor)) # Reset mouse rubberband self.Cursor_Canvas_RubberBand.reset(QgsWkbTypes.PointGeometry)
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) color = self.parameterAsColor(parameters, self.BACKGROUND_COLOR, context) self.tile_format = self.formats[self.parameterAsEnum(parameters, self.TILE_FORMAT, 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: 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) if self.tile_format == 'PNG': 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(color) 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()
def image(self): width = (self.xmax - self.xmin + 1) * self.TILE_SIZE height = (self.ymax - self.ymin + 1) * self.TILE_SIZE image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) p = QPainter(image) for tile in self.tiles.values(): if not tile.data: continue x = tile.x - self.xmin y = tile.y - self.ymin rect = QRect(x * self.TILE_SIZE, y * self.TILE_SIZE, self.TILE_SIZE, self.TILE_SIZE) timg = QImage() res = timg.loadFromData(tile.data) if res: p.drawImage(rect, timg) if debug_mode: p.setPen(Qt.black) p.drawText( rect, Qt.AlignBottom | Qt.AlignRight, # "x: %s, y:%s\nz: %s, data: %s" % (x, y, tile.zoom, tile.data.size()) "z: %s, data: %s" % (tile.zoom, tile.data.size())) if not res: p.setPen(Qt.darkRed) p.drawText(rect, Qt.AlignCenter, "Bad tile") p.setPen(Qt.black) p.drawRect(rect) return image
def append_CharacterMarkerSymbolLayerAsSvg(symbol, layer, context: Context): # pylint: disable=too-many-locals """ Appends a CharacterMarkerSymbolLayer to a symbol, rendering the font character to an SVG file. """ font_family = layer.font character = chr(layer.unicode) color = symbol_color_to_qcolor(layer.color) angle = convert_angle(layer.angle) font = QFont(font_family) font.setPointSizeF(layer.size) # Using the rect of a painter path gives better results then using font metrics path = QPainterPath() path.setFillRule(Qt.WindingFill) path.addText(0, 0, font, character) rect = path.boundingRect() font_bounding_rect = QFontMetricsF(font).boundingRect(character) # adjust size -- marker size in esri is the font size, svg marker size in qgis is the svg rect size scale = rect.width() / font_bounding_rect.width() gen = QSvgGenerator() svg_path = symbol_name_to_filename(context.symbol_name, context.picture_folder, 'svg') gen.setFileName(svg_path) gen.setViewBox(rect) painter = QPainter(gen) painter.setFont(font) # todo -- size! if context.parameterise_svg: painter.setBrush(QBrush(QColor(255, 0, 0))) else: painter.setBrush(QBrush(color)) painter.setPen(Qt.NoPen) painter.drawPath(path) painter.end() if context.parameterise_svg: with open(svg_path, 'r') as f: t = f.read() t = t.replace('#ff0000', 'param(fill)') t = t.replace('fill-opacity="1" ', 'fill-opacity="param(fill-opacity)"') t = t.replace( 'stroke="none"', 'stroke="param(outline)" stroke-opacity="param(outline-opacity) 1" stroke-width="param(outline-width) 0"' ) with open(svg_path, 'w') as f: f.write(t) svg_path = context.convert_path(svg_path) out = QgsSvgMarkerSymbolLayer(svg_path) out.setSizeUnit(context.units) out.setSize(context.convert_size(scale * rect.width())) out.setAngle(angle) out.setFillColor(color) out.setStrokeWidth(0) out.setEnabled(layer.enabled) out.setLocked(layer.locked) out.setOffset( adjust_offset_for_rotation( QPointF(context.convert_size(layer.x_offset), -context.convert_size(layer.y_offset)), layer.angle)) out.setOffsetUnit(context.units) symbol.appendSymbolLayer(out)
def paintEvent(self, e): painter = QPainter(self) #painter.begin(self); painter.drawImage(0, 0, self.img) painter.end()
def BurnDrawingsImage(source, overlay): base = source.scaled(overlay.size(), Qt.IgnoreAspectRatio) p = QPainter() p.setRenderHint(QPainter.HighQualityAntialiasing) p.begin(base) p.setCompositionMode(QPainter.CompositionMode_SourceOut) p.drawImage(0, 0, overlay) p.end() # Restore size base = base.scaled(source.size(), Qt.IgnoreAspectRatio) return base
def paintEvent(self, e: QPaintEvent): contRect = self.contentsRect() handleRadius = round(0.24 * contRect.height()) p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setPen(self._transparent_pen) barRect = QRectF(0, 0, contRect.width() - handleRadius, 0.40 * contRect.height()) barRect.moveCenter(contRect.center()) rounding = barRect.height() / 2 # the handle will move along this line trailLength = contRect.width() - 2 * handleRadius xPos = contRect.x( ) + handleRadius + trailLength * self._handle_position if self.isChecked(): p.setBrush(self._bar_checked_brush) p.drawRoundedRect(barRect, rounding, rounding) # p.drawText(barRect, self.getLabel(True)) p.setBrush(self._handle_checked_brush) else: p.setBrush(self._bar_brush) p.drawRoundedRect(barRect, rounding, rounding) # p.drawText(barRect, self.getLabel(False)) p.setPen(self._light_grey_pen) p.setBrush(self._handle_brush) p.drawEllipse(QPointF(xPos, barRect.center().y()), handleRadius, handleRadius) p.end()
def testRenderWithTransform(self): layer = QgsAnnotationLayer( 'test', QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext())) self.assertTrue(layer.isValid()) item = QgsAnnotationPolygonItem( QgsPolygon( QgsLineString([ QgsPoint(11.5, 13), QgsPoint(12, 13), QgsPoint(12, 13.5), QgsPoint(11.5, 13) ]))) item.setSymbol( QgsFillSymbol.createSimple({ 'color': '200,100,100', 'outline_color': 'black', 'outline_width': '2' })) item.setZIndex(1) i1_id = layer.addItem(item) item = QgsAnnotationLineItem( QgsLineString( [QgsPoint(11, 13), QgsPoint(12, 13), QgsPoint(12, 15)])) item.setSymbol( QgsLineSymbol.createSimple({ 'color': '#ffff00', 'line_width': '3' })) item.setZIndex(2) i2_id = layer.addItem(item) item = QgsAnnotationMarkerItem(QgsPoint(12, 13)) item.setSymbol( QgsMarkerSymbol.createSimple({ 'color': '100,200,200', 'size': '6', 'outline_color': 'black' })) item.setZIndex(3) i3_id = layer.addItem(item) layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) settings = QgsMapSettings() settings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857')) settings.setExtent(QgsRectangle(1250958, 1386945, 1420709, 1532518)) settings.setOutputSize(QSize(300, 300)) settings.setFlag(QgsMapSettings.Antialiasing, False) rc = QgsRenderContext.fromMapSettings(settings) rc.setCoordinateTransform( QgsCoordinateTransform(layer.crs(), settings.destinationCrs(), QgsProject.instance())) rc.setExtent(rc.coordinateTransform().transformBoundingBox( settings.extent(), QgsCoordinateTransform.ReverseTransform)) image = QImage(200, 200, QImage.Format_ARGB32) image.setDotsPerMeterX(int(96 / 25.4 * 1000)) image.setDotsPerMeterY(int(96 / 25.4 * 1000)) image.fill(QColor(255, 255, 255)) painter = QPainter(image) rc.setPainter(painter) try: renderer = layer.createMapRenderer(rc) renderer.render() finally: painter.end() self.assertTrue( self.imageCheck('layer_render_transform', 'layer_render_transform', image)) # also check details of rendered items item_details = renderer.takeRenderedItemDetails() self.assertEqual([i.layerId() for i in item_details], [layer.id()] * 3) self.assertCountEqual([i.itemId() for i in item_details], [i1_id, i2_id, i3_id]) self.assertEqual( [i.boundingBox() for i in item_details if i.itemId() == i1_id][0], QgsRectangle(11.5, 13, 12, 13.5)) self.assertEqual( [i.boundingBox() for i in item_details if i.itemId() == i2_id][0], QgsRectangle(11, 13, 12, 15)) self.assertEqual([ i.boundingBox().toString(2) for i in item_details if i.itemId() == i3_id ][0], '11.94,12.94 : 12.06,13.06')
def __init__(self, element, model, controls): super(ModelerGraphicItem, self).__init__(None) self.controls = controls self.model = model self.element = element if isinstance(element, ModelerParameter): svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'input.svg')) self.picture = QPicture() painter = QPainter(self.picture) svg.render(painter) self.pixmap = None self.text = element.param.description elif isinstance(element, ModelerOutput): # Output name svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'output.svg')) self.picture = QPicture() painter = QPainter(self.picture) svg.render(painter) self.pixmap = None self.text = element.description else: self.text = element.description self.pixmap = element.algorithm.icon().pixmap(15, 15) self.arrows = [] self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setZValue(1000) if not isinstance(element, ModelerOutput) and controls: svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg')) picture = QPicture() painter = QPainter(picture) svg.render(painter) pt = QPointF( ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, ModelerGraphicItem.BOX_HEIGHT / 2 - FlatButtonGraphicItem.HEIGHT / 2) self.editButton = FlatButtonGraphicItem(picture, pt, self.editElement) self.editButton.setParentItem(self) svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'delete.svg')) picture = QPicture() painter = QPainter(picture) svg.render(painter) pt = QPointF( ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, FlatButtonGraphicItem.HEIGHT / 2 - ModelerGraphicItem.BOX_HEIGHT / 2) self.deleteButton = FlatButtonGraphicItem(picture, pt, self.removeElement) self.deleteButton.setParentItem(self) if isinstance(element, Algorithm): alg = element.algorithm if alg.parameters: pt = self.getLinkPointForParameter(-1) pt = QPointF(0, pt.y()) if controls: self.inButton = FoldButtonGraphicItem( pt, self.foldInput, self.element.paramsFolded) self.inButton.setParentItem(self) if alg.outputs: pt = self.getLinkPointForOutput(-1) pt = QPointF(0, pt.y()) if controls: self.outButton = FoldButtonGraphicItem( pt, self.foldOutput, self.element.outputsFolded) self.outButton.setParentItem(self)