7. 矢量图层数据查询选择和保存

前言

为了获取地理空间数据的详细信息及统计结果,需要使用数据选择、筛选、查询与统计等方法。
数据查询可以获得矢量数据与栅格数据的属性信息;
数据选择(仅针对矢量图层)是指通过空间位置、属性信息等特征选取的部分地理要素,被选择的地理要素可以进一步被其他的编辑工具或分析工具处理;
数据筛选是指通过表达式等方式仅加载矢量数据中的部分要素,以便进一步制图或处理;
数据统计可以针对这些属性信息进行统计操作。

数据查询

QGis

  • 以myplaces.shp为例,添加图层后,右键菜单选择Open Attribute Table, 如下图
    在这里插入图片描述
  • 可以看到一个二维表格,显示矢量图层的数据,如下图
    在这里插入图片描述
  • 其数据存储和关系型数据库相同
  • 表头NAME、PLACE、ADDR_CITY等等相当于数据库中的字段,在QGis中以QgsField类表示
  • 每一行是一个Feature,feature除表中的数据外还有空间属性,在QGis中以QgsFeature类表示
  • 每一行的每一列是一个具体的数据,在QGis中以QgsAttributes类表示
  • 可以从表格中筛选数据,点击下图所示按钮
    在这里插入图片描述
  • 输入表达式,如下图
    在这里插入图片描述
  • 选择Filter Current Selection后,点击按钮后,效果如下图所示
    在这里插入图片描述
    在这里插入图片描述

代码实现

获取图层数据的字段QgsField

  • QgsField代表字段,详情见文档
  • QgsVectorLayer中的函数QgsFields fields()用于获取字段
void MainWindow::getFieldsSlot()
{
    //添加测试图层
    QString filename = QStringLiteral("maps/shapefile/myplaces.shp");
    QFileInfo ff(filename);
    QgsVectorLayer* layer = (QgsVectorLayer*)mApp->addVectorLayer(filename,ff.baseName());
    zoomToFirstLayer<QgsVectorLayer*>();

    mVectorDataDockWidget->show();
    mVectorDataDockWidget->plainTextEdit()->clear();
    for(auto field : layer->fields())
    {
        mVectorDataDockWidget->plainTextEdit()->appendPlainText(QString("%1:%2").arg(field.name()).arg(field.typeName()));
    }
}

在这里插入图片描述
在这里插入图片描述

获取图层数据QgsFeature以及QgsAttribute

  • QgsFeature代表图层中一个特征,该特征包含一个featureId,空间特征(点、线、面以及其坐标)和字段/值属性列表。详情见文档
  • QgsAttributes是feature的字段/值属性,详情见文档
  • QgsVectorLayer的函数QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() )用户获取features,其参数QgsFeatureRequest用于过滤数据,默认参数会获取所有feature
  • QgsFeature的函数attributes()用于获取feature的属性
  • 首先演示获取所有feature,代码如下
void MainWindow::getFeaturesSlot()
{
    //添加测试图层
    QString filename = QStringLiteral("maps/shapefile/myplaces.shp");
    QFileInfo ff(filename);
    QgsVectorLayer* layer = (QgsVectorLayer*)mApp->addVectorLayer(filename,ff.baseName());
    zoomToFirstLayer<QgsVectorLayer*>();

    mVectorDataDockWidget->show();
    mVectorDataDockWidget->plainTextEdit()->clear();

    QgsFeatureIterator it = layer->getFeatures();
    QgsFeature f;
    while(it.nextFeature(f))
    {
        QString str;
        str.append(QString("%1").arg(f.id()));
        str.append(" ");
        QgsAttributes attrs = f.attributes();
        for(int i = 0;i < attrs.size();++i)
        {
            str.append(attrs[i].toString());
            str.append(" ");
        }
        mVectorDataDockWidget->plainTextEdit()->appendPlainText(str);
    }
}

在这里插入图片描述
在这里插入图片描述

  • 筛选数据的代码如下,将字段RAINFALL的值大于200.0的保留
    QString str = QString("\"RAINFALL\" > 200.0");
    auto request = QgsFeatureRequest().setFilterExpression(str);
    QgsFeatureIterator it = layer->getFeatures(request);
  • 完整测试代码如下
