首页 > 其他分享 >PyQGIS开发 3 基础功能开发

PyQGIS开发 3 基础功能开发

时间:2024-09-20 14:53:10浏览次数:3  
标签:文件 功能 self layer 栅格 PyQGIS 开发 图层 添加

PyQGIS开发 3 基础功能开发

1 添加图层树与地图视图

1.1 添加控件

1.2 Python代码

from PyQt5.QtCore import QMimeData
from qgis.PyQt.QtWidgets import QMainWindow
from qgis._core import QgsMapLayer, QgsRasterLayer, QgsVectorLayer
from qgis.core import QgsProject, QgsLayerTreeModel
from qgis.gui import QgsLayerTreeView, QgsMapCanvas, QgsLayerTreeMapCanvasBridge
import os.path as osp
from ui.mainWindow import Ui_MainWindow
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QFileDialog, QMessageBox

PROJECT = QgsProject.instance()


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        """
        MainWindow 类的初始化函数。

        该函数初始化 MainWindow 类的实例,设置窗口标题、初始化图层树、地图画布、
        图层树视图模型、建立图层树与地图画布的桥接,并注册界面事件功能。
        """
        super(MainWindow, self).__init__()
        self.setupUi(self)
        # 1 修改标题
        self.setWindowTitle("QGIS自定义界面")
        # 2 初始化图层树
        vl = QVBoxLayout(self.dockWidgetContents)
        self.layerTreeView = QgsLayerTreeView(self)
        vl.addWidget(self.layerTreeView)
        # 3 初始化地图画布
        self.mapCanvas = QgsMapCanvas(self)
        hl = QHBoxLayout(self.frame)
        hl.setContentsMargins(0, 0, 0, 0)  # 设置周围间距
        hl.addWidget(self.mapCanvas)
        # 4 设置图层树风格
        self.model = QgsLayerTreeModel(PROJECT.layerTreeRoot(), self)
        self.model.setFlag(QgsLayerTreeModel.AllowNodeRename)  # 允许图层节点重命名
        self.model.setFlag(QgsLayerTreeModel.AllowNodeReorder)  # 允许图层拖拽排序
        self.model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility)  # 允许改变图层节点可视性
        self.model.setFlag(QgsLayerTreeModel.ShowLegendAsTree)  # 展示图例
        self.model.setAutoCollapseLegendNodes(10)  # 当节点数大于等于10时自动折叠
        self.layerTreeView.setModel(self.model)
        # 4 建立图层树与地图画布的桥接
        self.layerTreeBridge = QgsLayerTreeMapCanvasBridge(PROJECT.layerTreeRoot(), self.mapCanvas, self)
        # 注册界面事件功能
        self.registerFunc()
        # 5 初始加载影像
        self.firstAdd = True
        # 6 允许拖拽文件
        self.setAcceptDrops(True)

    def registerFunc(self):
        """
        注册动作的触发函数

        该函数将动作与对应的触发函数连接起来,使得当用户点击动作时,相应的函数会被触发
        """
        self.actionOpenRaster.triggered.connect(self.actionOpenRasterTriggered)
        self.actionOpenVector.triggered.connect(self.actionOpenVectorTriggered)


    def actionOpenRasterTriggered(self):
        """
        处理打开栅格文件的触发事件

        此方法通过 QFileDialog 弹出文件选择对话框,获取用户选择的栅格文件路径。
        如果用户选择了文件,将调用 addRasterLayer 方法添加该文件对应的栅格图层到窗口中。

        参数:
            None

        返回值:
            无

        异常: 
            如果文件选择对话框取消或出错,不会添加任何图层。
        """
        data_file, ext = QFileDialog.getOpenFileName(
            self,
            '打开',
            '',
            'GeoTiff(*.tif;*tiff;*TIF;*TIFF);;All Files(*);;JPEG(*.jpg;*.jpeg;*.JPG;*.JPEG);;*.png;;*.pdf')
        if data_file:
            self.addRasterLayer(data_file)


    def actionOpenVectorTriggered(self):
        """
        处理打开矢量文件的触发事件

        此方法通过 QFileDialog 弹出文件选择对话框,获取用户选择的矢量文件路径。
        如果用户选择了文件,将调用 addVectorLayer 方法添加该文件对应的矢量图层到窗口中。

        参数:
            None

        返回值:
            无

        异常: 
            如果文件选择对话框取消或出错,不会添加任何图层。
        """
        data_file, ext = QFileDialog.getOpenFileName(
            self, '打开', '',
            "ShapeFile(*.shp);;All Files(*);;Other(*.gpkg;*.geojson;*.kml)")
        if data_file:
            self.addVectorLayer(data_file)


    def addRasterLayer(self, rasterFilePath):
        """
        将栅格图层添加到地图画布中。

        此方法用于将栅格文件加载为栅格图层,并将其添加到地图画布中显示。如果是第一次添加图层,它会作为基础图层添加,并设置为可编辑状态。否则,它会作为普通图层添加。

        参数:
            rasterFilePath (str): 要添加的栅格文件的路径。

        返回:
            无

        注意:
            如果文件路径无效或文件无法加载为栅格图层,则不会添加任何图层。
        """
        # 读取栅格文件并创建栅格图层
        raster_layer = self.readRasterFile(rasterFilePath)

        # 如果是首次添加图层,则将其作为基础图层添加到地图画布,并设置为可编辑
        if self.firstAdd:
            self.addMapLayer(raster_layer, self.mapCanvas, True)
            self.firstAdd = False
        # 否则,将其作为普通图层添加到地图画布
        else:
            self.addMapLayer(raster_layer, self.mapCanvas)


    def addVectorLayer(self, vectorFilePath):
        """
         向当前QGIS项目中添加一个新的矢量图层,并显示在地图画布上。
        
         参数:
            vectorFilePath (str): 要添加的矢量文件的路径。
            
         返回:
            None
        """
        vector_layer = self.readVectorFile(vectorFilePath)
        if self.firstAdd:
            self.addMapLayer(vector_layer, self.mapCanvas, True)
            self.firstAdd = False
        else:
            self.addMapLayer(vector_layer, self.mapCanvas)


    def addMapLayer(self, layer: QgsMapLayer, mapCanvas: QgsMapCanvas, firstAddLayer=False):
        """
        将地图层添加到 QGIS 项目和地图画布中。
        
        参数:
            layer (QgsMapLayer):要添加的地图层。
            mapCanvas (QgsMapCanvas):地图画布,用于显示地图层。
            firstAddLayer (bool):是否是第一次添加图层。如果是,将设置画布的 CRS 和范围。
        
        返回:
            无
        
        注意:
            如果图层已经存在,它将重命名以避免冲突。如果图层无效,它将不会被添加。
        """
        # 检查图层是否有效
        if layer.isValid():
            # 如果是第一次添加图层,设置画布的 CRS 和范围
            if firstAddLayer:
                mapCanvas.setDestinationCrs(layer.crs())
                mapCanvas.setExtent(layer.extent())

            # 确保图层名称唯一
            while PROJECT.mapLayersByName(layer.name()):
                layer.setName(layer.name() + "_1")

            # 将图层添加到项目中
            PROJECT.addMapLayer(layer)

            # 更新画布的图层列表并刷新
            layers = [layer] + [PROJECT.mapLayer(i) for i in PROJECT.mapLayers()]
            mapCanvas.setLayers(layers)
            mapCanvas.refresh()

    def readRasterFile(self, rasterFilePath: str) -> QgsRasterLayer:
        """
        从给定的文件路径中读取栅格文件,并返回相应的 QgsRasterLayer 对象。

        参数:
            rasterFilePath (str):要读取的栅格文件的完整路径。

        返回:
            QgsRasterLayer:如果成功读取文件,则返回相应的 QgsRasterLayer 对象;否则返回 None。
        """
        raster_layer = QgsRasterLayer(rasterFilePath, osp.basename(rasterFilePath))
        return raster_layer

    def readVectorFile(self, vectorFilePath):
        """
        从给定的文件路径中读取矢量文件,并返回相应的 QgsVectorLayer 对象。

        参数:
            vectorFilePath (str): 要读取的矢量文件的完整路径。

        返回:
            QgsVectorLayer: 如果成功读取文件,则返回相应的 QgsVectorLayer 对象;否则返回 None。
        """
        vector_layer = QgsVectorLayer(vectorFilePath, osp.basename(vectorFilePath), "ogr")
        return vector_layer

    def dragEnterEvent(self, fileData):
        """
        处理拖放文件进入窗口的事件。

        如果拖放的文件是URL类型,则接受事件;否则,忽略事件。

        参数:
        fileData - 拖放事件的数据。

        返回:
        None
        """
        if fileData.mimeData().hasUrls():
            fileData.accept()
        else:
            fileData.ignore()


    def dropEvent(self, fileData):
        """
        处理拖放事件,根据文件类型添加对应的图层到QGIS中

        参数:
        fileData (QDragEnterEvent): 拖放事件对象

        返回:
        None
        """
        mimeData: QMimeData = fileData.mimeData()
        filePathList = [u.path()[1:] for u in mimeData.urls()]
        for filePath in filePathList:
            filePath: str = filePath.replace("/", "//")
            if filePath.split(".")[-1] in ["tif", "TIF", "tiff", "TIFF", "GTIFF", "png", "jpg", "pdf"]:
                self.addRasterLayer(filePath)
            elif filePath.split(".")[-1] in ["shp", "SHP", "gpkg", "geojson", "kml"]:
                self.addVectorLayer(filePath)
            elif filePath == "":
                pass
            else:
                QMessageBox.about(self, '警告', f'{filePath}为不支持的文件类型,目前支持栅格影像和shp矢量')

    def getRasterLayerAttrs(self, rasterLayer: QgsRasterLayer):
        print("name: ", rasterLayer.name())  # 图层名
        print("type: ", rasterLayer.type())  # 栅格还是矢量图层
        print("height - width: ", rasterLayer.height(), rasterLayer.width())  # 尺寸
        print("bands: ", rasterLayer.bandCount())  # 波段数
        print("extent", rasterLayer.extent())  # 外接矩形范围
        print("source", rasterLayer.source())  # 图层的源文件地址
        print("crs", rasterLayer.crs())  # 图层的坐标系统

    def getVectorLayerAttrs(self, vectorLayer: QgsVectorLayer):
        print("name: ", vectorLayer.name())  # 图层名
        print("type: ", vectorLayer.type())  # 栅格还是矢量图层
        print("extent", vectorLayer.extent())  # 外接矩形范围
        print("source", vectorLayer.source())  # 图层的源文件地址
        print("crs", vectorLayer.crs())  # 图层的坐标系统

