1. 程式人生 > >OSG+QGIS在QT Creator下環境配置

OSG+QGIS在QT Creator下環境配置

本週在一位大佬的指引下,成功將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,還在尋求解決方法。

待完成:將二三維視口的座標建立聯絡,實現兩個視口座標的聯動即二三維的聯動。