当前位置: 首页 > backend >正文

【QGIS二次开发】地图编辑-08

  系列目录:

【QGIS二次开发】地图显示与交互-01_qgis二次开发加载地图案例-CSDN博客

【QGIS二次开发】地图显示与交互-02_setlayerlabeling-CSDN博客

【QGIS二次开发】地图符号与色表-03-CSDN博客

【QGIS二次开发】地图编辑-04-CSDN博客

【QGIS二次开发】地图编辑-05-CSDN博客

【QGIS二次开发】地图编辑-06-CSDN博客

【QGIS二次开发】地图编辑-07-CSDN博客


4.17 格式刷

先将数据添加到界面上面,再点击需要作为母版的数据,再点击格式刷工具

图 74 格式刷按键

点击后,跳出的窗口会展示所有和母版矢量数据类型相同的数据,例如此处会出现所有面类型的数据,而不会出现其他类型的。勾选后点击“OK”,所有勾选的数据都会被刷上模板数据的样式。

图 75 格式刷选择图层

结果如下。

图 76 格式刷效果

相关代码分析

DataViewer::on_actiongeshishua_triggered 函数用于响应用户触发的操作,比如菜单项点击。首先,它获取当前活动的图层,并显示一个 LayerSelectionDialog 对话框,以便用户选择要应用样式的目标图层。如果用户在对话框中选择了图层且当前图层存在,则函数获取当前图层的样式。接着,为每个选定的目标图层创建一个唯一的样式名称,并将当前图层的样式应用到这些目标图层上。

LayerSelectionDialog 类是一个继承自 QDialog 的自定义对话框类,用于显示和选择图层。构造函数接受一个当前图层(可选),并调用 setupUi 方法构建对话框界面。setupUi 方法设置对话框的标题,初始化列表部件(用于显示图层列表),并添加确定和取消按钮。如果提供了当前图层且它是矢量图层,代码会遍历项目中所有图层,并将与当前图层具有相同几何类型的矢量图层添加到列表中供用户选择。selectedLayers 方法返回用户在对话框中选中的图层列表。

代码部分如下

class LayerSelectionDialog : public QDialog {    Q_OBJECT    public:    LayerSelectionDialog(QWidget* parent = nullptr)    : QDialog(parent) {    setupUi();    }    LayerSelectionDialog(QWidget* parent = nullptr, QgsMapLayer* L=nullptr)    : QDialog(parent) {    m_currentLayer = L;    setupUi();    }    QList<QgsMapLayer*> selectedLayers() const {    QList<QgsMapLayer*> layers;    for (int i = 0; i < m_listWidget->count(); ++i) {    QListWidgetItem* item = m_listWidget->item(i);    if (item->checkState() == Qt::Checked) {    QgsMapLayer* layer = item->data(Qt::UserRole).value<QgsMapLayer*>();    layers.append(layer);    }    }    return layers;    }    private:    QgsMapLayer* m_currentLayer;    QListWidget* m_listWidget;    void setupUi() {    setWindowTitle("选择图层");    m_listWidget = new QListWidget(this);    // 检查当前图层是否为空    if (m_currentLayer && m_currentLayer->type() == QgsMapLayerType::VectorLayer) {    QgsVectorLayer* veclayer = qobject_cast<QgsVectorLayer*>(m_currentLayer);    if (veclayer) {  // 确保转换成功    const auto layers = QgsProject::instance()->mapLayers().values();    for (QgsMapLayer* layer : layers) {    if (layer->type() == QgsMapLayerType::VectorLayer) {    QgsVectorLayer* eveveclayer = qobject_cast<QgsVectorLayer*>(layer);    if (eveveclayer && eveveclayer->geometryType() == veclayer->geometryType()) {    QListWidgetItem* item = new QListWidgetItem(eveveclayer->name(), m_listWidget);    item->setFlags(item->flags() | Qt::ItemIsUserCheckable);    item->setCheckState(Qt::Unchecked);    item->setData(Qt::UserRole, QVariant::fromValue(eveveclayer));    }    }    }    }    }    QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);    connect(buttonBox, &QDialogButtonBox::accepted, this, &LayerSelectionDialog::accept);    connect(buttonBox, &QDialogButtonBox::rejected, this, &LayerSelectionDialog::reject);    QVBoxLayout* layout = new QVBoxLayout(this);    layout->addWidget(m_listWidget);    layout->addWidget(buttonBox);    resize(400, 300); // 设定对话框的初始大小    }    };    void DataViewer::on_actiongeshishua_triggered()    
{    // 显示图层选择对话框    currentLayer = m_layerTreeView->currentLayer();    LayerSelectionDialog dialog(this, currentLayer);    if (dialog.exec() == QDialog::Accepted) {    // 获取用户选择的目标图层列表    QList<QgsMapLayer*> targetLayers = dialog.selectedLayers();    if (!targetLayers.isEmpty() && currentLayer) {    // 获取当前图层的样式名称和数据    QString currentStyleName = currentLayer->styleManager()->currentStyle();    QgsMapLayerStyle currentStyle = currentLayer->styleManager()->style(currentStyleName);    // 生成唯一的样式名称    QString uniqueStyleName = "tempStyle_" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");    // 应用样式到每个选中的目标图层    for (QgsMapLayer* targetLayer : targetLayers) {    targetLayer->styleManager()->addStyle(uniqueStyleName, currentStyle);    targetLayer->styleManager()->setCurrentStyle(uniqueStyleName);    }    }    }    
}    

4.18 线缓冲区

