Qt+QGIS二次开发:向shp矢量图层中添加新的字段

2023-06-07,,

添加一个新的字段到shp文件中,并且从Excel里导入数据到该字段。原shp文件里的字段ID应该与Excel里的字段ID一一对应才能正确的导入。下图分别是shp的字段和Excel的字段

将class字段添加到shp中去:

(1)从Excel中读取数据(为了读取方便,存为.csv或者txt文件)

QStringList readFromCSV(QString mfilename)
{
QStringList readlist;
if (mfilename !="")
{
QFileInfo csvFI(mfilename);
QString ext = csvFI.suffix();
if ( ext == "csv" || ext == "txt")
{
QFile *importFile = new QFile(mfilename);
if ( !importFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::information(NULL, "error", "Cannot open import file !", QMessageBox::Yes | QMessageBox::No);
return readlist;
}
readlist.clear();
QTextStream readIn(importFile);//读入文件
while ( !readIn.atEnd()) //读取每一行
{
readlist.push_back(readIn.readLine());
} importFile->close();
}
}
return readlist;
}

返回的readlist是所有行的数据,下面要根据Id来将每一行后面的class字段插入shp文件

(2)插入class字段及值到shp

首先要创建新字段名,然后再插入值

bool ImportLandInfo::insertInfo(QString mShpfile)
{ QgsVectorLayer * newLayer; newLayer = new QgsVectorLayer(mShpfile, fileinfo.baseName(), "ogr");
if ( newLayer != NULL)
{
qDebug("newLayer is valid");
}
else
{
return false;
}
QStringList readlist = readFromCSV(“F:\\data.csv”);//Excel文件 //创建新字段
QList<QgsField> newFieldList;
QStringList fields = readlist.at().split(",", QString::SkipEmptyParts); //得到Excel的字段名
for (int i = ; i < fields.count(); ++i)
{
QString fieldname;
if ( fields.at(i) == "Id" )
{
continue;
}
else
{
fieldname = fields.at(i);
}
QgsField shpField( fieldname, QVariant::String);
newFieldList.push_back( shpField ); }
QgsVectorDataProvider* vectorProvider = newLayer->dataProvider();
vectorProvider->addAttributes( newFieldList ); //新字段中插入值
QMap<int, int> idmap = generateIdIndex(); //由原shp图层得到QMap<ID, featureId>
int fieldIndex = -; //每个待插入字段的索引号
int IdIndex = -; // ID字段的索引号
for (int j = ; j < readlist.count(); ++j)
{
QString filed;
QgsChangedAttributesMap changeMap;
QgsAttributeMap changeAttributeMap; QStringList field = readlist.at( j ).split(",", QString::SkipEmptyParts);
for ( int k = ; k < field.count(); ++k)
{
if ( field.at(k) == "Id" )
{
IdIndex = k;
continue;
}
if ( j == ) //第一行时是计算字段在属性表中的index
{
fieldIndex = vectorProvider->fieldNameIndex( field.at(k) );
break;
}
else //不是第一行则插入
{
changeAttributeMap.insert( fieldIndex + k - , QVariant( field.at(k) ) );
}
}
if ( j == )
{
continue;
}
int ID = field.at(IdIndex).toInt(); QMap<int, int>::iterator i = idmap.find( ID); //找到指定ID对应的要素id(featureId)
int featureId = i.value();
changeMap.insert( featureId, changeAttributeMap );
vectorProvider->changeAttributeValues( changeMap );
}
delete vectorProvider;
return true;
}

generateIdIndex()是为了得到Id对应的FeatureID,因为属性字段Id和要素的FeatureID是不一致的。

QMap<int, int> ImportLandInfo::generateIdIndex()
{
QMap<int, int> idMap;
QgsVectorLayer * orignalLayer;
QFileInfo fileinfo(moriginalShpfile);
orignalLayer = new QgsVectorLayer(moriginalShpfile, fileinfo.baseName(), "ogr");
if ( orignalLayer != NULL)
{
qDebug("newLayer is valid");
}
QgsVectorDataProvider* vectorProvider = orignalLayer->dataProvider();
QgsFeature feature; int idIndex = vectorProvider->fieldNameIndex( "Id" );
int count = orignalLayer->featureCount();
for ( int i = ; i < count; ++i)
{
orignalLayer->featureAtId( i, feature);
const QgsAttributeMap &attributes = feature.attributeMap();
int id = -;
id = attributes[ idIndex].toInt();
idMap.insert( id, feature.id());
}
return idMap;
}

这样字段class的值就添加到shp中去了。结果如图:

参考链接:QGis(四)shp矢量图层添加新字段

Qt+QGIS二次开发:向shp矢量图层中添加新的字段的相关教程结束。

《Qt+QGIS二次开发:向shp矢量图层中添加新的字段.doc》

下载本文的Word格式文档,以方便收藏与打印。