QGIS二次开发,我的第一篇
来源:互联网 发布:英格拉姆体测数据 编辑:程序博客网 时间:2024/05/19 13:22
开始搞QGIS二次开发,希望能记录下开发的的点点滴滴,也是自己学习的笔记记录。
先直接上代码把:
#include<QtGui/QApplication>
#include<qgsapplication.h>
//扩展了Qapplication以便可以获取QGIS的特定资源,比如主题路径和数据库路径等。
#include<qgsproviderregistry.h>
//是一个单体类来管理数据访问程序(data provider),用于加载插件;
#include<qgsmaplayerregistry.h>
//此类用来记录现在已经加载的地图图层,并且提供方法来获取指向地;
#include<qgsvectorlayer.h>
//矢量图层;
#include<qgsmapcanvas.h>
//一个类保存了指向图层的指针,和图层是否可见等信息。是主要的地图区域,用于绘制地图。;
#include<QString>
#include<QApplication>
#include<QWidget>
#include <QStringList>
#include<QMessageBox>
#include<QObject>
#include <QList>
#include <QFileInfoList>
#include <QDir>
#include <QLibrary>
#include <QDebug>
#include <qgssymbollayerv2.h>
#include <qgssymbolv2.h>
#include <qgsmarkersymbollayerv2.h>
#include <qgsvectorlayerrenderer.h>
#include <qgsrendercontext.h>
#include <qgssinglesymbolrendererv2.h>//是一个渲染类,利用Qgssymbol来显示所有特征,可以用来渲染点,线 面用一个颜色(每个矢量图层必须有一个符号关联);
#include <qgssymbollayerv2.h>
//代码
int main( int argc, char *argv[] )
{
QgsApplication myApp( argc, argv, true );//在这里换成QgsApplication,方便调用QgsApplication的静态方法。
QgsApplication::setPrefixPath( "F:/QGISxiazai/dev", true );//设置插件路径;
QgsApplication::initQgis();
QgsProviderRegistry* provider = QgsProviderRegistry::instance();
// 改成你自己的点矢量文件路径
QString myLayerPath = "E:/data/dierpi/point55.shp";
QString myLayerBaseName = "airports"; //图层名称;
////打开矢量文件;
QList<QgsMapLayer*> myList;
QgsVectorLayer* veclayer = new QgsVectorLayer( myLayerPath, myLayerBaseName, "ogr", false );
if ( !veclayer )
{
return 0;
}
if ( veclayer->isValid() )
{
QMessageBox::information( 0, "", "layer is valid" );
veclayer->setProviderEncoding( "System" );
myList << veclayer;
}
if ( veclayer->geometryType() == QGis::Point )
{
// 创建 svgMarkerSymbolLayer
QgsSvgMarkerSymbolLayerV2* svgMarker = new QgsSvgMarkerSymbolLayerV2();
svgMarker->setPath( "F:/QGISxiazai/dev/svg/money/money_currency_exchange.svg" );
QgsSvgMarkerSymbolLayerV2* svgMarker1 = new QgsSvgMarkerSymbolLayerV2();
svgMarker1->setPath( "F:/QGISxiazai/dev/svg/money/money_atm.svg" );
QgsSymbolLayerV2List symList;
symList.append( svgMarker );
symList.append( svgMarker1 );///绑定;
QgsMarkerSymbolV2* markSym = new QgsMarkerSymbolV2( symList );
//分配一个地图渲染器,需要传入几何类型(vectorlayer是一个自我描述的类);
QgsSingleSymbolRendererV2* symRenderer = new QgsSingleSymbolRendererV2( markSym );
svgMarker->setSize( 5 );
svgMarker1->setSize( 5 );////大小设置;
veclayer->setRendererV2( symRenderer );
}
//实例化地图注册类之后,然后增加图层;
QgsMapLayerRegistry::instance()->addMapLayer( veclayer );
QList<QgsMapCanvasLayer> myLayerSet;
//向list数据中增加mapCanvasLayer;
myLayerSet.append( QgsMapCanvasLayer( veclayer ) );
QgsMapCanvas* mypMapCanvas = new QgsMapCanvas( 0, 0 );
mypMapCanvas->setExtent( veclayer->extent() );
//开启反锯齿效果;
mypMapCanvas->enableAntiAliasing( true );
mypMapCanvas->setCanvasColor( QColor( 255, 255, 255 ) );
mypMapCanvas->freeze( false );
//设定mapCanvas的数据集;
mypMapCanvas->setLayerSet( myLayerSet );
mypMapCanvas->setVisible( true );
mypMapCanvas->refresh();
return myApp.exec();
}
在这个工程之前需要把工程路径的各个库配置好;
在生成的EXE下要对应好相应的dll版本,才能正确运行;
x现在来分析一下代码:
几个类之间的关系
首先要讲的,是矢量图层样式相关的几个类,它们分别是
- QgsVectorLayer
- QgsSymbolV2
- QgsSymbolLayerV2
- QgsFeatureRendererV2
它们的关系是这样的。QgsFeatureRendererV2 控制着QgsVectorLayer 的“渲染”样式,而具体用什么样式来“渲染”,则是有 QgsSymbolV2来定义的,QgsSymbolLayerV2 是 QgsSymbolV2 的扩展。搞明白这几个类的关系有助于我们后面的理解。实际上,我们基本不会直接用到这几个类,大多数时候是在用它们的子类。
QgsVectorLayer 不必多说,只需要知道使用它的方法“setRendererV2()”来绑定它的 Renderer 就好了。
QgsFeatureRendererV2
来看看矢量图层都支持那些 Renderer,也就是 QgsFeatureRendererV2 这个类的派生关系,如下图
从图上可以看到,这里支持的渲染方式还是蛮多的,GIS的同学看到这些名字应该不会太陌生,就是我们设置图层属性面板时候的那个下拉菜单里面的内容,见下图。
这里内容太多,就不逐个介绍了,本篇文章中我们只关注一个最简单也是最常用的 QgsSingleSymbolRendererV2 ,也就是我们经常使用在点图层标记上的单个的样式。
QgsSymbolV2
这个类就是直接关系到图层显示的“造型”了,也就是在这里设置各种图层样式的属性。还是先来看看它的派生类关系。
简单说明一下,QgsFillSymbolV2 对应的是多边形矢量图层,QgsLineSymbolV2 对应的是线性矢量图层, 而QgsMarkerSymbolV2 自然就是对应点矢量图层了。
关于这些类的设置大多集中在“颜色”、“大小”、“透明度”等属性上,每个派生类也都有自己的一些属性,详细的情况还是建议大家看看 API 文档 。
QgsSymbolLayerV2
QGis扩展了简单的 Symbol 图层样式,将原来单一的 Symbol 变成了“图层”方式,使得样式可定制的自由度开阔了许多, 当然派生关系也多了很多,见下图。
从这个图里面可以看到,分别对应这多边形、线和点都有各自的样式图层,将一个矢量图形的图标拆分,基本每个地方都有可定制的余地,都有专门的样式图层类来控制。这里很多同学应该特别关注一下QgsSvgMarkerSymbolLayerV2 这个类,这个类允许我们使用自己做好的“svg”格式的图标来作为图层的显示样式,借助这个特性,我们能够将t做成图层显示成任何我们想要的样式,如下图效果。
调用机理
下面我将会通过一个非常简单的示例来阐述这些类的调用机理。
要做图层样式显示,自然需要一个矢量图层,于是
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
这里我们以“点”图层作为例子,直接copy代码的同学,需要将你的文件路径改为一个有效的“点”图层文件路径。
然后,创建一个样式图层,也就是 QgsSymbolLayerV2 类型,但我们要使用“svg” 格式的图片作为显示样式,因此使用 QgsSymbolLayerV2 的派生类 QgsSvgMarkerSymbolLayerV2 。先不要太在意下面代码中构造函数里面的字符串,后面来讲它的作用。
- 1
- 2
- 1
- 2
前面说过,这是一个样式图层,图层是可以叠加的,也就是说可以做好几个这样的样式,然后叠加上去显示,但是总归要有一个管理这些样式图层的集合,于是
- 1
- 1
并将刚才创建的样式图层装到这个 List 里面去,喜欢的话你可以多装几个样式图层进去,这里就只装一个做演示。
- 1
- 1
做好了显示样式,还需要将这个样式传给图层”渲染器“才行,需要建立一个点图层的 Renderer,并且这个 Renderer 还只接受 QgsSymbolV2 这个类型的参数,于是需要将样式图层 QgsSymbolLayerV2 转换为 QgsSymbolV2 类型。由于这里是点图层,就用到 QgsSymbolV2 的子类 QgsMarkerSymbolV2 , 又通过 API 文档了解到这个类的构造函数接受 QgsSymbolLayerV2List 这个样式图层的集合,于是也就将 Symbol 和 SymbolLayer 联系了起来。代码如下。
- 1
- 2
- 1
- 2
最后,就只需要将这个图层渲染器连接到之前建立的矢量图层就好了
- 1
- 1
这样,MapCanvas 刷新以后,就可以看到图层的显示效果了。如果觉得图标小,还可以加一句
- 1
- 1
效果如下图:
最后一点
上面的代码直接拷贝是会有问题的,效果应该是下面这样
全是问号,为什么?
这是没有找到对应的 svg 图标,也就是刚才上面的那一句
- 1
- 1
这里只给了文件的名称,并没有指出文件的路径,因此程序找不到对应的 svg 格式文件。
打开QGis源码,不难发现这里有两种方式传文件路径,一种是在全局设置一个 svg 文件夹的默认路径,另一种则是直接在创建类之后给出完整的文件路径。
- 先设置默认路径,再传文件名作为构造函数的参数
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
之后就可以按照上文的方式传文件名 “money/money_bank2.svg” 进去了
- 1
- 1
- 直接给出完成的文件路径
- 1
- 2
- 1
- 2
效果是一样的。
这里先借用别人的分析了,引自http://blog.csdn.net/deirjie/article/details/50464768- QGIS二次开发,我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- 我的第一篇
- Python-将文本中内容按行读入numpy中
- HCDA学习笔记(二)
- String和ASCII相互转换
- ubuntu14.04 nfs 搭建
- 数据结构——顺序线性表
- QGIS二次开发,我的第一篇
- Response.sendRedirect()
- 判断当前界面是不是桌面
- 【前端攻城狮之路】手把手教你用CSS画三角形(百度15前端研发笔试卷)
- LINQ体验(2)——C# 3.0新语言特性和改进(上篇)
- AndroidStudio插件开发(进阶篇之Action机制)
- cogs740 [网络流24题]分配问题
- Leetcode N-Queens II
- hive 与 kylin的搭建