예제 #1
0
    def renderTile(self, x, y):
        """
        Render one tile

        :param x: The x index of the current tile
        :param y: The y index of the current tile
        """
        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))
        finally:
            del src_ds
            tmpfile.close()
            os.unlink(tmpfile.name)
예제 #2
0
    def renderedImage(self,
                      width,
                      height,
                      extent,
                      transp_background=False,
                      layerids=None):
        # render layers with QgsMapRendererCustomPainterJob
        from qgis.core import QgsMapRendererCustomPainterJob
        antialias = True
        settings = self.exportSettings.mapSettings

        # store old map settings
        old_outputSize = settings.outputSize()
        old_extent = settings.extent()
        old_rotation = settings.rotation()
        old_layers = settings.layers()
        old_backgroundColor = settings.backgroundColor()

        # map settings
        settings.setOutputSize(QSize(width, height))
        settings.setExtent(extent.unrotatedRect())
        settings.setRotation(extent.rotation())

        if layerids:
            settings.setLayers(tools.getLayersByLayerIds(layerids))

        if transp_background:
            settings.setBackgroundColor(QColor(Qt.transparent))

        has_pluginlayer = False
        for layer in settings.layers():
            if layer and layer.type() == QgsMapLayer.PluginLayer:
                has_pluginlayer = True
                break

        # create an image
        image = QImage(width, height, QImage.Format_ARGB32_Premultiplied)
        painter = QPainter()
        painter.begin(image)
        if antialias:
            painter.setRenderHint(QPainter.Antialiasing)

        # rendering
        job = QgsMapRendererCustomPainterJob(settings, painter)
        if has_pluginlayer:
            job.renderSynchronously(
            )  # use this method so that TileLayerPlugin layer is rendered correctly
        else:
            job.start()
            job.waitForFinished()
        painter.end()

        # restore map settings
        settings.setOutputSize(old_outputSize)
        settings.setExtent(old_extent)
        settings.setRotation(old_rotation)
        settings.setLayers(old_layers)
        settings.setBackgroundColor(old_backgroundColor)

        return image
예제 #3
0
  def renderedImage(self, width, height, extent, transp_background=False, layerids=None):
    if QGis.QGIS_VERSION_INT < 20700:
      return self._renderedImage2(width, height, extent, transp_background, layerids)

    # render layers with QgsMapRendererCustomPainterJob
    from qgis.core import QgsMapRendererCustomPainterJob
    antialias = True
    settings = self.exportSettings.mapSettings

    # store old map settings
    old_outputSize = settings.outputSize()
    old_extent = settings.extent()
    old_rotation = settings.rotation()
    old_layerids = settings.layers()
    old_backgroundColor = settings.backgroundColor()

    # map settings
    settings.setOutputSize(QSize(width, height))
    settings.setExtent(extent.unrotatedRect())
    settings.setRotation(extent.rotation())

    if layerids is not None:
      settings.setLayers(layerids)

    if transp_background:
      settings.setBackgroundColor(QColor(Qt.transparent))
    #else:    #TODO: remove
      #settings.setBackgroundColor(self.exportSettings.canvas.canvasColor())

    has_pluginlayer = False
    for layerId in settings.layers():
      layer = QgsMapLayerRegistry.instance().mapLayer(layerId)
      if layer and layer.type() == QgsMapLayer.PluginLayer:
        has_pluginlayer = True
        break

    # create an image
    image = QImage(width, height, QImage.Format_ARGB32_Premultiplied)
    painter = QPainter()
    painter.begin(image)
    if antialias:
      painter.setRenderHint(QPainter.Antialiasing)

    # rendering
    job = QgsMapRendererCustomPainterJob(settings, painter)
    if has_pluginlayer:
      job.renderSynchronously()   # use this method so that TileLayerPlugin layer is rendered correctly
    else:
      job.start()
      job.waitForFinished()
    painter.end()

    # restore map settings
    settings.setOutputSize(old_outputSize)
    settings.setExtent(old_extent)
    settings.setRotation(old_rotation)
    settings.setLayers(old_layerids)
    settings.setBackgroundColor(old_backgroundColor)

    return tools.base64image(image)