       选中面弧段转后的结果作为演示数据,点击工具栏中的生成缓冲区工具,弹出输入缓冲区半径的对话框,单位根据图层的投影实时显示,用户输入半径后点击确定,操作过程如下图所示:

图 77 输入缓冲区半径

       生成的缓冲区如下图所示:

图 78 生成缓冲区

       生成缓冲区功能实现的主要代码如下,通过在按钮点击事件中获取用户在界面上输入的缓冲区长度,并通过迭代遍历选中的要素,在内存中创建一个新的矢量图层bufferLayer。对于每个选中的要素,获取其几何体并利用指定的缓冲区长度和圆弧段数进行缓冲区生成。然后,创建一个新的要素bufferFeature,将生成的缓冲区几何体设置为其几何体,并通过数据提供者将新要素添加到bufferLayer中。最后,将bufferLayer添加到当前QGIS项目中,并刷新地图视图以显示新添加的缓冲区图层。最后,窗口被关闭。

void QgsMapToolGenerateBuffer::on_pushButton_clicked() {    QString bufferle = ui.lineEdit->text();    if (!bufferle.isEmpty()) {    bufferlength = bufferle.toDouble();    QgsVectorLayer* bufferLayer = new QgsVectorLayer("Polygon?crs=epsg:4326", "Buffer", "memory");    bufferLayer->startEditing();    QgsFeatureIterator selectedFeatureIt = m_currentlayer->getSelectedFeatures();    QgsFeature selectedFeature;    while (selectedFeatureIt.nextFeature(selectedFeature)) {    // 获取要素的几何体    QgsGeometry geom = selectedFeature.geometry();    // 生成缓冲区,假设我们想要的缓冲区半径是bufferlength,圆弧段数是8    QgsGeometry buffer = geom.buffer(bufferlength, 8);    // 创建一个新的要素    QgsFeature bufferFeature;    bufferFeature.setGeometry(buffer);    // 将新的要素添加到数据提供者    bufferLayer->dataProvider()->addFeature(bufferFeature);    }    //bufferLayer->commitChanges();    QgsProject::instance()->addMapLayer(bufferLayer);    m_mapCanvas->refresh();    m_mapCanvas->refreshAllLayers();    }    window->close();    
}    

http://www.xdnf.cn/news/7027.html

相关文章:

  • tauri2项目使用sidcar嵌入可执行文件并使用命令行调用
  • 实战设计模式之状态模式
  • 互联网大厂Java面试场景:从Spring Boot到分布式缓存技术的探讨
  • 十一、STM32入门学习之FREERTOS移植
  • React 19 中的useRef得到了进一步加强。
  • ngx_http_proxy_protocol_vendor_module 模块
  • 【Linux】进程的基本概念
  • 虚幻引擎5-Unreal Engine笔记之Pawn与胶囊体的关系
  • 【android bluetooth 协议分析 01】【HCI 层介绍 5】【SetEventMask命令介绍】
  • Elasticsearch 初步认识
  • 用 UniApp 构建习惯打卡 App —— HabitLoop 开发记
  • 【cursor】有效解决
  • Denoising Score Matching with Langevin Dynamics
  • 【HarmonyOS 5开发入门】DevEco Studio安装配置完全指南
  • Flink 的窗口机制
  • 【ant design】ant-design-vue 4.0实现主题色切换
  • 【软考 McCabe度量法】
  • 深入理解指针(6)
  • 基因编辑根治胰腺癌-陈墨仙
  • Raft 协议:分布式一致性算法的核心思想
  • 欢乐熊大话蓝牙知识4:GATT 协议全解:蓝牙传数据到底怎么传?
  • 费马小定理
  • 数学复习笔记 16
  • 【Linux网络编程】Socket编程:协议理论入门
  • 数据库的规范化设计方法---3种范式
  • AIStarter Windows 版本迎来重磅更新!模型插件工作流上线,支持 Ollama / ComfyUI 等多平台本地部署模型统一管理
  • FPC连接器的未来趋势:柔性时代的核心桥梁
  • 【Redis】Hash 哈希
  • opencv4.11生成ArUco标记 ArUco Marker
  • IP68防水Type-C连接器实测:水下1米浸泡72小时的生存挑战