开发环境:Win10 + VS2010 + Qt 4.8.6 + QGis 2.14.4html
其实本文实现的功能相似于QGis中“添加文本数据图层”的一个简化版,本文不会涉及到对话框的使用,不经过与用户互交的方式建立要素,而是直接经过代码方式添加点要素,起到一个抛砖引玉的做用。app
(一)先将整个流程大概梳理下:分布式
一、首先建立一个临时(memory)矢量图层 ;ide
二、将建立的图层添加到地图画布中 ;测试
三、建立几何要素 ;ui
四、将几何要素添加到矢量图层中 ;编码
五、更新图层范围并刷新画布 .spa
(二)程序代码:指针
// 测试代码 /* "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;
(三)代码分析:code
建立临时图层
第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"表明建立的是一个临时图层。
将图层添加到地图画布中
第2一、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开发不久,我在程序的其余地方将画布冻结了,致使图层不能正常显示,本身捣鼓了不少次才发现。
(四)效果图: