前言
在学习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>