添加一个新的字段到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矢量图层中添加新的字段的更多相关文章

  1. Qt+QGis二次开发:创建临时图层并添加要素

    开发环境:Win10 + VS2010 + Qt 4.8.6 + QGis 2.14.4 其实本文实现的功能类似于QGis中“添加文本数据图层”的一个简化版,本文不会涉及到对话框的使用,不通过与用户互 ...

  2. Qt+QGIS二次开发:自定义类实现查询矢量数据的属性字段值(图查属性)

    在GIS领域,有两种重要的查询操作,图查属性和属性查图. 本文主要介绍如何在QGIS中通过从QgsMapToolIdentify中派生自定义类实现查询矢量数据的属性字段值(图查属性). 重点参考资料: ...

  3. Qt+QGIS二次开发:读取矢量元素及其属性

    1  概述矢量图层内矢量元素组成,矢量图层的加载由驱动实现,驱动必须实现对矢量图层内元素的读写操作功能. 2 原理矢量元素包含几何和属性两部分组成.几何部分用于提供图形相关内容.属性部分提供与几何相关 ...

  4. Qt Qgis 二次开发——鼠标点击识别矢量要素

    Qt Qgis 二次开发--鼠标点击识别矢量要素 介绍: 识别矢量要素需要用到QGis的一个工具类:QgsMapToolIdentifyFeature 一个QgsMapTool的子类的子类,官方文档描 ...

  5. Qt+QGis二次开发:加载栅格图层和矢量图层

    一.加载栅格图像 加载栅格图像的详细步骤在下面代码里: //添加栅格数据按钮槽函数 void MainWindow::addRasterlayers() { //步骤1:打开文件选择对话框 QStri ...

  6. Qt+QGis二次开发:矢量图层的显示样式

    原文链接:QGis二次开发基础 -- 矢量图层的显示样式

  7. Qt+QGIS二次开发:开发环境搭建(超级详细)

    原文链接: 1.qgis二次开发环境搭建(超级详细) 2.QGIS开发教程(1)——QGIS开发准备工作 3.QGIS(2.18.15 源码)+Qt(5/5.9.3)+VS2015(X64)编译

  8. Qt+QGis二次开发:打开S-57格式(*.000)电子海图数据,并设置多边形要素的显示风格

    不过多的废话了,直接上源码: addChartlayers()方法时“打开海图”按钮的triggered()信号所绑定的槽函数. //添加海图数据小按钮槽函数 void MainWindow::add ...

  9. Qt+QGIS二次开发:QGIS中使用QgsRubberBand类创建临时图形

    1  概述 临时图形Rubberband主要用于高亮显示.交互绘制等情况下.2 原理 临时图形是在一个底色透明的图层(顶层)上,添加已有的几何元素或者创建一个几何元素(临时图形),可以设置相应的样式, ...

随机推荐

  1. 【Java深入研究】6、CGLib动态代理机制详解

    一.首先说一下JDK中的动态代理: JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的 但是,JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该 ...

  2. 8.并发容器ConcurrentHashMap#put方法解析

    jdk1.7.0_79 HashMap可以说是每个Java程序员用的最多的数据结构之一了,无处不见它的身影.关于HashMap,通常也能说出它不是线程安全的.这篇文章要提到的是在多线程并发环境下的Ha ...

  3. 站在DevOps肩膀上的TestOps(二)

    一十一 发表于 2018-03-14 16:40:22 TestOps   摘要: TestOps模型旨在将整个团队的注意力集中在质量上,因此TestOps确实需要无缝且可靠. 一个简单的例子是任何测 ...

  4. Go开发之路 -- Go语言基本语法 - 作业

    1. 判断101 - 200之间有多少个素数,并输出所有素数. package main import ( "fmt" ) var count = 0 func prime(a, ...

  5. 在线客服兼容谷歌Chrome、苹果Safari、Opera浏览器的修改

    纵览全网提供的众多号称兼容多浏览器的自动收缩在线客服,其实只兼容了IE和FF两种,当遇到谷歌Chrome.苹果Safari.Opera浏览器时鼠标还没点到客服按钮就会自动缩回,实用效果完全打折 以下代 ...

  6. 警告!中国90%AI初创企业将在两年内落败出局

    https://mp.weixin.qq.com/s/-RkyLda1jovaHBlBTsi-BA 近年来,中国涌现了一大批AI初创企业,但AI热潮也伴随着泡沫.由于近期市场资金紧缩,投资者发出警告, ...

  7. 接口自动化 基于python+Testlink+Jenkins实现的接口自动化测试框架[V2.0改进版]

    基于python+Testlink+Jenkins实现的接口自动化测试框架[V2.0改进版]   by:授客 QQ:1033553122 由于篇幅问题,,暂且采用网盘分享的形式: 下载地址: [授客] ...

  8. 安卓界面之Viewpager和Tablayout实现滑动界面

    摘要:六部实现选项卡界面 一. 在gradle文件添加以下代码: implementation 'com.android.support:design:28.0.0' 在gradle文件添加以上代码后 ...

  9. Linux Mint Mate 常用

    Linux Mint基于Ubuntu  Mate 桌面版据说资源占用较少 http://mirrors.tuna.tsinghua.edu.cn/linuxmint-cd/stable/17.3/li ...

  10. 基于VMware Workstation在Windows Server 2008 R2上搭建SQL Server 2012高可用性组(AlwaysOn Group)测试环境(二)

    接上篇: 以SERVER02为例,将服务器加入域,并安装故障转移群集:(SERVER02-SERVER-04操作相同)