Пример #1
0
def write_image(
    feedback,
    tex_layer,
    tex_pixel_size,
    destination_crs,
    destination_extent,
    filepath,
    imagetype,
):
    """
    Save current QGIS canvas to image file.
    """

    feedback.pushInfo("Rendering texture image (timeout in 30s)...")
    project = QgsProject.instance()

    # Get extent size in meters
    d = QgsDistanceArea()
    d.setSourceCrs(
        crs=destination_crs, context=QgsProject.instance().transformContext()
    )
    p00, p10, p01 = (
        QgsPointXY(destination_extent.xMinimum(), destination_extent.yMinimum()),
        QgsPointXY(destination_extent.xMaximum(), destination_extent.yMinimum()),
        QgsPointXY(destination_extent.xMinimum(), destination_extent.yMaximum()),
    )
    wm = d.measureLine(p00, p10)  # euclidean dist, extent width in m
    hm = d.measureLine(p00, p01)  # euclidean dist, extent height in m

    # Image settings and texture layer choice
    settings = QgsMapSettings()  # build settings
    settings.setDestinationCrs(destination_crs)  # set output crs
    settings.setExtent(destination_extent)  # in destination_crs
    if tex_layer:
        layers = (tex_layer,)  # chosen texture layer
    else:
        canvas = iface.mapCanvas()
        layers = canvas.layers()  # get visible layers
    wpix = int(wm / tex_pixel_size)
    hpix = int(hm / tex_pixel_size)
    settings.setOutputSize(QSize(wpix, hpix))
    settings.setLayers(layers)
    feedback.pushInfo(
        f"Requested texture size: {wm:.2f}x{hm:.2f} m, {wpix}x{hpix} pixels."
    )

    # Render and save image
    render = QgsMapRendererParallelJob(settings)
    render.start()
    t0 = time.time()
    while render.isActive():
        dt = time.time() - t0
        QCoreApplication.processEvents()
        if feedback.isCanceled():
            render.cancelWithoutBlocking()
            return
        if dt >= 30.0:
            render.cancelWithoutBlocking()
            feedback.reportError("Render timed out, no texture saved.")
            return
    image = render.renderedImage()
    try:
        image.save(filepath, imagetype)
    except IOError:
        raise QgsProcessingException(
            f"Texture not writable to <{filepath}>, cannot proceed."
        )
    feedback.pushInfo(f"Texture saved in {dt:.2f} seconds.")
Пример #2
0
def write_texture(
    feedback,
    tex_layer,
    tex_extent,
    tex_pixel_size,
    utm_crs,  # destination_crs
    filepath,
    imagetype,
):
    """
    Crop and save texture to image file.
    """

    # Calc tex_extent size in meters (it is in utm)
    tex_extent_xm = tex_extent.xMaximum() - tex_extent.xMinimum()
    tex_extent_ym = tex_extent.yMaximum() - tex_extent.yMinimum()

    # Calc tex_extent size in pixels
    tex_extent_xpix = int(tex_extent_xm / tex_pixel_size)
    tex_extent_ypix = int(tex_extent_ym / tex_pixel_size)

    # Choose exporting layers
    if tex_layer:  # use user tex layer
        layers = (tex_layer,)
    else:  # no user tex layer, use map canvas
        canvas = iface.mapCanvas()
        layers = canvas.layers()

    # Image settings and texture layer choice
    settings = QgsMapSettings()  # build settings
    settings.setDestinationCrs(utm_crs)  # set output crs
    settings.setExtent(tex_extent)  # in utm_crs
    settings.setOutputSize(QSize(tex_extent_xpix, tex_extent_ypix))
    settings.setLayers(layers)

    feedback.pushInfo(
        f"Texture size: {tex_extent_xpix} x {tex_extent_ypix} pixels, {tex_extent_xm:.1f} x {tex_extent_ym:.1f} meters"
    )

    # Render and save image
    render = QgsMapRendererParallelJob(settings)
    render.start()
    t0 = time.time()
    while render.isActive():
        dt = time.time() - t0
        QCoreApplication.processEvents()
        if feedback.isCanceled():
            render.cancelWithoutBlocking()
            return
        if dt >= 30.0:
            render.cancelWithoutBlocking()
            feedback.reportError("Texture render timed out, no texture saved.")
            return
    image = render.renderedImage()
    try:
        image.save(filepath, imagetype)
    except IOError:
        raise QgsProcessingException(
            f"Texture not writable to <{filepath}>, cannot proceed."
        )
    feedback.pushInfo(f"Saved (in {dt:.2f} s): <{filepath}>")