def createLayerRenderSettings(self, layer, dest_crs, outputFormat):
     settings = QgsMapSettings()
     settings.setFlag(QgsMapSettings.Flag.Antialiasing, on=False)
     settings.setFlag(QgsMapSettings.Flag.UseRenderingOptimization,
                      on=False)
     settings.setFlag(QgsMapSettings.Flag.UseAdvancedEffects, on=False)
     settings.setOutputImageFormat(outputFormat)
     settings.setDestinationCrs(dest_crs)
     settings.setLayers([layer])
     dpi = 256
     settings.setOutputDpi(dpi)
     canvas_red = QgsProject.instance().readNumEntry(
         'Gui', '/CanvasColorRedPart', 255)[0]
     canvas_green = QgsProject.instance().readNumEntry(
         'Gui', '/CanvasColorGreenPart', 255)[0]
     canvas_blue = QgsProject.instance().readNumEntry(
         'Gui', '/CanvasColorBluePart', 255)[0]
     color = QColor(canvas_red, canvas_green, canvas_blue, 0)
     settings.setBackgroundColor(color)
     labeling_engine_settings = settings.labelingEngineSettings()
     labeling_engine_settings.setFlag(
         QgsLabelingEngineSettings.UsePartialCandidates, False)
     settings.setLabelingEngineSettings(labeling_engine_settings)
     try:
         layer.resampleFilter().setZoomedInResampler(None)
         layer.resampleFilter().setZoomedOutResampler(None)
         layer.resampleFilter().setOn(False)
     except:
         pass  #Is not a raster
     return settings
    def createLayerRenderSettings(layer, dest_crs, outputFormat, feedback):
        settings = QgsMapSettings()
        try:
            settings.setFlag(QgsMapSettings.Flag.Antialiasing, False)
        except:
            pass

        try:
            settings.setFlag(QgsMapSettings.Flag.UseRenderingOptimization,
                             True)
        except:
            feedback.pushConsoleInfo(
                "Warning: Rendering optimizations not available in your QGIS version."
            )
            pass
        try:
            settings.setFlag(QgsMapSettings.Flag.UseAdvancedEffects, False)
        except:
            feedback.pushConsoleInfo(
                "Warning: Opacity and blending effects not available in your QGIS version."
            )
            pass

        settings.setOutputImageFormat(outputFormat)
        settings.setDestinationCrs(dest_crs)
        settings.setLayers([layer])
        settings.setOutputDpi(256)
        color = QColor(0, 0, 0, 0)
        settings.setBackgroundColor(color)
        try:
            labeling_engine_settings = settings.labelingEngineSettings()
            try:
                labeling_engine_settings.setFlag(
                    QgsLabelingEngineSettings.UsePartialCandidates, False)
            except:
                feedback.pushConsoleInfo(
                    "Warning: Cannot draw label candidates that are partially outside of the map view. Your QGIS version has not 'UsePartialCandidates'."
                )
                pass
            settings.setLabelingEngineSettings(labeling_engine_settings)
        except:
            feedback.pushConsoleInfo(
                "Warning: This QGIS version does not support label Engine.")
        try:
            layer.resampleFilter().setZoomedInResampler(None)
            layer.resampleFilter().setZoomedOutResampler(None)
            layer.resampleFilter().setOn(False)
        except:
            pass  #Is not a raster
        return settings
Пример #3
0
    def generate(self, writer, parameters, context, feedback):
        feedback.setProgress(1)

        extent = self.parameterAsExtent(parameters, self.EXTENT, context)
        self.min_zoom = self.parameterAsInt(parameters, self.ZOOM_MIN, context)
        self.max_zoom = self.parameterAsInt(parameters, self.ZOOM_MAX, context)
        dpi = self.parameterAsInt(parameters, self.DPI, context)
        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()