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

【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();    
}    

相关文章:

  • React响应事件中onClick={handleClick} 的结尾有没有小括号的区别
  • React 19中如何向Vue那样自定义状态和方法暴露给父组件。
  • 使用vscode做python项目fastapi的开发
  • Vue环境下数据导出Excel的全面指南
  • MLLM常见概念通俗解析(一)
  • 电子电路:什么是电流离散性特征?
  • 日志参数含义
  • Ubuntu搭建TFTP服务器的方法
  • 优先级队列(堆)
  • JMeter 教程:使用 HTTP 请求的参数列表发送 POST 请求(form 表单格式)
  • 嵌入式硬件篇---拓展板
  • 简单使用Slidev和PPTist
  • 柔性PZT压电薄膜在线监测锂电池内部缺陷-应对薄膜电池安全挑战
  • Go 语言即时通讯系统开发日志-日志day2-5:架构设计与日志封装
  • 关于文件分片的介绍和应用
  • CSS- 4.3 绝对定位(position: absolute)学校官网导航栏实例
  • 【上位机——WPF】布局控件
  • Adapter适配器模式
  • 利用systemd启动部署在服务器上的web应用
  • Zookeeper入门(三)
  • 一周人物|收藏家瓦尔特捐出藏品,女性艺术家“对话”摄影
  • 国家统计局答澎湃:我国投资的潜力依然巨大,支撑投资增长的有利因素仍然比较多
  • 广西隆林突发山洪,致3人遇难1人失联
  • 全国游泳冠军赛:孙杨、潘展乐同进400自决赛,今晚将正面对决
  • 下辖各区密集“联手”,南京在下一盘什么样的棋?
  • 一个留美学生的思想转向——裘毓麐的《游美闻见录》及其他