You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手求教:用C++开发QGIS插件(读取点坐标并显示)的完整步骤

用C++开发QGIS插件:读取点坐标并显示的完整步骤

1. 准备开发环境

  • 安装带开发组件的QGIS:Windows选「QGIS Desktop with Developer Tools」,Linux安装libqgis-dev类包,macOS通过官方安装包或Homebrew勾选开发组件
  • 配置C++开发环境:安装MSVC/GCC/Clang编译器,以及CMake构建工具
  • 环境变量配置:确保编译器能识别QGIS的头文件和库文件路径,Windows可手动设置QGIS_INCLUDE_DIR、QGIS_LIB_DIR,Linux/macOS安装dev包后一般自动识别

2. 创建插件项目框架

新建项目文件夹(如PointLoaderPlugin),在其中创建CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(PointLoaderPlugin)

# 查找依赖
find_package(QGIS REQUIRED COMPONENTS core gui)
find_package(Qt5 REQUIRED COMPONENTS Widgets)

# 定义插件库
add_library(${PROJECT_NAME} SHARED
    pointloaderplugin.h
    pointloaderplugin.cpp
    pointloaderdialog.h
    pointloaderdialog.cpp
    ui_pointloaderdialog.h
)

# 链接依赖库
target_link_libraries(${PROJECT_NAME}
    PRIVATE
    QGIS::core
    QGIS::gui
    Qt5::Widgets
)

# 安装到QGIS插件目录
install(TARGETS ${PROJECT_NAME}
    DESTINATION ${QGIS_PLUGIN_DIR}
)

3. 实现插件核心代码

3.1 插件主类(菜单/工具栏入口)

创建pointloaderplugin.h:

#ifndef POINTLOADERPLUGIN_H
#define POINTLOADERPLUGIN_H

#include <QObject>
#include <qgisplugin.h>
#include <QAction>

class PointLoaderDialog;

class PointLoaderPlugin : public QObject, public QgisPlugin
{
    Q_OBJECT
    Q_INTERFACES(QgisPlugin)

public:
    explicit PointLoaderPlugin(QgisInterface* iface);
    ~PointLoaderPlugin() override;

    void initGui() override;
    void unload() override;

private slots:
    void showLoadDialog();

private:
    QgisInterface* mIface;
    QAction* mLoadAction;
    PointLoaderDialog* mDialog;
};

#endif // POINTLOADERPLUGIN_H

创建pointloaderplugin.cpp:

#include "pointloaderplugin.h"
#include "pointloaderdialog.h"

PointLoaderPlugin::PointLoaderPlugin(QgisInterface* iface)
    : mIface(iface), mLoadAction(nullptr), mDialog(nullptr) {}

PointLoaderPlugin::~PointLoaderPlugin() {
    unload();
}

void PointLoaderPlugin::initGui() {
    // 创建工具栏按钮和菜单
    mLoadAction = new QAction(QIcon(":/icons/point_icon.png"), "加载点坐标", this);
    connect(mLoadAction, &QAction::triggered, this, &PointLoaderPlugin::showLoadDialog);
    
    mIface->addToolBarIcon(mLoadAction);
    mIface->addPluginToMenu("&点加载工具", mLoadAction);
}

void PointLoaderPlugin::unload() {
    // 清理资源
    mIface->removePluginMenu("&点加载工具", mLoadAction);
    mIface->removeToolBarIcon(mLoadAction);
    delete mLoadAction;
    
    if (mDialog) {
        delete mDialog;
        mDialog = nullptr;
    }
}

void PointLoaderPlugin::showLoadDialog() {
    if (!mDialog) {
        mDialog = new PointLoaderDialog(mIface);
    }
    mDialog->show();
}

3.2 文件选择与点加载对话框

用Qt Designer创建对话框(包含文件选择按钮、路径输入框、加载按钮),生成ui_pointloaderdialog.h。

创建pointloaderdialog.h:

#ifndef POINTLOADERDIALOG_H
#define POINTLOADERDIALOG_H

#include <QDialog>
#include <QgisInterface>

namespace Ui {
class PointLoaderDialog;
}

class PointLoaderDialog : public QDialog
{
    Q_OBJECT

public:
    explicit PointLoaderDialog(QgisInterface* iface, QWidget *parent = nullptr);
    ~PointLoaderDialog();

private slots:
    void on_selectFileBtn_clicked();
    void on_loadPointsBtn_clicked();

private:
    Ui::PointLoaderDialog *ui;
    QgisInterface* mIface;
    