예제 #4
0
    def renderSingleMetatile(self, metatile):
        if self.feedback.isCanceled():
            return
            # Haven't found a better way to break than to make all the new threads return instantly

        if "Dummy" in threading.current_thread().name or len(
                self.settingsDictionary) == 1:  # single thread testing
            threadSpecificSettings = list(self.settingsDictionary.values())[0]
        else:
            thread_nr = self.thread_nr_re.search(
                threading.current_thread().name)[0]  # terminating number only
            threadSpecificSettings = self.settingsDictionary[thread_nr]

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

        #Append MapSettings scope in order to update map variables (e.g @map_scale) with new extent data
        exp_context = threadSpecificSettings.expressionContext()
        exp_context.appendScope(
            QgsExpressionContextUtils.mapSettingsScope(threadSpecificSettings))
        threadSpecificSettings.setExpressionContext(exp_context)

        image = QImage(size, QImage.Format_ARGB32_Premultiplied)
        image.fill(self.color)
        dpm = threadSpecificSettings.outputDpi() / 25.4 * 1000
        image.setDotsPerMeterX(dpm)
        image.setDotsPerMeterY(dpm)
        painter = QPainter(image)
        job = QgsMapRendererCustomPainterJob(threadSpecificSettings, 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:
            tileImage = image.copy(self.tile_width * r, self.tile_height * c,
                                   self.tile_width, self.tile_height)
            self.writer.write_tile(tile, tileImage)

        # to stop thread sync issues
        with self.progressThreadLock:
            self.progress += 1
            self.feedback.setProgress(100 *
                                      (self.progress / self.totalMetatiles))
예제 #5
0
파일: Rasterize.py 프로젝트: pkampf/QGIS
    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 renderMetatile(self, metatile, dest_crs, outputFormat, renderSettings,
                    transformContext, sourceCrs):
     wgs_to_dest = QgsCoordinateTransform(sourceCrs, dest_crs,
                                          transformContext)
     renderSettings.setExtent(
         wgs_to_dest.transformBoundingBox(QgsRectangle(*metatile.extent())))
     size = QSize(self.WIDTH * metatile.rows(),
                  self.HEIGHT * metatile.columns())
     renderSettings.setOutputSize(size)
     image = QImage(size, outputFormat)
     image.fill(Qt.transparent)
     dpm = renderSettings.outputDpi() / 25.4 * 1000
     image.setDotsPerMeterX(dpm)
     image.setDotsPerMeterY(dpm)
     painter = QPainter(image)
     job = QgsMapRendererCustomPainterJob(renderSettings, painter)
     job.renderSynchronously()
     painter.end()
     return image
예제 #7
0
    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 writeThumbnail(self, mapDestExtent, mapTitle, mapAttr, operation,
                    renderSettings):
     mapTitle = UTILS.normalizeName(mapTitle)
     mapAttr = UTILS.normalizeName(mapAttr)
     renderSettings.setExtent(mapDestExtent)
     size = QSize(180, 180)
     renderSettings.setOutputSize(size)
     image = QImage(size, QImage.Format_ARGB32_Premultiplied)
     image.fill(Qt.transparent)
     dpm = renderSettings.outputDpi() / 25.4 * 1000
     image.setDotsPerMeterX(dpm)
     image.setDotsPerMeterY(dpm)
     painter = QPainter(image)
     job = QgsMapRendererCustomPainterJob(renderSettings, painter)
     job.renderSynchronously()
     painter.end()
     legendFolder = self.getPathForMap(mapTitle, mapAttr, operation)
     os.makedirs(legendFolder, exist_ok=True)
     image.save(os.path.join(legendFolder, 'thumbnail.png'), self.format,
                self.quality)
 def renderMetatile(metatile, dest_crs, renderSettings, transformContext,
                    sourceCrs, width, height):
     wgs_to_dest = QgsCoordinateTransform(sourceCrs, dest_crs,
                                          transformContext)
     renderSettings.setExtent(
         wgs_to_dest.transformBoundingBox(QgsRectangle(*metatile.extent())))
     size = QSize(width * metatile.rows(), height * metatile.columns())
     renderSettings.setOutputSize(size)
     image = QImage(size, renderSettings.outputImageFormat())
     image.fill(Qt.transparent)
     dpm = renderSettings.outputDpi() / 25.4 * 1000
     image.setDotsPerMeterX(dpm)
     image.setDotsPerMeterY(dpm)
     painter = QPainter(image)
     #painter.setRenderHints(QPainter.RenderHint.NonCosmeticDefaultPen, on=True)
     #painter.setCompositionMode(QPainter.CompositionMode_Source)
     job = QgsMapRendererCustomPainterJob(renderSettings, painter)
     job.renderSynchronously()
     painter.end()
     return image
예제 #10
0
    def renderer(self):
        if 'QGIS_AUTH_DB_DIR_PATH' not in os.environ:
            os.environ['QGIS_AUTH_DB_DIR_PATH'] = '/tmp'

        qgis = None
        while True:
            options, result = self.queue.get()

            # Don't start QGIS until first request
            if qgis is None:
                qgis = QgsApplication([], False)
                qgis.setPrefixPath(self.settings.get('path'), True)
                qgis.setDefaultSvgPaths(qgis.svgPaths() +
                                        self.settings.get('svgpaths'))
                qgis.setMaxThreads(1)
                qgis.initQgis()

            try:
                if isinstance(options, LegendOptions):
                    style, = options

                    layer = self._qgs_memory_layer(style)
                    layer.setName(style.parent.display_name)

                    QgsMapLayerRegistry.instance().addMapLayer(layer)

                    root = QgsLayerTreeGroup()
                    root.addLayer(layer)

                    # 'Cannot create a QPixmap when no GUI is being used'
                    #  warning occurs here
                    model = QgsLayerTreeModel(root)

                    settings = QgsLegendSettings()
                    settings.setTitle('')
                    settings.setBoxSpace(1)
                    settings.setSymbolSize(QSizeF(5, 3))
                    settings.setDpi(96)

                    renderer = QgsLegendRenderer(model, settings)

                    # Dots per mm
                    dpmm = settings.dpi() / 25.4

                    min_size = renderer.minimumSize()
                    size = QSize(dpmm * min_size.width(),
                                 dpmm * min_size.height())
                    img = QImage(size, QImage.Format_ARGB32)
                    img.fill(QColor(0, 0, 0, 0))

                    painter = QPainter()
                    painter.begin(img)
                    painter.scale(dpmm, dpmm)
                    renderer.drawLegend(painter)
                    painter.end()

                    QgsMapLayerRegistry.instance().removeAllMapLayers()

                    ba = QByteArray()
                    bf = QBuffer(ba)
                    bf.open(QIODevice.WriteOnly)
                    img.save(bf, 'PNG')
                    bf.close()

                    buf = StringIO()
                    buf.write(bf.data())
                    buf.seek(0)
                    result.put(buf)

                else:
                    path = features = None
                    if isinstance(options, VectorRenderOptions):
                        style, features, render_size, \
                            extended, target_box = options
                        layer = self._qgs_memory_layer(style,
                                                       features=features)
                    elif isinstance(options, RasterRenderOptions):
                        style, path, render_size, \
                            extended, target_box = options
                        layer = QgsRasterLayer(path)
                        layer.loadNamedStyle(
                            self.env.file_storage.filename(style.qml_fileobj))

                    settings = QgsMapSettings()
                    settings.setLayers([layer.id()])
                    settings.setFlag(QgsMapSettings.DrawLabeling)
                    settings.setFlag(QgsMapSettings.Antialiasing)

                    settings.setCrsTransformEnabled(True)
                    settings.setDestinationCrs(layer.crs())
                    settings.setMapUnits(layer.crs().mapUnits())
                    settings.setOutputSize(QSize(*render_size))
                    settings.setExtent(QgsRectangle(*extended))

                    settings.setOutputImageFormat(QImage.Format_ARGB32)
                    bgcolor = QColor.fromRgba(qRgba(255, 255, 255, 0))
                    settings.setBackgroundColor(bgcolor)
                    settings.setOutputDpi(96)

                    QgsMapLayerRegistry.instance().addMapLayer(layer)
                    settings.setLayers([layer.id()])

                    # Create QImage by hand to be able to use
                    # QgsMapRendererCustomPainterJob. Others will not
                    # allow to workaround a bug with overlay rendering.
                    img = QImage(settings.outputSize(), QImage.Format_ARGB32)

                    # These cludges are needed for rendering
                    # on transparent background, otherwise it's a mess.
                    img.fill(QColor.fromRgba(qRgba(255, 255, 255, 255)))
                    img.fill(QColor.fromRgba(qRgba(255, 255, 255, 0)))

                    # DPI should be equal to settings, otherwise an error.
                    # In QImage the resolution is set in dots per meter
                    # for each axis.
                    dpm = settings.outputDpi() / 25.4 * 1000
                    img.setDotsPerMeterX(dpm)
                    img.setDotsPerMeterY(dpm)

                    painter = QPainter(img)
                    job = QgsMapRendererCustomPainterJob(settings, painter)
                    job.renderSynchronously()
                    painter.end()

                    QgsMapLayerRegistry.instance().removeAllMapLayers()

                    img = self._qimage_to_pil(img)

                    # Clip needed part
                    result.put(img.crop(target_box))

                    # Cleanup
                    if path is not None:
                        gdal.Unlink(path)

            except Exception as exc:
                self.logger.error(exc.message)
                result.put(exc)

        qgis.exitQgis()
예제 #11
0
    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
예제 #12
0
파일: TilesXYZ.py 프로젝트: manisandro/QGIS
    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)

        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
