日前由于项目需求,学习了QGIS,并在QGIS上进行二次开发。在这里记录一下到目前为止的——入坑过程。
下载QGIS可以从官网上直接下载。首先,我也是想着编译一下源码,从源码学习。当我开始下载源码之后,并按照网上的一系列教程开始编译时,到目前为止,我还没有成功过。都是在VS中编译时报各种错误。所以,本文不介绍源码编译。当我哪天成功了,我再来补充。
下面介绍一下我所使用的环境:
Qt开发环境配置:启动VS2017,如果没有安装Qt VS tools的在”工具–>扩展和更新”中搜索并下载安装。然后配置QtVSTools,添加Qt安装的路径。该部分内容可以自行百度。
当开发环境配置好了之后,创建Qt工程(Qt Gui Application)。在选择导入模块的时候勾选以下几个(其实就是比默认的多选择XML)
将编译环境改成release x64(release是因为QGIS下载的都是release版本的,debug得自己编译,x64是因为我的机器是64位的),然后编译、运行,看看时候能否正常执行
在“C++” >>”常规” >> “附加包含目录”中添加以下项(具体路径需要做适当调整):
C:\path\to\OSGeo4W64\include
C:\path\to\OSGeo4W64\apps\qgis\include
在“链接器” >>”常规” >> “附加库目录”中添加以下项(具体路径需要做适当调整):
C:\path\to\OSGeo4W64\apps\qgis\lib;
在“链接器” >>”输入” >> “附加依赖项”中添加以下项:
qgis_app.lib
qgis_core.lib
qgis_gui.lib
main.cpp
如下所示#include "ImageViewer.h"
#include
#include
int main(int argc, char *argv[])
{
QgsApplication a(argc, argv, true);
QgsApplication::setPrefixPath("C:/path/to/OSGeo4W64/apps/qgis", true);
QgsApplication::initQgis(); //初始化QGIS应用
ImageViewer w; //创建一个窗体,类似于Qt
w.show();
return a.exec(); //进入QGIS应用的消息循环
}
每一个QGIS的程序开始时都必须声明创建QgsApplication,这个和Qt必须创建QApplication一样,所以这里就是将QApplication替换成QgsApplication。QgsApplication::setPrefixPath
是用来设置qgis的安装路径的,其实它主要作用是加载plugins。
ImageViewer.cpp
如下所示#include "ImageViewer.h"
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qgsvectorlayer.h>
ImageViewer::ImageViewer(QWidget *parent)
: QMainWindow(parent)
{
this->resize(600, 400);
// create the menus and then add the actions to them.
fileMenu = this->menuBar()->addMenu("File");
openFileAction = new QAction("Open", this);
this->connect(openFileAction, SIGNAL(triggered(bool)), this, SLOT(on_openFileAction_triggered()));
fileMenu->addAction(openFileAction);
// initialize the map canvas
mapCanvas = new QgsMapCanvas();
this->setCentralWidget(mapCanvas);
mapCanvas->setCanvasColor(QColor(255, 255, 255));
mapCanvas->setVisible(true);
mapCanvas->enableAntiAliasing(true);
}
void ImageViewer::on_openFileAction_triggered() {
addVectorLayer();
}
void ImageViewer::addVectorLayer()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open shape file"), "", "*.shp");
QStringList temp = fileName.split('/');
QString basename = temp.at(temp.size() - 1);
QgsVectorLayer* vecLayer = new QgsVectorLayer(fileName, basename, "ogr");
if (!vecLayer->isValid())
{
QMessageBox::critical(this, "error", QString("layer is invalid: \n") + fileName);
return;
}
mapCanvas->setExtent(vecLayer->extent());
layers.append(vecLayer);
mapCanvas->setLayers(layers);
mapCanvas->refresh();
}
该段代码主要的作用就是添加菜单栏,在菜单栏中添加“File”菜单,然后在“File”菜单中增加一个“Open” Action,并设置Open的响应函数。在响应函数中加载矢量地图文件(.shp格式),并显示在界面中。
ImageViewer.h
如下所示#pragma once
#include
#include
#include
#include
class ImageViewer : public QMainWindow
{
Q_OBJECT
public:
ImageViewer(QWidget *parent = Q_NULLPTR);
private:
// create the menus and then add the actions to them.
QMenu *fileMenu;
QAction *openFileAction;
//map canvas
QgsMapCanvas *mapCanvas;
QList layers;
public slots:
void on_openFileAction_triggered();
//
public:
void addVectorLayer();
};
再次运行程序后会遇到缺少各种DLL的错误,这时候有两种方法:
C:\path\to\OSGeo4W64\bin
和C:\path\to\OSGeo4W64\app\qgis\bin
添加到环境变量Path中C:\path\to\OSGeo4W64\bin
和C:\path\to\OSGeo4W64\app\qgis\bin
中的DLL全部拷贝到生成的exe的目录下。这时再次运行程序,可能还是会缺少各种DLL,如果是以Qt5开头的,在C:\path\to\OSGeo4W64\app\Qt5
中查找;如果是其他的DLL,可以在你的系统中查找,推荐使用everything。如果还是找不到需要的DLL,请自己百度下载或者请留言,看看我有没有。