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

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

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

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

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

3、创建几何要素 ;

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

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

(二)程序代码:

  1. // 测试代码
  2.  
  3. /* "Point?crs=EPSG:4326&field=id:integer&
  4. * field=name:string(50)&index=yes&
  5. * memoryid={63152c31-9f38-4410-9983-fc9abe84973f}"
  6. */
  7. QString layerProperties = "Point?"; // 几何类型
  8. layerProperties.append(QString( "crs=EPSG:4326&" )); // 参照坐标系
  9. layerProperties.append(QString( "field=id:integer&field=name:string(50)&" )); // 添加字段
  10. layerProperties.append(QString( "index=yes&" )); // 创建索引
  11. layerProperties.append(QString( // 临时编码
  12. "memoryid=%1" ).arg( QUuid::createUuid().toString() ));
  13.  
  14. QgsVectorLayer* newLayer = new QgsVectorLayer(
  15. layerProperties, QString( "临时点层" ), QString( "memory" ) );
  16.  
  17. if (!newLayer->isValid())
  18. {
  19. return false;
  20. }
  21.  
  22. // 添加到地图
  23. QgsMapLayerRegistry::instance()->addMapLayer(newLayer);
  24.  
  25. QgsVectorDataProvider* dateProvider = newLayer->dataProvider();
  26.  
  27. // 创建点
  28. QgsFeature MyFeature;
  29. MyFeature.setGeometry( QgsGeometry::fromPoint(QgsPoint(102.4443, 32.2123)) );
  30. MyFeature.setAttributes(QgsAttributes() << QVariant(1) << QVariant("test"));
  31.  
  32. QgsFeature MyFeature1;
  33. MyFeature1.setGeometry( QgsGeometry::fromPoint(QgsPoint(102.4643, 32.2133)) );
  34. MyFeature1.setAttributes(QgsAttributes() << QVariant(2) << QVariant("test1"));
  35.  
  36. // 开始编辑
  37. newLayer->startEditing();
  38.  
  39. // 添加要素
  40. dateProvider->addFeatures(QgsFeatureList() << MyFeature << MyFeature1);
  41.  
  42. // 保存
  43. newLayer->commitChanges();
  44.  
  45. // 更新范围
  46. newLayer->updateExtents();
  47. mMapCanvas->refresh();
  48. 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行才真正创建临时图层:

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

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

  将图层添加到地图画布中  

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

  创建几何要素  

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

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

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

  1. 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. One Person Game(zoj3593+扩展欧几里德)

    One Person Game Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status ...

  2. java多线程关键字volatile、lock、synchronized

    --------------------- 本文来自 旭日Follow_24 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xuri24/article/detail ...

  3. css的一些细节

    1.中文符号居中效果 对于动态输出文字可以不用在意,某些页面可能会有类似提示文案的地方,用英文标点符号,对于居中效果比较友好. 2.元素的上下间距 布局的时候从上往下开始写页面,一般都是写下一个的元素 ...

  4. blfs(systemv版本)学习笔记-编译安装ligtdm显示管理器

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! ligtdm带有显示管理器和登录器,参照我的笔记安装xorg和i3后安装lightdm,就可以组成一个简易的桌面环境了 下面是l ...

  5. php+smarty轻松开发微社区/微论坛

    今天我们就来分析微社区的基本功能构成吧.首先,每个论坛最主要的是会员在对应的版块下发帖,或者在感兴趣的主题帖下跟帖盖楼.其次,会员能时时看到帖子或版块的基本信息.所以主要大块是: 前台:会员的注册登录 ...

  6. Linux 下tomcat 出现 java.lang.OutOfMemoryError: unable to create new native thread

    问题现象: Tomcat(8.5.13)部署了SuperMap iServer,并发用户在100左右.系统运行一段时间后,服务崩溃.异常提示 问题分析: 1.看到日志中的提示信息后,认为是系统内存不足 ...

  7. Chrome调试本地文件无法使用window.opener对象进行窗口间值传递

    今天在百度BAE上建了个应用,svn上传后发现页面间互调有些问题,几经查询发现: (1)IE下正常的window.opener.object1.object2页面间对象访问方法在Chrome下不能使用 ...

  8. Java JVM监控工具JConsole简介

    Java JVM监控工具JConsole简介 jconsole命令 功能:打开java监视管理控制台 方法: jconsole [选项1] [选项2] …… [选项n] 常用选项: -help     ...

  9. python pip 使用时错误: Patal error in launcher:Unable to create process using '"'

    当前我的电脑配置是64位, 装有python2.7 和python 3.6 两个版本 在使用pip install mysqlclient 的时候,出现了  Patal error in launch ...

  10. 高通 sensor 从native到HAL

    app注册传感器监听 Android Sensor Framework 的整体架构如下图所示: 前几篇sensor相关的文章介绍了sensor的hal的知识,以press_sensor实时显示气压坐标 ...