예제 #13
0
    def generate(self, writer, parameters, context, feedback):
        feedback.setProgress(1)

        extent = self.parameterAsExtent(parameters, self.EXTENT, context)
        self.min_zoom = self.parameterAsInt(parameters, self.ZOOM_MIN, context)
        self.max_zoom = self.parameterAsInt(parameters, self.ZOOM_MAX, context)
        dpi = self.parameterAsInt(parameters, self.DPI, context)
        self.tile_format = self.formats[self.parameterAsEnum(parameters, self.TILE_FORMAT, context)]
        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()
예제 #14
0
    print('crs authid: %s' % layer.crs().authid())
    print('extent: %s' % layer.sourceExtent().toString())
    QgsProject.instance().addMapLayer(layer)

    image = QImage(QSize(600, 400), QImage.Format_ARGB32_Premultiplied)

    image.fill(QColor(255, 255, 128).rgb())

    painter = QPainter(image)

    settings = QgsMapSettings()
    settings.setOutputDpi(image.logicalDpiX())
    settings.setOutputImageFormat(QImage.Format_ARGB32)
    settings.setDestinationCrs(layer.crs())
    settings.setOutputSize(image.size())
    settings.setFlag(QgsMapSettings.Antialiasing, True)
    settings.setFlag(QgsMapSettings.RenderMapTile, True)
    settings.setFlag(QgsMapSettings.UseAdvancedEffects, True)
    settings.setBackgroundColor(QColor(255, 255, 255, 0))

    settings.setLayers([layer])
    settings.setExtent(layer.extent())

    job = QgsMapRendererCustomPainterJob(settings, painter)
    job.renderSynchronously()
    painter.end()

    output_path = os.environ.get('QGIS_DJANGO_PROVIDER_TEST_OUTPUT',
                                 '/tmp/qgis-django-provider-test.png')
    image.save(output_path, 'png')
예제 #15
0
def GDX_Publisher(self):

    #				print ("GDX_Publisher -------------------------------\n")

    tumpdir = unicode(
        QFileInfo(QgsApplication.qgisUserDatabaseFilePath()).path()
    ) + "/python/plugins/gearthview3/_WebServer"

    #				print (tumpdir)

    adesso = str(datetime.datetime.now())
    adesso = adesso.replace(" ", "_")
    adesso = adesso.replace(":", "_")
    adesso = adesso.replace(".", "_")

    #				print ("adesso: <%s>\n" %(adesso))

    # HERE IT DELETES THE OLD IMAGE ------------------------------------
    # (if you comment these, images still remain ...  :)
    for filename in glob.glob(str(tumpdir + '/*.png')):
        os.remove(str(filename))
    for filename in glob.glob(str(tumpdir + '/*.pngw')):
        os.remove(str(filename))
