zoukankan      html  css  js  c++  java
  • 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矢量图层添加新字段

  • 相关阅读:
    Web开发较好用的几个chrome插件
    SQL注入专题
    内存泄露检测之ccmalloc
    ruby method lambda block proc 联系与区别 next break return
    c++构造函数详解
    VIM使用系列之一—配置VIM下编程和代码阅读环境
    一个项目经理的经验总结
    如何改正拖拉的习惯
    PHP开源软件《个人管理系统》希望大家一起来开发
    PHP 开源软件《个人管理系统》——完善登录模块
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/10382226.html
Copyright © 2011-2022 走看看