    // 创建内存点图层
    QgsVectorLayer* createPointLayer();
    // 从文件读取坐标并添加到图层
    bool loadPoints(const QString& filePath, QgsVectorLayer* layer);
};

#endif // POINTLOADERDIALOG_H

创建pointloaderdialog.cpp:

#include "pointloaderdialog.h"
#include "ui_pointloaderdialog.h"
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QgsFeature>
#include <QgsGeometry>
#include <QgsPointXY>
#include <QgsProject>

PointLoaderDialog::PointLoaderDialog(QgisInterface* iface, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::PointLoaderDialog),
    mIface(iface)
{
    ui->setupUi(this);
}

PointLoaderDialog::~PointLoaderDialog() {
    delete ui;
}

void PointLoaderDialog::on_selectFileBtn_clicked() {
    QString filePath = QFileDialog::getOpenFileName(this, "选择坐标文件", "", "文本文件 (*.txt);;所有文件 (*.*)");
    if (!filePath.isEmpty()) {
        ui->filePathEdit->setText(filePath);
    }
}

QgsVectorLayer* PointLoaderDialog::createPointLayer() {
    // 创建WGS84坐标系的内存点图层
    QString layerName = "导入的点";
    QgsVectorLayer* layer = new QgsVectorLayer("Point?crs=EPSG:4326", layerName, "memory");
    return layer->isValid() ? layer : nullptr;
}

bool PointLoaderDialog::loadPoints(const QString& filePath, QgsVectorLayer* layer) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::warning(this, "错误", "无法打开文件");
        return false;
    }

    QTextStream in(&file);
    QgsFeature feature(layer->fields());
    QList<QgsFeature> featureList;

    while (!in.atEnd()) {
        QString line = in.readLine().trimmed();
        if (line.isEmpty()) continue;
        
        // 解析逗号分隔的经纬度(格式:经度,纬度)
        QStringList coords = line.split(",");
        if (coords.size() != 2) continue;
        
        bool lonOk, latOk;
        double lon = coords[0].toDouble(&lonOk);
        double lat = coords[1].toDouble(&latOk);
        if (!lonOk || !latOk) continue;
        
        feature.setGeometry(QgsGeometry::fromPointXY(QgsPointXY(lon, lat)));
        featureList.append(feature);
    }

    // 添加要素到图层
    if (!layer->dataProvider()->addFeatures(featureList)) {
        QMessageBox::warning(this, "错误", "添加点失败");
        return false;
    }

    layer->updateExtents();
    file.close();
    return true;
}

void PointLoaderDialog::on_loadPointsBtn_clicked() {
    QString filePath = ui->filePathEdit->text();
    if (filePath.isEmpty()) {
        QMessageBox::warning(this, "提示", "请先选择坐标文件");
        return;
    }

    QgsVectorLayer* layer = createPointLayer();
    if (!layer) {
        QMessageBox::warning(this, "错误", "创建图层失败");
        return;
    }

    if (loadPoints(filePath, layer)) {
        // 将图层添加到项目并刷新画布
        QgsProject::instance()->addMapLayer(layer);
        mIface->mapCanvas()->refresh();
        this->close();
    }
}

4. 编译与安装插件

  • 创建build目录,进入后执行编译命令:
    # Linux/macOS
    cmake .. -DCMAKE_BUILD_TYPE=Release
    make
    sudo make install
    
    # Windows(MSVC环境)
    cmake .. -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=Release
    cmake --build . --config Release --target INSTALL
    
  • 手动安装:将编译生成的库文件(.so/.dll/.dylib)复制到QGIS插件目录:
    • Linux: ~/.local/share/QGIS/QGIS3/profiles/default/plugins/
    • Windows: C:\Users\<用户名>\AppData\Roaming\QGIS\QGIS3\profiles\default\plugins\
    • macOS: ~/Library/Application Support/QGIS/QGIS3/profiles/default/plugins/

5. 测试插件

  • 启动QGIS,在「插件」菜单找到「点加载工具」并启用
  • 点击工具栏的「加载点坐标」按钮,选择符合格式的坐标文件(每行经度,纬度),加载后即可在画布看到点要素

关键注意事项

  • 坐标格式适配:如果文件是空格/制表符分隔或带表头,需修改loadPoints里的解析逻辑
  • 坐标系调整:若坐标使用其他坐标系,修改createPointLayer中的EPSG代码即可
  • 错误处理:示例代码添加了基础提示,实际开发可根据需求扩展异常处理逻辑

内容的提问来源于stack exchange,提问作者wangxin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:48:10