# ------------------------------------------------------------------

    mapCanvas = self.iface.mapCanvas()

    text = mapCanvas.extent().toString()
    text1 = text.replace(",", " ")
    text2 = text1.replace(" : ", ",")

    #				print ("extent: <%s>\n" %(text2))

    layer = mapCanvas.currentLayer()

    #				print ("Layer: <%s>\n" %(layer.name() ))

    extent = mapCanvas.extent()
    crsSrc = mapCanvas.mapSettings().destinationCrs()
    crsDest = QgsCoordinateReferenceSystem(4326)

    try:
        transform = QgsCoordinateTransform(crsSrc, crsDest,
                                           QgsProject.instance())
    except:
        transform = QgsCoordinateTransform(crsSrc, crsDest)

    projectedExtent = transform.transformBoundingBox(extent)

    x1 = projectedExtent.xMinimum()
    y1 = projectedExtent.yMinimum()

    x2 = projectedExtent.xMaximum()
    y2 = projectedExtent.yMinimum()

    x3 = projectedExtent.xMaximum()
    y3 = projectedExtent.yMaximum()

    x4 = projectedExtent.xMinimum()
    y4 = projectedExtent.yMaximum()

    xc = (x1 + x3) / 2.
    yc = (y1 + y3) / 2.

    out_folder = tumpdir

    # create output image and initialize it

    mapRect = mapCanvas.extent()
    width = mapCanvas.width()
    height = mapCanvas.height()
    srs = mapCanvas.mapSettings().destinationCrs()

    #				print (width, height)

    # MINORU
    #				canvas = mapCanvas
    ##				image = QImage(size.width(), size.height(), QImage.Format_ARGB32_Premultiplied)
    #				image = QImage(QSize(math.ceil(width), math.ceil(height)), QImage.Format_ARGB32)
    #				image.fill(Qt.transparent)
    ##				image.fill(QColor(0))
    #				painter = QPainter()
    #				painter.setRenderHint(QPainter.Antialiasing, True)
    #				painter.setRenderHint(QPainter.TextAntialiasing, True)
    #				painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
    ##				painter.setRenderHint(QPainter.transparent, True)
    #
    ##				brush = QtGui.QBrush()
    ##				brush.setColor(QtGui.QColor(0))
    ##				painter.setBackground(self, 0)
    #
    #				painter.begin(image)
    #				canvas.render(painter)
    #				painter.end()
    # MINORU

    # MINORU2

    #				settings = self.exportSettings.mapSettings

    settings = QgsMapSettings()
    #				extent = settings.extent()
    extent = mapCanvas.extent()

    # store old map settings
    #				old_outputSize = settings.outputSize()
    #				old_extent = settings.extent()
    #				old_rotation = settings.rotation()
    #				old_layers = settings.layers()
    #				old_backgroundColor = settings.backgroundColor()

    # map settings
    settings.setOutputSize(QSize(width, height))
    #				settings.setExtent(extent.unrotatedRect())
    #				settings.setRotation(extent.rotation())

    #				if layerids:
    #				   settings.setLayers(tools.getLayersByLayerIds(layerids))

    #				if transp_background:
    settings.setBackgroundColor(QColor(Qt.transparent))

    has_pluginlayer = False
    for layer in settings.layers():
        if layer and layer.type() == QgsMapLayer.PluginLayer:
            has_pluginlayer = True
            break

    # create an image
    image = QImage(width, height, QImage.Format_ARGB32_Premultiplied)
    painter = QPainter()
    painter.begin(image)
    #				if antialias:
    #				   painter.setRenderHint(QPainter.Antialiasing)

    # rendering
    job = QgsMapRendererCustomPainterJob(settings, painter)
    if has_pluginlayer:
        job.renderSynchronously(
        )  # use this method so that TileLayerPlugin layer is rendered correctly
    else:
        job.start()
        job.waitForFinished()
    painter.end()

    # restore map settings
    #				settings.setOutputSize(old_outputSize)
    #				settings.setExtent(old_extent)
    #				settings.setRotation(old_rotation)
    #				settings.setLayers(old_layers)
    #				settings.setBackgroundColor(old_backgroundColor)

    # MINORU2

    kml = codecs.open(out_folder + '/doc.kml', 'w', encoding='utf-8')

    kml.write('<?xml version="1.0" encoding="UTF-8"?>\n')
    kml.write(
        '<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">\n'
    )
    kml.write('    <Document>\n')
    kml.write('    	 <name>QGisView</name>\n')
    kml.write('    	 <Snippet maxLines="0"></Snippet>\n')

    #				loc = ("    	 <description><![CDATA[https://map.what3words.com/%.7lf,%.7lf]]></description>\n") %(yc, xc)

    #				kml.write(loc)

    kml.write('	     <open>1</open>\n')

    kml.write('	<Style id="sh_style">\n')
    kml.write('		<PolyStyle>\n')
    kml.write('			<color>7fff8080</color>\n')
    kml.write('		</PolyStyle>\n')
    kml.write('	</Style>\n')
    kml.write('	<StyleMap id="msn_style">\n')
    kml.write('		<Pair>\n')
    kml.write('			<key>normal</key>\n')
    kml.write('			<styleUrl>#sn_style</styleUrl>\n')
    kml.write('		</Pair>\n')
    kml.write('		<Pair>\n')
    kml.write('			<key>highlight</key>\n')
    kml.write('			<styleUrl>#sh_style</styleUrl>\n')
    kml.write('		</Pair>\n')
    kml.write('	</StyleMap>\n')
    kml.write('	<Style id="sn_style">\n')
    kml.write('		<PolyStyle>\n')
    kml.write('			<color>00ff8080</color>\n')
    kml.write('			<fill>0</fill>\n')
    kml.write('		</PolyStyle>\n')
    kml.write('	</Style>\n')

    kml.write('	     <Style id="sh_ylw-pushpin">\n')
    kml.write('	     	<IconStyle>\n')
    kml.write('	     		<scale>1.2</scale>\n')
    kml.write('	     	</IconStyle>\n')
    kml.write('	     	<PolyStyle>\n')
    kml.write('	     		<fill>0</fill>\n')
    kml.write('	     	</PolyStyle>\n')
    kml.write('	     </Style>\n')
    kml.write('	     <Style id="sn_ylw-pushpin">\n')
    kml.write('	     	<PolyStyle>\n')
    kml.write('	     		<fill>0</fill>\n')
    kml.write('	     	</PolyStyle>\n')
    kml.write('	     </Style>\n')
    kml.write('	     <StyleMap id="msn_ylw-pushpin">\n')
    kml.write('	     	<Pair>\n')
    kml.write('	     		<key>normal</key>\n')
    kml.write('	     		<styleUrl>#sn_ylw-pushpin</styleUrl>\n')
    kml.write('	     	</Pair>\n')
    kml.write('	     	<Pair>\n')
    kml.write('	     		<key>highlight</key>\n')
    kml.write('	     		<styleUrl>#sh_ylw-pushpin</styleUrl>\n')
    kml.write('	     	</Pair>\n')
    kml.write('	     </StyleMap>\n')

    kml.write('    <StyleMap id="msn_style">\n')
    kml.write('        <Pair>\n')
    kml.write('            <key>normal</key>\n')
    kml.write('            <styleUrl>#sn_style</styleUrl>\n')
    kml.write('        </Pair>\n')
    kml.write('        <Pair>\n')
    kml.write('            <key>highlight</key>\n')
    kml.write('            <styleUrl>#sh_style</styleUrl>\n')
    kml.write('        </Pair>\n')
    kml.write('    </StyleMap>\n')

    kml.write('	     	<Style id="hl">\n')
    kml.write('	     		<IconStyle>\n')
    kml.write('	     			<scale>0.7</scale>\n')
    kml.write('	     			<Icon>\n')
    kml.write(
        '	     				<href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle_highlight.png</href>\n'
    )
    kml.write('	     			</Icon>\n')
    kml.write('	     		</IconStyle>\n')
    kml.write('	     		<LabelStyle>\n')
    kml.write('	     			<scale>0.7</scale>\n')
    kml.write('	     		</LabelStyle>\n')
    kml.write('	     		<ListStyle>\n')
    kml.write('	     		</ListStyle>\n')
    kml.write('	     	</Style>\n')
    kml.write('	     	<Style id="default">\n')
    kml.write('	     		<IconStyle>\n')
    kml.write('	     			<scale>0.7</scale>\n')
    kml.write('	     			<Icon>\n')
    kml.write(
        '	     				<href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png</href>\n'
    )
    kml.write('	     			</Icon>\n')
    kml.write('	     		</IconStyle>\n')
    kml.write('	     		<LabelStyle>\n')
    kml.write('	     			<scale>0.7</scale>\n')
    kml.write('	     		</LabelStyle>\n')
    kml.write('	     		<ListStyle>\n')
    kml.write('	     		</ListStyle>\n')
    kml.write('	     	</Style>\n')
    kml.write('	     	<StyleMap id="default0">\n')
    kml.write('	     		<Pair>\n')
    kml.write('	     			<key>normal</key>\n')
    kml.write('	     			<styleUrl>#default</styleUrl>\n')
    kml.write('	     		</Pair>\n')
    kml.write('	     		<Pair>\n')
    kml.write('	     			<key>highlight</key>\n')
    kml.write('	     			<styleUrl>#hl</styleUrl>\n')
    kml.write('	     		</Pair>\n')
    kml.write('	     	</StyleMap>\n')

    rotazio = 0.0

    rotazio = -(mapCanvas.rotation())

    kml.write('      <Folder>\n')

    xc = (x1 + x3) / 2.
    yc = (y1 + y3) / 2.
    dx = (x3 - x1) * 75000.  #100000.

    kml.write('    		<open>1</open>\n')
    kml.write('    		<NetworkLink>\n')
    kml.write('    		   <name>QGIS_link</name>\n')
    kml.write('    		   <visibility>1</visibility>\n')
    kml.write('    		   <open>1</open>\n')
    kml.write('    		   <Link>\n')
    kml.write('    		      <href>QGIS_link.kmz</href>\n')
    kml.write('    		   </Link>\n')
    kml.write('    		</NetworkLink>\n')

    kml.write('    		<LookAt>\n')
    stringazza = ("    		   <longitude>%lf</longitude>\n") % (xc)
    kml.write(stringazza)
    stringazza = ("    		   <latitude>%lf</latitude>\n") % (yc)
    kml.write(stringazza)
    kml.write('    		   <altitude>0</altitude>\n')

    stringazza = ("    		   <heading>%lf</heading>\n") % (rotazio)
    kml.write(stringazza)

    kml.write('    		   <tilt>0</tilt>\n')
    stringazza = ("    		   <range>%lf</range>\n") % (dx)
    kml.write(stringazza)
    kml.write('    		   <gx:altitudeMode>relativeToGround</gx:altitudeMode>\n')
    kml.write('    		</LookAt>\n')

    kml.write('      <GroundOverlay>\n')
    kml.write('    	 <name>QGisView</name>\n')

    kml.write('    	<Icon>\n')

    xN = projectedExtent.xMinimum()
    yN = projectedExtent.yMinimum()

    nomePNG = ("QGisView_%lf_%lf_%s") % (xN, yN, adesso)
    stringazza = ("    	<href>%s.png</href>\n") % (nomePNG)
    kml.write(stringazza)
    kml.write('    		<viewBoundScale>1.0</viewBoundScale>\n')
    kml.write('    	</Icon>\n')
    kml.write('    	<gx:LatLonQuad>\n')
    kml.write('    		<coordinates>\n')

    stringazza = ("%.7lf,%.7lf,0 %.7lf,%.7lf,0 %.7lf,%.7lf,0 %.7lf,%.7lf,0\n"
                  ) % (x1, y1, x2, y2, x3, y3, x4, y4)
    kml.write(stringazza)

    kml.write('    		</coordinates>\n')
    kml.write('    	</gx:LatLonQuad>\n')
    kml.write('    </GroundOverlay>\n')

    #Export tfw-file
    xScale = (projectedExtent.xMaximum() -
              projectedExtent.xMinimum()) / image.width()
    yScale = (projectedExtent.yMaximum() -
              projectedExtent.yMinimum()) / image.height()

    f = open(out_folder + "/" + nomePNG + ".pngw", 'w')
    f.write(str(xScale) + '\n')
    f.write(str(0) + '\n')
    f.write(str(0) + '\n')
    f.write('-' + str(yScale) + '\n')
    f.write(str(projectedExtent.xMinimum()) + '\n')
    f.write(str(projectedExtent.yMaximum()) + '\n')
    f.write(str(projectedExtent.xMaximum()) + '\n')
    f.write(str(projectedExtent.yMinimum()))
    f.close()

    input_file = out_folder + "/" + nomePNG + ".png"

    #Save the image
    image.save(input_file, "png")

    nomeLay = "gearthview"  # foo default name

    #  Adesso scrivo il vettoriale
    #  Prendo il sistema di riferimento del Layer selezionato ------------------

    curLayer = mapCanvas.currentLayer()

    iface = qgis.utils.iface

    selectedLayers = iface.layerTreeView().selectedLayers()

    if (not selectedLayers):
        #				   print ("selectedLayers is Empty")
        selectedLayers = []
        selectedLayers.append(curLayer)

    for layer in selectedLayers:

        if layer:

            if layer.type() == layer.VectorLayer:

                name = layer.source()
                nomeLayer = layer.name()
                nomeLay = nomeLayer.replace(" ", "_")

                #				    print(layer.name())

                kml.write('    <Folder>\n')
                stringazza = ('			<name>%s</name>\n') % (nomeLay)
                kml.write(stringazza)

                crsSrc = layer.crs()

                crsDest = QgsCoordinateReferenceSystem(4326)  # Wgs84LLH
                xform = QgsCoordinateTransform(crsSrc, crsDest,
                                               QgsProject.instance())

                #----------------------------------------------------------------------------
                #  Trasformo la finestra video in coordinate layer,
                #     per estrarre solo gli elementi visibili
                #----------------------------------------------------------------------------
                #				    mapCanvas = iface.mapCanvas()
                boundBox = mapCanvas.extent()

                xMin = float(boundBox.xMinimum())
                yMin = float(boundBox.yMinimum())

                xMax = float(boundBox.xMaximum())
                yMax = float(boundBox.yMaximum())

                crs2 = mapCanvas.mapSettings().destinationCrs()
                crsSrc2 = QgsCoordinateReferenceSystem(crs2.authid())
                crsDest2 = QgsCoordinateReferenceSystem(layer.crs())
                xform2 = QgsCoordinateTransform(crsSrc2, crsDest2,
                                                QgsProject.instance())

                pt0 = xform2.transform(QgsPointXY(xMin, yMin))
                pt1 = xform2.transform(QgsPointXY(xMax, yMax))

                rect = QgsRectangle(pt0, pt1)

                #				    print ("pt0x: <%s>" %(str(pt0.x())) )
                #				    print ("pt0y: <%s>" %(str(pt0.y())) )
                #				    print ("pt1x: <%s>" %(str(pt1.x())) )
                #				    print ("pt1y: <%s>" %(str(pt1.y())) )

                rq = QgsFeatureRequest(rect)

                iter = layer.getFeatures(rq)

                for feat in iter:

                    nele = feat.id()

                    # fetch geometry
                    geom = feat.geometry()
                    # show some information about the feature

                    #				      print (("GeomType: %d") %(geom.type()))

                    if geom.type() == 0:

                        elem = geom.asPoint()
                        x1 = elem.x()
                        y1 = elem.y()

                        #				        pt1 = xform.transform(QgsPoint(x1, y1))

                        kml.write('	<Placemark>\n')

                        stringazza = ('		<name>%s</name>\n') % (nele)
                        kml.write(stringazza)

                        kml.write('	<styleUrl>#default0</styleUrl>\n')

                        # DESCRIPTION DATA-----------
                        kml.write('	<Snippet maxLines="0"></Snippet>\n')
                        kml.write('	<description><![CDATA[\n')
                        kml.write('<html><body><table border="1">\n')
                        kml.write(
                            '<tr><th>Field Name</th><th>Field Value</th></tr>\n'
                        )

                        # Prendo il contenuto dei campi -------------
                        fff = feat.fields()
                        num = fff.count()
                        iii = -1
                        for f in layer.fields():
                            iii = iii + 1

                            stringazza = ('<tr><td>%s</td><td>%s</td></tr>\n'
                                          ) % (f.name(), feat[iii])

                            kml.write(stringazza)

                        kml.write('</table></body></html>\n')
                        kml.write(']]></description>\n')

                        # EXTENDED DATA -------------
                        stringazza = (
                            '		<ExtendedData><SchemaData schemaUrl="#%s">\n'
                        ) % (nomeLay)
                        kml.write(stringazza)

                        ## Prendo il contenuto dei campi -------------
                        fff = feat.fields()
                        num = fff.count()
                        iii = -1
                        for f in layer.fields():
                            iii = iii + 1

                            stringazza = (
                                '				<SimpleData name="%s">%s</SimpleData>\n'
                            ) % (f.name(), feat[iii])

                            if (stringazza.find('<SimpleData name="descrip') ==
                                    -1):
                                kml.write(stringazza)

                        kml.write('		</SchemaData></ExtendedData>\n')
                        # EXTENDED DATA -------------

                        wkt = layer.crs().toWkt()
                        source = osr.SpatialReference()
                        source.ImportFromWkt(wkt)

                        target = osr.SpatialReference()
                        target.ImportFromEPSG(4326)

                        transform = osr.CoordinateTransformation(
                            source, target)

                        testo = geom.asWkt()
                        #				        print (testo)

                        testo = testo.replace("PointZ (", "Point (")
                        testo = testo.replace("PointZM (", "Point (")
                        testo = testo.replace(" 0,", ",")
                        testo = testo.replace(" 0)", ")")

                        geometra = ogr.CreateGeometryFromWkt(testo)
                        geometra.Transform(transform)
                        testoKML = geometra.ExportToKML()
                        kml.write(testoKML)

                        kml.write('	</Placemark>\n')

                    elif geom.type() == 1:

                        elem = geom.asPolyline()

                        kml.write('	<Placemark>\n')

                        stringazza = ('		<name>%s</name>\n') % (nele)
                        kml.write(stringazza)

                        kml.write('	<styleUrl>#default0</styleUrl>\n')

                        # DESCRIPTION DATA-----------
                        kml.write('	<Snippet maxLines="0"></Snippet>\n')
                        kml.write('	<description><![CDATA[\n')
                        kml.write('<html><body><table border="1">\n')
                        kml.write(
                            '<tr><th>Field Name</th><th>Field Value</th></tr>\n'
                        )

                        # Prendo il contenuto dei campi -------------
                        fff = feat.fields()
                        num = fff.count()
                        iii = -1
                        for f in layer.fields():
                            iii = iii + 1

                            stringazza = ('<tr><td>%s</td><td>%s</td></tr>\n'
                                          ) % (f.name(), feat[iii])

                            kml.write(stringazza)

                        kml.write('</table></body></html>\n')
                        kml.write(']]></description>\n')

                        # EXTENDED DATA -------------
                        stringazza = (
                            '		<ExtendedData><SchemaData schemaUrl="#%s">\n'
                        ) % (nomeLay)
                        kml.write(stringazza)

                        ## Prendo il contenuto dei campi -------------
                        fff = feat.fields()
                        num = fff.count()
                        iii = -1
                        for f in layer.fields():
                            iii = iii + 1

                            stringazza = (
                                '				<SimpleData name="%s">%s</SimpleData>\n'
                            ) % (f.name(), feat[iii])

                            if (stringazza.find('<SimpleData name="descrip') ==
                                    -1):
                                kml.write(stringazza)

                        kml.write('		</SchemaData></ExtendedData>\n')
                        # EXTENDED DATA -------------

                        wkt = layer.crs().toWkt()
                        source = osr.SpatialReference()
                        source.ImportFromWkt(wkt)

                        target = osr.SpatialReference()
                        target.ImportFromEPSG(4326)

                        transform = osr.CoordinateTransformation(
                            source, target)

                        testo = geom.asWkt()
                        #				        print (testo)

                        testo = testo.replace("LineStringZ (", "LineString (")
                        testo = testo.replace("LineStringZM (", "LineString (")
                        testo = testo.replace(" 0,", ",")
                        testo = testo.replace(" 0)", ")")

                        geometra = ogr.CreateGeometryFromWkt(testo)
                        geometra.Transform(transform)
                        testoKML = geometra.ExportToKML()
                        kml.write(testoKML)

                        kml.write('	</Placemark>\n')

                    elif geom.type() == 2:

                        kml.write('	<Placemark>\n')

                        stringazza = ('		<name>%s</name>\n') % (nele)
                        kml.write(stringazza)
                        kml.write('		<styleUrl>#msn_style</styleUrl>\n')

                        # DESCRIPTION DATA-----------
                        kml.write('	<Snippet maxLines="0"></Snippet>\n')
                        kml.write('	<description><![CDATA[\n')
                        kml.write('<html><body><table border="1">\n')
                        kml.write(
                            '<tr><th>Field Name</th><th>Field Value</th></tr>\n'
                        )

                        # Prendo il contenuto dei campi -------------
                        fff = feat.fields()
                        num = fff.count()
                        iii = -1
                        for f in layer.fields():
                            iii = iii + 1

                            stringazza = ('<tr><td>%s</td><td>%s</td></tr>\n'
                                          ) % (f.name(), feat[iii])

                            kml.write(stringazza)

                        kml.write('</table></body></html>\n')
                        kml.write(']]></description>\n')

                        # EXTENDED DATA -------------
                        stringazza = (
                            '		<ExtendedData><SchemaData schemaUrl="#%s">\n'
                        ) % (nomeLay)
                        kml.write(stringazza)

                        ## Prendo il contenuto dei campi -------------
                        fff = feat.fields()
                        num = fff.count()
                        iii = -1
                        for f in layer.fields():
                            iii = iii + 1

                            stringazza = (
                                '				<SimpleData name="%s">%s</SimpleData>\n'
                            ) % (f.name(), feat[iii])

                            if (stringazza.find('<SimpleData name="descrip') ==
                                    -1):
                                kml.write(stringazza)

                        kml.write('		</SchemaData></ExtendedData>\n')
                        # EXTENDED DATA -------------

                        testo = geom.asWkt()
                        #				        print (testo)

                        wkt = layer.crs().toWkt()
                        source = osr.SpatialReference()
                        source.ImportFromWkt(wkt)

                        target = osr.SpatialReference()
                        target.ImportFromEPSG(4326)

                        transform = osr.CoordinateTransformation(
                            source, target)

                        testo = testo.replace("PolygonZ (", "Polygon (")
                        testo = testo.replace("PolygonZM (", "Polygon (")
                        testo = testo.replace(" 0,", ",")
                        testo = testo.replace(" 0)", ")")
                        geometra = ogr.CreateGeometryFromWkt(testo)
                        geometra.Transform(transform)
                        testoKML = geometra.ExportToKML()

                        testoKML = testoKML.replace(
                            "<Polygon>",
                            "<Polygon><altitudeMode>relativeToGround</altitudeMode>"
                        )

                        kml.write(testoKML)

                        kml.write('	</Placemark>\n')

                kml.write('  </Folder>\n')

    kml.write('</Folder>\n')

    kml.write('</Document>\n')
    kml.write('</kml>\n')
    kml.close()

    if platform.system() == "Windows":
        os.startfile(out_folder + '/doc.kml')

    if platform.system() == "Darwin":
        os.system("open " + str(out_folder + '/doc.kml'))

    if platform.system() == "Linux":
        os.system("xdg-open " + str(out_folder + '/doc.kml'))
