osg+osgEarth+vs+qt显示地球

1 篇文章 0 订阅


前言

在学习gis有关内容的时候,有可能会需要学习相关的osg的知识,此篇文章建立在所需库都已编译完成后来做的很简单的显示地球的demo。如需自行编译请跳过。需要以及编好的库私我。


一、运行结果

在这里插入图片描述

二、重要代码

头文件:

#pragma once
#include <QTimer>
#include <QApplication>
#include <QGridLayout>

#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/MultiTouchTrackballManipulator>
#include <osgDB/ReadFile>

#include "GraphicsWindowQt.h"

#include <iostream>
#include"earthwidget_global.h"
class EARTHWIDGET_EXPORT EarthWidget : public QWidget, public osgViewer::CompositeViewer
{
public:
    EarthWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, 
        osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::CompositeViewer::SingleThreaded);

    EarthWidget(const std::string& filePath,QWidget* parent = 0, Qt::WindowFlags f = 0,
        osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::CompositeViewer::SingleThreaded);

    QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene);

    osgQt::GraphicsWindowQt* createGraphicsWindow(int x, int y, int w,
        int h, const std::string& name = "", bool windowDecoration = false);

    //    virtual void paintEvent( QPaintEvent* /*event*/ )
    //    { frame(); }

        //定时器事件
    void timerEvent(QTimerEvent*)
    {
        frame();
    }

    //启动定时器绘制
    void show()
    {
        QWidget::show();
        _timerID = startTimer(10);
    }


protected:
    //QTimer _timer;
    int _timerID;               //定时器ID
};

源文件:

#include "EarthWidget.h"
#include <osgEarth/Map>
#include <osgEarthUtil/EarthManipulator>

EarthWidget::EarthWidget(QWidget* parent, Qt::WindowFlags f,
	osgViewer::ViewerBase::ThreadingModel threadingModel)
	: QWidget(parent, f)
{
    setThreadingModel(threadingModel);
    setKeyEventSetsDone(0);

    auto filePath = QCoreApplication::applicationDirPath().toStdString();

    QWidget* widget1 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile(filePath + "\\cow.osgt"));
    QWidget* widget2 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile(filePath + "\\glider.osgt"));
    QWidget* widget3 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile(filePath + "\\axes.osgt"));
    QWidget* widget4 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile(filePath + "\\fountain.osgt"));

    QGridLayout* grid = new QGridLayout;
    grid->addWidget(widget1, 0, 0);
    grid->addWidget(widget2, 0, 1);
    grid->addWidget(widget3, 1, 0);
    grid->addWidget(widget4, 1, 1);
    setLayout(grid);

    //connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
    //_timer.start( 10 );
}

EarthWidget::EarthWidget(const std::string& filePath, QWidget* parent, Qt::WindowFlags f, osgViewer::ViewerBase::ThreadingModel threadingModel)
{
    setThreadingModel(threadingModel);
    setKeyEventSetsDone(0);

    osgQt::GraphicsWindowQt* gw = createGraphicsWindow(0, 0, width(), height());
    osg::Node* globe = osgDB::readNodeFile(filePath);
    if (!globe)
        return;

    // viewer
    osgViewer::Viewer* viewer = new osgViewer::Viewer;
    viewer->setSceneData(globe);

    // manipulator
    osg::ref_ptr<osgEarth::Util::EarthManipulator> mainManipulator = new osgEarth::Util::EarthManipulator;
    viewer->setCameraManipulator(mainManipulator);

    // run
    viewer->setUpViewInWindow(100, 100, 800, 600);

    osg::ref_ptr<osg::Node> rus = viewer->getSceneData();
    QWidget* widget = addViewWidget(gw, rus);

    QHBoxLayout* hly = new QHBoxLayout;
    hly->addWidget(widget);

    setLayout(hly);
}

QWidget* EarthWidget::addViewWidget(osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene)
{
    osgViewer::View* view = new osgViewer::View;
    addView(view);

    osg::Camera* camera = view->getCamera();
    camera->setGraphicsContext(gw);

    const osg::GraphicsContext::Traits* traits = gw->getTraits();

    camera->setClearColor(osg::Vec4(0.2, 0.2, 0.6, 1.0));
    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));

    camera->setDrawBuffer(GL_BACK);
    camera->setReadBuffer(GL_BACK);

    camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0f, 10000.0f);

    view->setSceneData(scene);
    view->addEventHandler(new osgViewer::StatsHandler);
    view->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator);
    gw->setTouchEventsEnabled(true);
    return gw->getGLWidget();
}

osgQt::GraphicsWindowQt* EarthWidget::createGraphicsWindow(int x, int y, int w, int h,
    const std::string& name, bool windowDecoration)
{
    osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
    traits->windowName = name;
    traits->windowDecoration = windowDecoration;
    traits->x = x;
    traits->y = y;
    traits->width = w;
    traits->height = h;
    traits->doubleBuffer = true;
    traits->alpha = ds->getMinimumNumAlphaBits();
    traits->stencil = ds->getMinimumNumStencilBits();
    traits->sampleBuffers = ds->getMultiSamples();
    traits->samples = ds->getNumMultiSamples();

    return new osgQt::GraphicsWindowQt(traits.get());
}

合适的地方调用

OSGTest_01::OSGTest_01(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::SingleThreaded;
	//EarthWidget* viewWidget = new EarthWidget(0,Qt::Widget, threadingModel);
	//auto filePath = QCoreApplication::applicationDirPath().toStdString()+"/cow.osgt";
	auto filePath = QCoreApplication::applicationDirPath().toStdString() + "/test.earth";
	EarthWidget* viewWidget = new EarthWidget(filePath,this,0, threadingModel);
	setCentralWidget(viewWidget);
	viewWidget->show();
}

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

三、加载文件

1、 osgEarth源码有world.tif文件,拷入运行目录
2、自定义test.earth文件,内容如下:

<map name="MyMap" type="geocentric" version="2">
<image name="bluemarble" driver="gdal">
<url>world.tif</url>
</image>
</map>
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值