开发环境:Win10 + VS2010 + Qt 4.8.6 + QGis 2.14.4

其实本文实现的功能类似于QGis中“添加文本数据图层”的一个简化版,本文不会涉及到对话框的使用,不通过与用户互交的方式创建要素,而是直接通过代码方式添加点要素,起到一个抛砖引玉的作用。

(一)先将整个流程大概梳理下:

1、首先创建一个临时(memory)矢量图层 ;

2、将创建的图层添加到地图画布中 ;

3、创建几何要素 ;

4、将几何要素添加到矢量图层中 ;

5、更新图层范围并刷新画布 .

(二)程序代码:

// 测试代码

/* "Point?crs=EPSG:4326&field=id:integer&
* field=name:string(50)&index=yes&
* memoryid={63152c31-9f38-4410-9983-fc9abe84973f}"
*/
QString layerProperties = "Point?"; // 几何类型
layerProperties.append(QString( "crs=EPSG:4326&" )); // 参照坐标系
layerProperties.append(QString( "field=id:integer&field=name:string(50)&" )); // 添加字段
layerProperties.append(QString( "index=yes&" )); // 创建索引
layerProperties.append(QString( // 临时编码
"memoryid=%1" ).arg( QUuid::createUuid().toString() )); QgsVectorLayer* newLayer = new QgsVectorLayer(
layerProperties, QString( "临时点层" ), QString( "memory" ) ); if (!newLayer->isValid())
{
return false;
} // 添加到地图
QgsMapLayerRegistry::instance()->addMapLayer(newLayer); QgsVectorDataProvider* dateProvider = newLayer->dataProvider(); // 创建点
QgsFeature MyFeature;
MyFeature.setGeometry( QgsGeometry::fromPoint(QgsPoint(102.4443, 32.2123)) );
MyFeature.setAttributes(QgsAttributes() << QVariant(1) << QVariant("test")); QgsFeature MyFeature1;
MyFeature1.setGeometry( QgsGeometry::fromPoint(QgsPoint(102.4643, 32.2133)) );
MyFeature1.setAttributes(QgsAttributes() << QVariant(2) << QVariant("test1")); // 开始编辑
newLayer->startEditing(); // 添加要素
dateProvider->addFeatures(QgsFeatureList() << MyFeature << MyFeature1); // 保存
newLayer->commitChanges(); // 更新范围
newLayer->updateExtents();
mMapCanvas->refresh();
return true;

(三)代码分析:

           创建临时图层  

第3-11行,这段代码可能是我与网上其他的教程中比较不一样的地方,这里通过构造一种URL形式的字符串,通过上面的注释大家应该都大概明白这个字符串的意思了,通过这种形式很简洁方便的使我们将要创建的图层具备了多个条件,特别是简化对于图层字段的添加:

第7行 QString layerProperties = "Point?" 定义了我们创建图层的几何类型,可以是"Point"、"LineString"、"Polygon"、"MultiPoint"、"MultiLineString"、"MultiPolygon"其中之一;

第8行 QString( "crs=EPSG:4326&" ) 是图层的参照坐标系,定义一个正确的坐标系是一个良好的习惯,如果需要一定灵活性可以参照QGis的方式通过对话框选取,或是根据自己的需求来实现,需要改变的仅仅是"EPSG:4326" 而已;

第8行 QString( "field=id:integer&field=name:string(50)&" ) 是定义的图层字段,这也是我觉得很方便的一个地方,多个字段用"&" 进行连接,完整形式为 field=name:type(length,precision) ,从参数看不仅可以定义长度还可以定义其精度;

第10行 QString( "index=yes&" ) 是定义空间索引,对于数据量较大的图层很有用;

第11行 QString( "memoryid=%1" ).arg( QUuid::createUuid().toString() ) 比较有趣,它通过QUuid创建了一个全局唯一标识符(UUID),Qt中解释主要是用于分布式计算环境中的实体标识,而此处是用于当我们多次创建临时图层时的唯一标识符;

第3-5行就是一个URL形式字符串的完整展示,包含上述的所有内容,最后{}中一串数字就是通过QUuid自动创建的标识。虽然我没有尝试过,但是应该除了几何类型必须要定义以外,其他的都是可选项,当然如果我们采用这种方式肯定不仅仅是定义一个图层的几何类型而已。

上面准备工作说了很多,第13行才真正创建临时图层:

QgsVectorLayer* newLayer = new QgsVectorLayer( layerProperties, QString( "临时点层" ), QString( "memory" ) );

QgsVectorLayer类有3个参数,第1个参数就是URL形式的字符串layerProperties,另外经常用的一种很简单的方式就是直接定义其图层的几何类型即可,如"Point";第2个参数是图层的名称;第3个参数是创建图层的类型,这里传入的"memory"代表创建的是一个临时图层。

  将图层添加到地图画布中  

