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

添加一个新的字段到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(0).split(",", QString::SkipEmptyParts);  //得到Excel的字段名
    for (int i = 0; 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 = -1;  //每个待插入字段的索引号
    int IdIndex = -1;    // ID字段的索引号
    for (int j = 0; j < readlist.count(); ++j)
    {
        QString filed; 
        QgsChangedAttributesMap changeMap;
        QgsAttributeMap changeAttributeMap;
 
        QStringList field = readlist.at( j ).split(",", QString::SkipEmptyParts);
        for ( int k = 0; k < field.count(); ++k)
        {
            if (  field.at(k) == "Id" )
            {    
                IdIndex = k;
                continue;
            }            
            if ( j == 0)  //第一行时是计算字段在属性表中的index
            {    
                fieldIndex = vectorProvider->fieldNameIndex( field.at(k) );
                break;
            }
            else  //不是第一行则插入
            {
                changeAttributeMap.insert( fieldIndex + k - 1, QVariant( field.at(k) ) );
            }
        }
        if ( j == 0)
        {
            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 = 0; i < count; ++i)
    {
        orignalLayer->featureAtId( i, feature);
        const QgsAttributeMap &attributes = feature.attributeMap();
        int id = -1;
        id = attributes[ idIndex].toInt();
        idMap.insert( id, feature.id());
    }    
    return idMap;
}

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

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

posted @ 2019-02-15 10:39  rainbow70626  阅读(1517)  评论(1编辑  收藏  举报