本周在一位大佬的指引下,成功将OSG和QGIS的环境从VS迁移到QT creator下,其中主要是pro文件中include路径和lib的包含以及lib文件的加载。
其中主要的配置代码如下:
QGIS_RootDir = $$PWD/..
QGIS_3rdParty = $${QGIS_RootDir}/3rdParty
INCLUDEPATH += $${QGIS_3rdParty}
INCLUDEPATH += $${QGIS_3rdParty}/qgis289vs2010/include
QGISLibPath = $${QGIS_3rdParty}/qgis289vs2010/lib
Osg_RootDir = $$PWD/..
Osg_3rdParty = $${Osg_RootDir}/3rdParty
INCLUDEPATH += $${Osg_3rdParty}
INCLUDEPATH += $${Osg_3rdParty}/osg-3.4.0/include
OsgLibPath = $${Osg_3rdParty}/osg-3.4.0/lib
CONFIG(debug, debug|release){
BIN_DIR = $${QGIS_RootDir}/BinD
LIBS += $${QGISLibPath}/qgis_core.lib
LIBS += $${QGISLibPath}/qgis_gui.lib
LIBS += $${QGISLibPath}/qgis_analysis.lib
LIBS += $${OsgLibPath}/osgViewerd.lib
LIBS += $${OsgLibPath}/osgDBd.lib
LIBS += $${OsgLibPath}/OpenThreadsd.lib
LIBS += $${OsgLibPath}/osgd.lib
LIBS += $${OsgLibPath}/osgManipulatord.lib
LIBS += $${OsgLibPath}/osgTextd.lib
LIBS += $${OsgLibPath}/osgGAd.lib
LIBS += $${OsgLibPath}/osgUtild.lib
LIBS += $${OsgLibPath}/osgUId.lib
LIBS += $${OsgLibPath}/osgQTd.lib
}
else{
BIN_DIR = $${QGIS_RootDir}/Bin
LIBS += $${QGISLibPath}/qgis_core.lib
LIBS += $${QGISLibPath}/qgis_gui.lib
LIBS += $${QGISLibPath}/qgis_analysis.lib
LIBS += $${OsgLibPath}/osgViewer.lib
LIBS += $${OsgLibPath}/osgDB.lib
LIBS += $${OsgLibPath}/OpenThreads.lib
LIBS += $${OsgLibPath}/osg.lib
LIBS += $${OsgLibPath}/osgManipulator.lib
LIBS += $${OsgLibPath}/osgText.lib
LIBS += $${OsgLibPath}/osgGA.lib
LIBS += $${OsgLibPath}/osgUtil.lib
LIBS += $${OsgLibPath}/osgUI.lib
LIBS += $${OsgLibPath}/osgQT.lib
}
DESTDIR = $${BIN_DIR}
unix{
DEFINES += CORE_EXPORT=
DEFINES += GUI_EXPORT=
DEFINES += ANALYSIS_EXPORT=
}
!unix{
DEFINES += CORE_EXPORT=__declspec(dllimport)
DEFINES += GUI_EXPORT=__declspec(dllimport)
DEFINES += ANALYSIS_EXPORT=__declspec(dllimport)
}
其中
QGIS_RootDir = $$PWD/..
Osg_RootDir = $$PWD/..
是设置qgis和osg的根目录为此项目的上级目录,我的qgis和osg的库文件都放在这个根目录的3rdParty下
QGIS_3rdParty = $${QGIS_RootDir}/3rdParty
INCLUDEPATH += $${QGIS_3rdParty}
INCLUDEPATH += $${QGIS_3rdParty}/qgis289vs2010/include
QGISLibPath = $${QGIS_3rdParty}/qgis289vs2010/lib
Osg_3rdParty = $${Osg_RootDir}/3rdParty
INCLUDEPATH += $${Osg_3rdParty}
INCLUDEPATH += $${Osg_3rdParty}/osg-3.4.0/include
OsgLibPath = $${Osg_3rdParty}/osg-3.4.0/lib
以上这些代码是设置开发库的头文件和lib文件目录。
CONFIG(debug, debug|release){
BIN_DIR = $${QGIS_RootDir}/BinD
LIBS += $${QGISLibPath}/qgis_core.lib
LIBS += $${QGISLibPath}/qgis_gui.lib
LIBS += $${QGISLibPath}/qgis_analysis.lib
LIBS += $${OsgLibPath}/osgViewerd.lib
LIBS += $${OsgLibPath}/osgDBd.lib
LIBS += $${OsgLibPath}/OpenThreadsd.lib
LIBS += $${OsgLibPath}/osgd.lib
LIBS += $${OsgLibPath}/osgManipulatord.lib
LIBS += $${OsgLibPath}/osgTextd.lib
LIBS += $${OsgLibPath}/osgGAd.lib
LIBS += $${OsgLibPath}/osgUtild.lib
LIBS += $${OsgLibPath}/osgUId.lib
LIBS += $${OsgLibPath}/osgQTd.lib
}
else{
BIN_DIR = $${QGIS_RootDir}/Bin
LIBS += $${QGISLibPath}/qgis_core.lib
LIBS += $${QGISLibPath}/qgis_gui.lib
LIBS += $${QGISLibPath}/qgis_analysis.lib
LIBS += $${OsgLibPath}/osgViewer.lib
LIBS += $${OsgLibPath}/osgDB.lib
LIBS += $${OsgLibPath}/OpenThreads.lib
LIBS += $${OsgLibPath}/osg.lib
LIBS += $${OsgLibPath}/osgManipulator.lib
LIBS += $${OsgLibPath}/osgText.lib
LIBS += $${OsgLibPath}/osgGA.lib
LIBS += $${OsgLibPath}/osgUtil.lib
LIBS += $${OsgLibPath}/osgUI.lib
LIBS += $${OsgLibPath}/osgQT.lib
}
DESTDIR = $${BIN_DIR}
以上代码是依据QT的不同编译模式(debug、release),debug模式下加载相应的debug版库文件,release模式下加载release版库文件,且将项目exe文件生成到BIN_DIR目录下,debug模式下生成到BinD目录,release模式下生成到Bin目录。
unix{
DEFINES += CORE_EXPORT=
DEFINES += GUI_EXPORT=
DEFINES += ANALYSIS_EXPORT=
}
!unix{
DEFINES += CORE_EXPORT=__declspec(dllimport)
DEFINES += GUI_EXPORT=__declspec(dllimport)
DEFINES += ANALYSIS_EXPORT=__declspec(dllimport)
}
以上代码为QGIS的预定义命令。
经过以上Pro文件的定义,即可完成QT creator下的环境配置,注意应该新建一个构建套件(kits)设置编译器版本为编译qgis和osg源码的版本,qmake的版本要和编译osg是使用的版本相同,否则构建将失败。
本周又学习了一些osg和osgearth的知识,学会了使用osg构建地球模型,同时自己研究了将osg视口嵌入qt widget内的方法
构建两个类通过继承QGLWidget 和 osgViewer 从而实现osg视口在widget中的显示:
class AdapterWidget:public QGLWidget
{
public:
AdapterWidget(QWidget *parent=0,const char* name=0,const QGLWidget * shareWidget=0,WindowFlags f=0);
virtual ~AdapterWidget()
{
}
osgViewer::GraphicsWindow* getGraphicsWindow()
{
return _gw.get();
}
const osgViewer::GraphicsWindow* getGraphicsWidow()const
{
return _gw.get();
}
protected:
void init();
virtual void resizeGL(int width,int height);
virtual void keyPressEvent(QKeyEvent* event);
virtual void keyReleaseEvent(QKeyEvent* event);
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseReleaseEvent(QMouseEvent* event);//
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void wheelEvent(QWheelEvent* event);
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
};
class ViewerQT : public osgViewer::Viewer, public AdapterWidget
{
public:
ViewerQT(QWidget * parent=0,const char * name=0,const QGLWidget * shareWidget=0,WindowFlags f=0):AdapterWidget(parent ,name,shareWidget ,f)
{
getCamera()->setViewport(new osg::Viewport(0,0,width(),height()));
getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width())/static_cast<double>(height()), 1.0f, 10000.0f);
getCamera()->setGraphicsContext(getGraphicsWindow());
setThreadingModel(osgViewer::Viewer::SingleThreaded);
connect(&_timer,SIGNAL(timeout()),this,SLOT(updateGL()));//并且把它的timeout()连接到适当的槽。当这段时间过去了,它将会发射timeout()信号。
_timer.start(10);//使用start()来开始
}
virtual void paintGL()
{
frame();
}
protected:
QTimer _timer;
};
下面是osg中构建地球模型的代码,其中球半径为WGS84椭球半径:
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
hints->setDetailRatio(10);
osg::ref_ptr<osg::ShapeDrawable> sphere = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0,0,0),osg::WGS_84_RADIUS_POLAR),hints);
osg::ref_ptr<osg::Image> img1 = osgDB::readImageFile("land_shallow_topo_2048.jpg");
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
tex->setImage(img1);
//边界截取方案-->忽略边界-->消除裂缝(S、T、R对应X、Y、Z)
tex->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
tex->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
tex->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
stateset->setTextureAttributeAndModes(0,tex,osg::StateAttribute::ON);
sphere->setStateSet(stateset);
geode->addDrawable(sphere);
osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode;
csn->setEllipsoidModel(new osg::EllipsoidModel());
csn->addChild(geode);
root->addChild(csn);
ViewerQT * ViewerWindow=new ViewerQT;
ViewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
ViewerWindow->setSceneData(root.get());
将osg地球模型和之前完成的qgis系统结合:
目前还存在的问题有:1、没弄清qgis的头文件中间接包含了windows.h就会报错的解决方法,经确定为头文件重新define了min和max,还在寻求解决方法。
待完成:将二三维视口的坐标建立联系,实现两个视口坐标的联动即二三维的联动。