1.3 实现效果

标签:文件,功能,self,layer,栅格,PyQGIS,开发,图层,添加
From: https://blog.csdn.net/szy13323042191/article/details/142385584

相关文章

  • 高级QML 3D组件开发
    高级QML3D组件开发使用AI技术辅助生成QT界面美化视频课程QT性能优化视频课程QT原理与源码分析视频课程QTQMLC++扩展开发视频课程免费QT视频课程您可以看免费1000+个QT技术视频免费QT视频课程QT统计图和QT数据可视化视频免费看免费QT视频课程QT性能优化视频免费看免......
  • VSCode配置STM32HAL库开发环境
    1.开发工具下载下载STM32CubeMX:https://www.st.com.cn/zh/development-tools/stm32cubemx.html(可通过访客方式下载)安装时一直默认即可下载stm32固件库:在线下载方式(需要登陆):安装好STM32CubeMX后,在菜单栏【Help】->【ManageEmbeddedSoftwarePackages】里选择合适的固......
  • 3D游戏开发实战:QML与虚幻引擎
    3D游戏开发实战:QML与虚幻引擎使用AI技术辅助生成QT界面美化视频课程QT性能优化视频课程QT原理与源码分析视频课程QTQMLC++扩展开发视频课程免费QT视频课程您可以看免费1000+个QT技术视频免费QT视频课程QT统计图和QT数据可视化视频免费看免费QT视频课程QT性能优化视频......
  • 如何高效利用API进行电商开发:淘宝API接口详解
    淘宝(AlibabaGroup)提供了丰富的API接口供开发者使用,这些接口可以帮助开发者在淘宝平台上实现各种功能,如商品搜索、交易管理、订单处理等。对于电商开发者来说,高效利用淘宝API进行开发至关重要。以下是一些关键步骤和技巧,帮助你高效利用淘宝AP进行电商开发:了解淘宝开放平台注......
  • 软件开发的方法论:Supra模型
    Supra模型是一种用于软件开发的方法论,特别是在需求工程领域。它提供了一种系统化的方式来识别、分析和管理软件项目的需求。Supra模型强调在整个软件生命周期中持续地关注用户需求,并且通过迭代的方式逐步细化和完善这些需求。这个名字“Supra”并不是一个广泛认可的标准术语,因此可......
  • 《老挝语翻译通》app新功能来了!支持语音识别翻译,无需打字对着说话就能翻译!
    在这个全球化的时代,掌握一门新语言变得越来越重要。如果你要去老挝旅行或者工作,那么老挝语翻译通App就是你的最佳选择。简单易用,功能强大这款App专为需要在老挝语和汉语之间进行翻译的人设计。它不仅翻译准确,而且操作起来非常简单,界面也很清晰。无论你需要翻译什么,这个App都......
  • [2025]基于微信小程序停车场预约计费系统(基于微信小程序的智能停车场预约与计费系统、
    博主介绍:  ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W+粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台的优质作者。通过长期分享和实战指导,我致力于帮助更多学生......
  • 中移ML307开发板板载蓝牙使用教程-板载蓝牙基本介绍
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ML307_OPEN_BLE"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 说明开发板板载了一颗沁恒的CH......
  • 完善lazarus中文代码补全功能
    当lazarus使用中文变量等代码补全时列表没对应的中文变量的: 解决方法:打开相应文件,添加红字代码,修改后重新编译lazarus就可以。1、\lazarus\ide\wordcompletion.pp找到procedureInitCharTable;(lazarus3.4在63行)procedureInitCharTable;varc:char;beginforc:=low(ch......
  • 【Linux 】开发利器:深度探索 Vim 编辑器的无限可能
    ......