void MainWindow::getFeaturesSlot()
{
    //添加测试图层
    QString filename = QStringLiteral("maps/shapefile/myplaces.shp");
    QFileInfo ff(filename);
    QgsVectorLayer* layer = (QgsVectorLayer*)mApp->addVectorLayer(filename,ff.baseName());
    zoomToFirstLayer<QgsVectorLayer*>();

    mVectorDataDockWidget->show();
    mVectorDataDockWidget->plainTextEdit()->clear();

    //带feature的expression
    QString str = QString("\"RAINFALL\" > 200.0");
    auto request = QgsFeatureRequest().setFilterExpression(str);
    QgsFeatureIterator it = layer->getFeatures(request);
    QgsFeature f;
    while(it.nextFeature(f))
    {
        QString str;
        str.append(QString("%1").arg(f.id()));
        str.append(" ");
        QgsAttributes attrs = f.attributes();
        for(int i = 0;i < attrs.size();++i)
        {
            str.append(attrs[i].toString());
            str.append(" ");
        }
        mVectorDataDockWidget->plainTextEdit()->appendPlainText(str);
    }
}

在这里插入图片描述

数据选择

QGis

  • 在“Attributes Toolbar”工具栏中,单击按钮右侧的下拉按钮,弹出的菜单中展示了交互式选择的四种方式,如下图所示
    在这里插入图片描述
  • 选择要素之后,颜色变为黄色,如下图
    在这里插入图片描述
  • 在默认情况下,选择的要素以黄色的点、线或黄色面填充符号突出显示在地图画布上。在QGIS的“Options”对话框的“Canvas & Legend”选项卡中,通过“Selection color”选项即可更改选择要素的颜色
    在这里插入图片描述

代码实现

  • QgsVectorLayer的一组选择函数实现了多种选择方式,代码如下
void select( QgsFeatureId featureId );
void select( const QgsFeatureIds &featureIds );
void selectAll();
void selectByRect( QgsRectangle &rect, Qgis::SelectBehavior behavior = Qgis::SelectBehavior::SetSelection );
void selectByExpression( const QString &expression, Qgis::SelectBehavior behavior = Qgis::SelectBehavior::SetSelection, QgsExpressionContext *context = nullptr );
void selectByIds( const QgsFeatureIds &ids, Qgis::SelectBehavior behavior = Qgis::SelectBehavior::SetSelection );
void deselect( QgsFeatureId featureId );
void deselect( const QgsFeatureIds &featureIds );
void removeSelection();
void reselect();
void modifySelection( const QgsFeatureIds &selectIds, const QgsFeatureIds &deselectIds );

  • 完整测试代码如下
void MainWindow::selectFeaturesSlot()
{
    //添加测试图层
    QString filename = QStringLiteral("maps/shapefile/myplaces.shp");
    QFileInfo ff(filename);
    QgsVectorLayer* layer = (QgsVectorLayer*)mApp->addVectorLayer(filename,ff.baseName());
    zoomToFirstLayer<QgsVectorLayer*>();

    QString expression = QString("\"RAINFALL\" > 200.0");
    //选择所有
    //    layer->selectAll();
    //按照id选择
    //    QgsFeatureId id = 0;
    //    layer->select(id);
    //按照多个id选择
    //    QgsFeatureIds ids;
    //    ids << 0 << 1 << 2 << 3;
    //    layer->select(ids);
    //按照表达式选择
    //    layer->selectByExpression(expression);
    //按照区域选择,并且使用rubberband显示区域
    QgsRectangle rect(1006585,6222254,1010253,6219118);
    layer->selectByRect(rect);
    QgsPointXY point1(1006585,6222254);
    QgsPointXY point2(1010253,6222254);
    QgsPointXY point3(1006585,6219118);
    QgsPointXY point4(1010253,6219118);
    QgsRubberBand *rubberBand = new QgsRubberBand(mApp->mapCanvas(),QgsWkbTypes::PolygonGeometry);
    rubberBand->addPoint(point1);
    rubberBand->addPoint(point2);
    rubberBand->addPoint(point4);
    rubberBand->addPoint(point3);
    rubberBand->show();
    //选择feature并且闪烁
    //    QgsMapCanvasUtils::flashMatchingFeatures(mApp->mapCanvas(),layer,expression);
    //选择Feature并zoom
    //    QgsMapCanvasUtils::zoomToMatchingFeatures(mApp->mapCanvas(),layer,expression);
}

