Пример #1
0
    def add_to_layout(self,
                      layout,
                      background_color=QColor(255, 255, 255, 0),
                      size=80):
        """
        Inspired by https://opensourceoptions.com/blog/pyqgis-create-and-print-a-map-layout-with-python/
        """
        layers = [layer.layer() for layer in self.group.findLayers()]
        # create map item in the layout
        map = QgsLayoutItemMap(layout)
        map.setRect(20, 20, 20, 20)
        # set the map extent
        ms = QgsMapSettings()
        ms.setLayers(layers)  # set layers to be mapped
        crs = QgsCoordinateReferenceSystem()
        crs.createFromProj(self.projection.value.proj_str(self.origin))
        map.setCrs(crs)
        map.setFollowVisibilityPreset(True)
        map.setFollowVisibilityPresetName(Globe.THEME_NAME)
        rect = QgsRectangle(ms.fullExtent())

        ms.setExtent(rect)
        map.setExtent(rect)
        map.setBackgroundColor(background_color)
        layout.addLayoutItem(map)
        map.attemptMove(QgsLayoutPoint(5, 20, QgsUnitTypes.LayoutMillimeters))
        map.attemptResize(
            QgsLayoutSize(size, size, QgsUnitTypes.LayoutMillimeters))
Пример #2
0
def cvt_vtr(self):
    QSWATMOD_path_dict = self.dirs_and_paths()
    selectedVector = self.dlg.comboBox_vector_lyrs.currentText()
    layer = QgsProject.instance().mapLayersByName(str(selectedVector))[0]

    # Find .dis file and read number of rows, cols, x spacing, and y spacing (not allowed to change)
    for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder']) + "/*.dis"):
        with open(filename, "r") as f:
            data = []
            for line in f.readlines():
                if not line.startswith("#"):
                    data.append(line.replace('\n', '').split())
        nrow = int(data[0][1])
        ncol = int(data[0][2])
        delr = float(data[2][1])  # is the cell width along rows (y spacing)
        delc = float(
            data[3][1])  # is the cell width along columns (x spacing).

    # get extent
    ext = layer.extent()
    xmin = ext.xMinimum()
    xmax = ext.xMaximum()
    ymin = ext.yMinimum()
    ymax = ext.yMaximum()
    extent = "{a},{b},{c},{d}".format(a=xmin, b=xmax, c=ymin, d=ymax)

    fdnames = [
        field.name() for field in layer.dataProvider().fields()
        if not (field.name() == 'fid' or field.name() == 'id'
                or field.name() == 'xmin' or field.name() == 'xmax'
                or field.name() == 'ymin' or field.name() == 'ymax'
                or field.name() == 'grid_id' or field.name() == 'row'
                or field.name() == 'col' or field.name() == 'elev_mf')
    ]

    # Create swatmf_results tree inside
    root = QgsProject.instance().layerTreeRoot()
    if root.findGroup("swatmf_results"):
        swatmf_results = root.findGroup("swatmf_results")
    else:
        swatmf_results = root.insertGroup(0, "swatmf_results")

    if root.findGroup(selectedVector):
        rastergroup = root.findGroup(selectedVector)
    else:
        rastergroup = swatmf_results.insertGroup(0, selectedVector)
    per = 0
    self.dlg.progressBar_cvt_vtr.setValue(0)
    for fdnam in fdnames:
        QCoreApplication.processEvents()
        nodata = float(self.dlg.lineEdit_nodata.text())
        mincolor = self.dlg.mColorButton_min_rmap.color().name()
        maxcolor = self.dlg.mColorButton_max_rmap.color().name()
        name = fdnam
        name_ext = "{}.tif".format(name)
        output_dir = QSWATMOD_path_dict['SMshps']
        # create folder for each layer output
        rasterpath = os.path.join(output_dir, selectedVector)
        if not os.path.exists(rasterpath):
            os.makedirs(rasterpath)
        output_raster = os.path.join(rasterpath, name_ext)
        params = {
            'INPUT': layer,
            'FIELD': fdnam,
            'UNITS': 1,
            'WIDTH': delc,
            'HEIGHT': delr,
            'EXTENT': extent,
            'NODATA': nodata,
            'DATA_TYPE': 5,  #Float32
            'OUTPUT': output_raster
        }
        processing.run("gdal:rasterize", params)
        rasterlayer = QgsRasterLayer(output_raster,
                                     '{0} ({1})'.format(fdnam, selectedVector))
        QgsProject.instance().addMapLayer(rasterlayer, False)
        rastergroup.insertChildNode(0, QgsLayerTreeLayer(rasterlayer))
        stats = rasterlayer.dataProvider().bandStatistics(
            1, QgsRasterBandStats.All)
        rmin = stats.minimumValue
        rmax = stats.maximumValue
        fnc = QgsColorRampShader()
        lst = [
            QgsColorRampShader.ColorRampItem(rmin, QColor(mincolor)),
            QgsColorRampShader.ColorRampItem(rmax, QColor(maxcolor))
        ]
        fnc.setColorRampItemList(lst)
        fnc.setColorRampType(QgsColorRampShader.Interpolated)
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(fnc)
        renderer = QgsSingleBandPseudoColorRenderer(rasterlayer.dataProvider(),
                                                    1, shader)
        rasterlayer.setRenderer(renderer)
        rasterlayer.triggerRepaint()

        # create image
        img = QImage(QSize(800, 800), QImage.Format_ARGB32_Premultiplied)
        # set background color
        # bcolor = QColor(255, 255, 255, 255)
        bcolor = QColor(255, 255, 255, 0)
        img.fill(bcolor.rgba())
        # create painter
        p = QPainter()
        p.begin(img)
        p.setRenderHint(QPainter.Antialiasing)
        # create map settings
        ms = QgsMapSettings()
        ms.setBackgroundColor(bcolor)

        # set layers to render
        flayer = QgsProject.instance().mapLayersByName(rasterlayer.name())
        ms.setLayers([flayer[0]])

        # set extent
        rect = QgsRectangle(ms.fullExtent())
        rect.scale(1.1)
        ms.setExtent(rect)

        # set ouptut size
        ms.setOutputSize(img.size())

        # setup qgis map renderer
        render = QgsMapRendererCustomPainterJob(ms, p)
        render.start()
        render.waitForFinished()
        # get timestamp
        p.drawImage(QPoint(), img)
        pen = QPen(Qt.red)
        pen.setWidth(2)
        p.setPen(pen)

        font = QFont()
        font.setFamily('Times')
        # font.setBold(True)
        font.setPointSize(18)
        p.setFont(font)
        # p.setBackground(QColor('sea green')) doesn't work
        p.drawText(QRect(0, 0, 800, 800), Qt.AlignRight | Qt.AlignBottom,
                   fdnam)
        p.end()

        # save the image
        img.save(os.path.join(rasterpath, '{:03d}_{}.jpg'.format(per, fdnam)))

        # Update progress bar
        per += 1
        progress = round((per / len(fdnames)) * 100)
        self.dlg.progressBar_cvt_vtr.setValue(progress)
        QCoreApplication.processEvents()
        self.dlg.raise_()

    duration = self.dlg.doubleSpinBox_ani_r_time.value()

    # filepaths
    fp_in = os.path.join(rasterpath, '*.jpg')
    fp_out = os.path.join(rasterpath, '{}.gif'.format(selectedVector))

    # https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif
    fimg, *fimgs = [Image.open(f) for f in sorted(glob.glob(fp_in))]
    fimg.save(fp=fp_out,
              format='GIF',
              append_images=fimgs,
              save_all=True,
              duration=duration * 1000,
              loop=0,
              transparency=0)

    msgBox = QMessageBox()
    msgBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png'))
    msgBox.setWindowTitle("Coverted!")
    msgBox.setText(
        "Fields from {} were converted successfully!".format(selectedVector))
    msgBox.exec_()

    questionBox = QMessageBox()
    questionBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png'))
    reply = QMessageBox.question(questionBox, 'Open?',
                                 'Do you want to open the animated gif file?',
                                 QMessageBox.Yes, QMessageBox.No)
    if reply == QMessageBox.Yes:
        os.startfile(os.path.join(rasterpath, '{}.gif'.format(selectedVector)))