第21、23行将才创建的图层添加到地图画布中,并且获得一个QgsVectorDataProvider指针,该指针在后面会用到。

  创建几何要素  

第25-32行创建了两个点要素来展示结果,网上的很多例子为了让大家更清楚,是分开写的,我这个比较省事:

MyFeature.setGeometry( QgsGeometry::fromPoint(QgsPoint(102.4443, 32.2123)) );

使用setGeometry()设置了要素的几何体后,就继续用setAttributes()写入属性,属性类型、顺序与上面我们创建的是一致的,setAttributes()的参数是QgsAttributes对象,而QgsAttributes其实就是QVector<QVariant>,所用我下面代码中是添加的QVariant对象。

MyFeature.setAttributes(QgsAttributes() << QVariant(1) << QVariant("test"));

通过上面的两行代码就成功创建了几何要素并设置了它的属性。

          添加几何要素到矢量图层中  

        第34-41行我们利用上面获得的QgsVectorDataProvider指针将几何要素添加到了矢量图层中,我们先使用startEditing()来使图层可编辑,然后使用commitChanges()来提交改变结果。

  刷新  

最后更新图层范围,并刷新画布就OK了。

在这里多说一句,如果你按照此方法运行后,在地图画布上不能正常显示,检查下画布是否没有解冻,就是:mapCanvas()->freeze( false ) ,我之前在这吃了亏,由于才接触QGis开发不久,我在程序的其他地方将画布冻结了,导致图层不能正常显示,自己捣鼓了很多次才发现。

(四)效果图:

参考链接:QGis C++ 开发之创建临时图层并添加要素

Qt+QGis二次开发:创建临时图层并添加要素的更多相关文章

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

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

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

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

  3. QGis C++ 开发之创建临时图层并添加要素

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

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

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

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

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

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

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

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

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

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

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

  9. NX二次开发-创建(临时)坐标系

    函数:UF_CSYS_create_csys() . UF_CSYS_create_temp_csys() 函数说明:创建坐标系 .创建临时坐标系 用法: #include <uf.h> ...

随机推荐

  1. 【RabbitMQ】4、RabbitMQ几种Exchange 模式

    AMQP协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列.生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机.先由Exchange来接收,然后Exchang ...

  2. Debian、Ubuntu恢复误删除(或者说重装)的/var/lib/dpkg

    在使用ubuntu的使用,有可能会碰到dpkg挂掉,网上的通用解决方法,如果不管用: 1, dpkg 被中断,您必须手工运行 sudo dpkg --configure -a解决此问题 2, sudo ...

  3. 中软高科WEB前端面试题

    一个朋友面试的题目,百度了一下这个中软高科貌似是一个培训机构...以下答案是我本人的理解,仅供参考 HTML+CSS 1.你能解释一下css的盒子模型吗? 有两种盒子模型:IE盒子模型,W3C盒子模型 ...

  4. loadrunner 11 安装与使用

    注:以下链接均为转载,详细内容请查看原文. 安装教程: https://blog.csdn.net/u010731693/article/details/78986840 使用教程: https:// ...

  5. python redis 终端 redis-cli.py mini版本 redis 终端管理工具

    Python redis-cli.py Python3 redis-cli 命令行管理工具 redis终端工具 由于最近测试redis未授权访问漏洞,发现本机没有安装redis,不能运行redis-c ...

  6. [20170914]tnsnames.ora的管理.txt

    [20170914]tnsnames.ora的管理.txt --//昨天朋友讲tnsnams.ora的内容太长了,而且许多不需要的.管理不方便.我记得以前写[20150409]tnsnames.ora ...

  7. 阿里云搭建JAVA WEB环境(SQL Server + TomCat + 配置域名)

    假期刚刚搭完,先写个提纲,今晚写完: 1.申请一个月的免费的云服务器ECS; 2.在云服务器上安装Java开发环境+Sql Server+Tomcat; 3.购买域名并认证,绑定服务器共有IP地址; ...

  8. Eclipse配置和使用Maven

    一.ecplise配置Maven 1.下载eclipse的Maven插件.(有些eclipse版本中已经集成了此Maven插件,可以不用下载). 需要下载m2eclipse插件. 2.安装m2ecli ...

  9. Python基础知识:文件和异常

    1.相对路径:如果文件和程序在同一文件夹内,可不用路径:如果文件在程序所在文件夹下一级文件夹中,只需添加下一级文件夹名称即可: 在Linux和OS系统中:文件路径中使用斜杠(/) 在Windows系统 ...

  10. chrony时间服务器

    chrony有着比ntp服务器更好的优势来同步服务,在集群架构中,采用此种服务来同步时间也是最好的方式. 在集群环境中,一般都是一个服务器,然后上百个客户端来同步服务端的时间,接下来我们看看如何配置. ...