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


QgsField类表示QgsFeature类表示QgsAttributes类表示



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


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


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




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


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




SELECT * FROM jilin_dist left outer join prec on jilin_dist.NAME = prec.city;

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);