在这里插入图片描述
在这里插入图片描述

创建虚拟图层并保存为shape文件

虚拟图层是在不改变矢量数据源的情况下,改变某些空间或属性信息,或者组合多个矢量图层,并以虚拟图层的方式展现数据。虚拟图层并不直接指向数据源,而是通过SQL查询语句等引用一个或多个矢量图层。

QGis

  • 此处介绍如何通过虚拟图层将“2017.xlsx”文件连接到吉林省地级行政区划文件(jilin_dist.shp)
  • 分别加载这两个图层
    在这里插入图片描述
  • 打开图层jilin_dist的Attribute Table,如下图
    在这里插入图片描述
  • 打开图层2017–Sheet1的Attribute Table,如下图
    在这里插入图片描述
  • 添加一个虚拟图层,将上述两个图层的数据连接到一起
    在这里插入图片描述
  • 在“Layer name”文本框中输入新生成的虚拟图层的名称;在“Embedded layers”组合框中单击“Import”按钮,将上述两个图层加入列表中,并在“Local name”选项中设置图层名称,同时将其作为SQL查询语句的表名称。单击“Add”按钮可以输入图层位置;单击“Remove”按钮可以删除图层。在“Query”文本框中输入以下查询语句:
SELECT * FROM jilin_dist left outer join prec on jilin_dist.NAME = prec.city;
  • 该语句可以通过jilin_dist图层的“NAME”字段和prec图层的“city”字段将prec图层的属性连接到jilin_dist图层中。
  • 单击“Add”按钮即可在图层列表中看到该虚拟图层。打开virtual_layer图层的Attribute Table可以看到连接后的数据表,如下图
    在这里插入图片描述

代码实现

  • QgsVirtualLayerDefinition定义虚拟图层连接信息,详情见文档
  • 其成员函数void addSource( const QString &name, const QString &source, const QString &provider, const QString &encoding = "" );用于添加添加图层。代码如下
    //QgsVirtualLayerDefinition
    QgsVirtualLayerDefinition def;
    //add embedded layers
    def.addSource("prec","maps/virtuallayer/2017.xlsx|layername=Sheet1","ogr");
    def.addSource("jilin_dist","maps/virtuallayer/jilin_dist.shp","ogr");

  • 成员函数void setQuery( const QString &query )用于设置查询语句
    //查询语句
    def.setQuery("SELECT * FROM jilin_dist left outer join prec on jilin_dist.NAME = prec.city;");
  • 新建矢量图层QgsVectorLayer,数据源provider传入virtual,代码如下
const QgsVectorLayer::LayerOptions options { QgsProject::instance()->transformContext() };
QgsVectorLayer *vl = new QgsVectorLayer( def.toString(), QStringLiteral( "test" ), QStringLiteral( "virtual" ), options );
  • QgsVectorFileWriter用于将图层保存至文件,详情见文档
  • 其成员函数writeAsVectorFormatV3用于保存,虚拟图层保存至文件的代码如下
        QgsVectorFileWriter::SaveVectorOptions opt;
        QgsVectorFileWriter::writeAsVectorFormatV3(vl,"maps/virtuallayer/myvurtual.shp",QgsProject::instance()->transformContext(),opt);

在这里插入图片描述
在这里插入图片描述

  • 保存的图层文件如下
    在这里插入图片描述

总结

  • 分别演示了:
    • QGis软件矢量图层数据的查询、选择和保存
    • 二次开发c++ api的图层数据的查询、选择和保存
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷动软件工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值