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().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二次开发:创建临时图层并添加要素
开发环境:Win10 + VS2010 + Qt 4.8.6 + QGis 2.14.4 其实本文实现的功能类似于QGis中“添加文本数据图层”的一个简化版,本文不会涉及到对话框的使用,不通过与用户互 ...
- Qt+QGIS二次开发:自定义类实现查询矢量数据的属性字段值(图查属性)
在GIS领域,有两种重要的查询操作,图查属性和属性查图. 本文主要介绍如何在QGIS中通过从QgsMapToolIdentify中派生自定义类实现查询矢量数据的属性字段值(图查属性). 重点参考资料: ...
- Qt+QGIS二次开发:读取矢量元素及其属性
1 概述矢量图层内矢量元素组成,矢量图层的加载由驱动实现,驱动必须实现对矢量图层内元素的读写操作功能. 2 原理矢量元素包含几何和属性两部分组成.几何部分用于提供图形相关内容.属性部分提供与几何相关 ...
- Qt Qgis 二次开发——鼠标点击识别矢量要素
Qt Qgis 二次开发--鼠标点击识别矢量要素 介绍: 识别矢量要素需要用到QGis的一个工具类:QgsMapToolIdentifyFeature 一个QgsMapTool的子类的子类,官方文档描 ...
- Qt+QGis二次开发:加载栅格图层和矢量图层
一.加载栅格图像 加载栅格图像的详细步骤在下面代码里: //添加栅格数据按钮槽函数 void MainWindow::addRasterlayers() { //步骤1:打开文件选择对话框 QStri ...
- Qt+QGis二次开发:矢量图层的显示样式
原文链接:QGis二次开发基础 -- 矢量图层的显示样式
- Qt+QGIS二次开发:开发环境搭建(超级详细)
原文链接: 1.qgis二次开发环境搭建(超级详细) 2.QGIS开发教程(1)——QGIS开发准备工作 3.QGIS(2.18.15 源码)+Qt(5/5.9.3)+VS2015(X64)编译
- Qt+QGis二次开发:打开S-57格式(*.000)电子海图数据,并设置多边形要素的显示风格
不过多的废话了,直接上源码: addChartlayers()方法时“打开海图”按钮的triggered()信号所绑定的槽函数. //添加海图数据小按钮槽函数 void MainWindow::add ...
- Qt+QGIS二次开发:QGIS中使用QgsRubberBand类创建临时图形
1 概述 临时图形Rubberband主要用于高亮显示.交互绘制等情况下.2 原理 临时图形是在一个底色透明的图层(顶层)上,添加已有的几何元素或者创建一个几何元素(临时图形),可以设置相应的样式, ...
随机推荐
- mysql 主从模式总结(一)
1. 主从模式的部署步骤 目标:部署一个有3台主机的单主模式的MySQL分组. Primary:192.168.197.110. Secondary:192.168.197.111. Secondar ...
- 【Java并发编程】22、Exchanger源码解析(JDK1.7)
Exchanger是双向的数据传输,2个线程在一个同步点,交换数据.先到的线程会等待第二个线程执行exchangeSynchronousQueue,是2个线程之间单向的数据传输,一个put,一个tak ...
- React中props和state相同点和不同点
朋友们,我想死你们了,最近这几天忙着和病魔作斗争所以没怎么写博客,今天感觉好点了,赶紧来写一波,就是这木敬业. 今天我们来讨论讨论props和state相同点和不同点 首先我来概要说明一下这两者 pr ...
- python之锁, 队列
进程的其他方法 进程id,进程名字,查看进程是否活着is_alive() terminate()发送结束进程的信号 import time import os from multiprocessin ...
- 51Testing专访史亮:测试人员在国外
不久前,我接受了51Testing的访问,讨论了软件测试的一些问题.以下是全文. 1.史亮老师,作为我们51Testing的老朋友,能和我们说说您最近在忙些什么吗? 自2011年起,我加入Micros ...
- (后端)org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1,actual 0
两种方案: 用queryForList方法替换queryForObject或者queryForMap,因为这两个方法必须要有值,不能为空. 把这个异常捕获,用try/catch. 这个查询的结果是nu ...
- Info.plist的CFBundleIdentifier、CFBundleName、BundleDisplayName
plist关键字段: CFBundleIdentifier:应用包名.唯一标识 CFBundleVersion:文件版本号,可以每次发版本递增 CFBundleShortVersionString:a ...
- 洗礼灵魂,修炼python(34)--面向对象编程(4)—继承
前面已经说到面向对象编程有封装,继承,多态三大特性,那么其中的继承则很重要,可以直接单独的拿出来解析 继承 1.什么是继承: 字面意是子女继承父母的家产或者特性等.而在编程里继承是指子类继承父类(基类 ...
- webApi core2 DI通过代码来获取容器里面已注入的对象
请求服务 来自 HttpContext 的一次 ASP.NET 请求中可用的服务通过 RequestServices 集合公开的. 请求服务将你配置的服务和请求描述为应用程序的一部分.当你的对象指定依 ...
- android ninja【转】
Android7.0 Ninja编译原理 引言 使在Android N的系统上,初次使用了Ninja的编译系统.对于Ninja,最初的印象是用在了Chromium open source code的编 ...