QGis 二次开发基础 -- 显示数据
来源:互联网 发布:淘宝漏洞q币充值的网站 编辑:程序博客网 时间:2024/05/16 18:21
一直在忙别的事情,有很长一段时间没有做QGis。(忙着毕业,老师还要我写SCI,着实不容易。)在QGis的QQ群中很多初学者同学提出的一些问题,也没有怎么帮到大家,在这里讲一声抱歉了。(顺带宣传一下,QGis二次开发交流QQ群:68016799。)我也仅仅是刚入门而已,希望能够跟共同喜欢探索、喜欢开发的同学共交流。
写在前面,QGis源码编译请看这里 – QGis2.9.0源码编译及二次开发包下载, 二次开发环境配置请看这里 – qgis二次开发环境配置
今天正好有空,就想写一个非常基础的二次开发教程给大家。这篇博文,是为了解决大家在QGis二次开发学习过程中的一个非常基础的问题 – “显示数据”(没错,就是这么基础,任性!)。这里面涉及的东西确实是非常基础、非常简单的,但正是这么简单的东西也难倒了好一些同学,确实因为QGis的资料太少,现有的又大多比较陈旧、不适用。很多同学好不容易终于成功编译了QGis的源代码,然后就不知道怎么办了,找不到教程或者找到的教程都不能用。我在群里看到很多同学刚加进来就是为了要问一下“显示数据”的问题,可见这个问题虽然基础,但有一个可用的教程,总好过没有,能省去大家一点点时间纠结,也算是一种贡献吧。
进入正题。
首先,新建一个Qt Application工程,随便取个名字,就叫“qgis_dev”吧。
配置工程,见下图:
建立好工程之后,应该是这个样子的
有一个.ui的文件,是主界面,qgis_dev.h 和qgis_dev.cpp是控制这个主界面的Qt类。
这个时候需要配置QGis的开发环境,这个我在之前的博客中讲过了,步骤是一致的,就不赘述了。不清楚的同学可以参见这里–qgis二次开发环境配置。
双击那个 qgis_dev.ui 的文件,会打开Qt Designer,进行界面的设计。这里我们主要关注菜单的设计就行了,毕竟这部分都是Qt的知识,我想大家应该是比较清楚的吧。我主要添加了两个Action,分别是Vector菜单下的Add Vector 功能,以及Raster菜单下的Add Raster功能。今天也就只说这两个的功能的实现问题。
保存好这个UI,然后关闭Qt Designer,回到VS环境中。
打开qgis_dev.h将代码修改如下。(先贴源码,后面再详细分析源码中的语句)
#ifndef QGIS_DEV_H#define QGIS_DEV_H#include <QtGui/QMainWindow>#include "ui_qgis_dev.h"#include <QList>// QGis include#include <qgsmapcanvas.h>#include <qgsmaplayer.h>class qgis_dev : public QMainWindow{ Q_OBJECTpublic: qgis_dev( QWidget *parent = 0, Qt::WFlags flags = 0 ); ~qgis_dev();public slots: /** * 添加矢量图层 * * @return void - **/ void addVectorLayers(); /** * 添加栅格图层 * * @return void - **/ void addRasterLayers();private: Ui::qgis_devClass ui; QgsMapCanvas* mapCanvas; // 地图画布 QList<QgsMapCanvasLayer> mapCanvasLayerSet; // 地图画布所用的图层集合};#endif // QGIS_DEV_H
然后是qgis_dev.cpp文件
#include "qgis_dev.h"#include <QDialog>#include <QFileDialog>#include <QMessageBox>// QGis include#include <qgsvectorlayer.h>#include <qgsmaplayerregistry.h>#include <qgsrasterlayer.h>qgis_dev::qgis_dev( QWidget *parent, Qt::WFlags flags ) : QMainWindow( parent, flags ){ ui.setupUi( this ); mapCanvas = new QgsMapCanvas( ); this->setCentralWidget( mapCanvas ); mapCanvas->enableAntiAliasing( true ); mapCanvas->setCanvasColor( QColor( 255, 255, 255 ) ); mapCanvas->setVisible( true ); // connections connect( ui.actionAdd_Vector, SIGNAL( triggered() ), this, SLOT( addVectorLayers() ) ); connect( ui.actionAdd_Raster, SIGNAL( triggered() ), this, SLOT( addRasterLayers() ) );}qgis_dev::~qgis_dev(){}void qgis_dev::addVectorLayers(){ QString filename = QFileDialog::getOpenFileName( this, tr( "open vector" ), "", "*.shp" ); QStringList temp = filename.split( QDir::separator() ); QString basename = temp.at( temp.size() - 1 ); QgsVectorLayer* vecLayer = new QgsVectorLayer( filename, basename, "ogr", false ); if ( !vecLayer->isValid() ) { QMessageBox::critical( this, "error", "layer is invalid" ); return; } QgsMapLayerRegistry::instance()->addMapLayer( vecLayer ); mapCanvasLayerSet.append( vecLayer ); mapCanvas->setExtent( vecLayer->extent() ); mapCanvas->setLayerSet( mapCanvasLayerSet ); mapCanvas->setVisible( true ); mapCanvas->freeze( false ); mapCanvas->refresh();}void qgis_dev::addRasterLayers(){ QString filename = QFileDialog::getOpenFileName( this, tr( "open vector" ), "", "*.tif" ); QStringList temp = filename.split( QDir::separator() ); QString basename = temp.at( temp.size() - 1 ); QgsRasterLayer* rasterLayer = new QgsRasterLayer( filename, basename, "gdal", false ); if ( !rasterLayer->isValid() ) { QMessageBox::critical( this, "error", "layer is invalid" ); return; } QgsMapLayerRegistry::instance()->addMapLayer( rasterLayer ); mapCanvasLayerSet.append( rasterLayer ); mapCanvas->setExtent( rasterLayer->extent() ); mapCanvas->setLayerSet( mapCanvasLayerSet ); mapCanvas->setVisible( true ); mapCanvas->freeze( false ); mapCanvas->refresh();}
最后是main.cpp文件
#include<QtGui/QApplication>#include<qgsapplication.h>#include<QApplication>#include "qgis_dev.h"int main( int argc, char *argv[] ){ QgsApplication myApp( argc, argv, true ); QgsApplication::setPrefixPath( "C:/Program Files/qgis2.9.0", true ); // 注意:把这里的路径改成你电脑上Qgis的路径!!! QgsApplication::initQgis(); qgis_dev* myQgis = new qgis_dev(); myQgis->show(); return myApp.exec();}
OK,讲完了,直接运行应该就可以了,如果debug模式报错,试试release模式,有些同学用的QGis二次开发包不同,所以区分debug和release的。不过记住切换模式的时候,项目的开发属性需要重新配置。
现在分析下里面的核心代码以及比较容易出错的地方。
首先是main函数中的前三句
QgsApplication myApp( argc, argv, true ); QgsApplication::setPrefixPath( "C:/Program Files/qgis2.9.0", true ); // 注意:把这里的路径改成你电脑上Qgis的路径!!! QgsApplication::initQgis();
这个是QGis2.0版本以后的启动方式,其中setPrefixPath这个方法里面的路径是QGis的文件夹路径,这个函数的作用在QGis源代码中是这样的
可见这个路径是为了加载一些QGis文件夹中的路径,这里我们主要关注上图中标红的那句,也就是我们的plugin文件夹路径,加载数据必须加载的ogrprovider.dll以及gdalprovider.dll这两个文件都是在plugin文件夹下,因此这个路径没有配置正确,会存在加载数据失败的问题。
然后是QgsApplication::initQgis() 这个方法,源代码中的定义如下
也就是通过上面设置的插件路径来加载插件了。
在显示数据的部分,我们主要关心qgis_dev.cpp的addVectorLayers()这个方法,其中
QgsVectorLayer* vecLayer = new QgsVectorLayer( filename, basename, “ogr”, false );
这一句新建矢量图层,filename是矢量文件绝对路径,basename是名称。建立了图层以后,需要在图层管理中注册,也就是
QgsMapLayerRegistry::instance()->addMapLayer( vecLayer );
而要显示,则要加入到地图画布的图层集合中,这里的图层集合是由QList mapCanvasLayerSet;定义的,因此后面这句就比较明确了
mapCanvasLayerSet.append( vecLayer );
之后,就是将这个图层集合与地图画布关联起来,并设置相应的属性,刷新就能显示了
mapCanvas->setExtent( vecLayer->extent() );mapCanvas->setLayerSet( mapCanvasLayerSet );mapCanvas->setVisible( true );mapCanvas->freeze( false );mapCanvas->refresh();
后面的Raster图层的添加方式与这个类似,大家看代码应该就明白了。
最后,贴上工程的显示效果吧,支持漫游哦。
OK,先这样吧,放一个框架在这里,有空的话再把这个例子深入下去。大家有什么问题可以加QQ群:68016799,或者对什么功能感兴趣可以留言,共同交流,谢谢阅读。
- QGis 二次开发基础 -- 显示数据
- QGis 二次开发基础 -- 显示数据
- QGis二次开发基础 -- 图标不显示问题
- QGis二次开发基础 -- 栅格图像增强显示
- QGis二次开发基础 -- 栅格图像增强显示
- QGis二次开发基础 -- 矢量图层的显示样式
- QGis二次开发基础 -- 矢量图层属性图表显示
- QGis二次开发基础 -- 矢量图层的显示样式
- QGis二次开发基础 -- 矢量图层属性图表显示
- QGis二次开发基础 -- 属性表格
- QGis二次开发基础 -- 文字标注
- QGis二次开发基础 -- 属性表格
- QGis二次开发基础 -- 构建图层管理器
- QGis二次开发基础 -- 添加在线地图服务
- QGis二次开发基础 -- 根据属性查询要素
- QGis二次开发基础 -- 添加矢量要素功能
- QGis二次开发基础 -- 销毁当前地图工具
- QGis二次开发基础 -- 构建图层管理器
- 装饰模式
- web项目设置全局变量
- 最拥堵的路段
- FPGA
- 【PS】改变图标颜色
- QGis 二次开发基础 -- 显示数据
- xcode import<xx/xx.h> 头文件报错
- asp.net网页间传值方式之Response.Redirect和Server.Transfer
- IO_字节流_节点流_文件夹拷贝_工具制作_文件后缀与软件的关系JAVA149、163
- Error:(2, 0) Plugin with id 'com.github.dcendents.android-maven' not found解决办法
- SecureCRT突然假死的问题(Ctrl+S)
- iOS开发之数据存储(偏好设置)
- 返回页面
- Redis整合Spring结合使用缓存实例