예제 #16
0
    def renderer(self):
        qgis = QgsApplication([], False)
        qgis.setPrefixPath(self.settings.get('path'), True)
        qgis.setMaxThreads(1)
        qgis.initQgis()

        while True:
            try:
                fndata, srs, render_size, extended, \
                    target_box, result = self.queue.get()

                layer = QgsVectorLayer(fndata, 'layer', 'ogr')

                crs = QgsCoordinateReferenceSystem(srs.id)
                layer.setCrs(crs)

                settings = QgsMapSettings()
                settings.setLayers([layer.id()])
                settings.setFlag(QgsMapSettings.DrawLabeling)
                settings.setFlag(QgsMapSettings.Antialiasing)

                settings.setCrsTransformEnabled(True)
                settings.setDestinationCrs(crs)
                settings.setMapUnits(crs.mapUnits())
                settings.setOutputSize(QSize(*render_size))
                settings.setExtent(QgsRectangle(*extended))

                settings.setOutputImageFormat(QImage.Format_ARGB32)
                bgcolor = QColor.fromRgba(qRgba(255, 255, 255, 0))
                settings.setBackgroundColor(bgcolor)
                settings.setOutputDpi(96)

                QgsMapLayerRegistry.instance().addMapLayer(layer)
                settings.setLayers([layer.id()])

                # Создаем QImage руками чтобы можно было использовать
                # QgsMapRendererCustomPainterJob. Остальные не позволяют
                # обойти баг с рисованием поверх старого.
                img = QImage(settings.outputSize(), QImage.Format_ARGB32)

                # Эти костыли нужны для того, чтобы корректно рисовались
                # слои на прозрачном фоне, без этого получается каша.
                img.fill(QColor.fromRgba(qRgba(255, 255, 255, 255)))
                img.fill(QColor.fromRgba(qRgba(255, 255, 255, 0)))

                # DPI должно быть таким же как в settings, иначе ошибка. В QImage
                # разрешение указывается в точках на метр по каждой оси.
                dpm = settings.outputDpi() / 25.4 * 1000
                img.setDotsPerMeterX(dpm)
                img.setDotsPerMeterY(dpm)

                painter = QPainter(img)
                job = QgsMapRendererCustomPainterJob(settings, painter)
                job.renderSynchronously()
                painter.end()

                QgsMapLayerRegistry.instance().removeAllMapLayers()

                # Преобразование QImage в PIL
                ba = QByteArray()
                bf = QBuffer(ba)
                bf.open(QIODevice.WriteOnly)
                img.save(bf, 'PNG')
                bf.close()

                buf = StringIO()
                buf.write(bf.data())
                buf.seek(0)

                img = PIL.Image.open(buf)

                # Вырезаем нужный нам кусок изображения
                result.put(img.crop(target_box))

            except Exception as e:
                self.logger.error(e.message)

        qgis.exitQgis()
예제 #17
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()