其他分享
首页 > 其他分享> > 在Vs2017上集成osgearth3.2和qt5.9,并加载shp文件。

在Vs2017上集成osgearth3.2和qt5.9,并加载shp文件。

作者:互联网

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

经过两个星期,从osg零基础,配置好osgearth和qt集成,并加载好shp文件, 本着记录自己学习的状态,做好笔记,提升自己对代码的熟悉状态写下本文,希望对大家有所帮助。


提示:以下是本篇文
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、QT5.9在vs上部署

如何在Vs中安装QT,并完成部署环境。

https://www.bilibili.com/video/BV1AX4y1w7Nt?spm_id_from=333.999.0.0
根据B站上的视频,进行完成部署qt。
在这里插入图片描述

1.1 在Vs中下载插件

打开 Visual Studio ,在拓展->管理拓展->联机->搜索 qt ,然后下载.下载完毕后关闭 VS ,此时弹出安装界面,选择安装即可。
在这里插入图片描述

1.2 配置QT

当插件下载完成时,Vs状态栏上方会出现 Qt VS Tools 工具按钮。
在这里插入图片描述
点击Qt Versions,配置QT路径。
路径根据你Qt上下载Vs版本进行加载即可。
在这里插入图片描述
配置完成后,就可以创建QT应用程序了。
在这里插入图片描述

二、OsgEarth3.2环境配置。

OSG中文社区里面有很多教程。
我这里将osg公开资源以网盘形式分享给大家。
链接:https://pan.baidu.com/s/13aenl-NqkXRrl40luNwnzg
提取码:539f

下载文件后,打开编译好的库。
里面有详细教程
在这里插入图片描述

三、在QT中配置OsgEarth3.2

这一步花了我大半时间,终于在一位大佬的博客中得到解决,谢谢大哥!
https://blog.csdn.net/ambition_xiaoman/article/details/118609661
大家可以自行查看。

配置好的qt大概是这种的
在这里插入图片描述
能够加载出地球即可
在这里插入图片描述

四、在QT环境中利用osgEarth3.2加载shp文件。

其中在QT环境配置好osgearth加载shp文件,网上有很多很多例子,但都是osgearth2.10的,但是osgearth2.1在qt上集成环境的例子好像没有,查了很多很多教程和网站都没有,我就根据osgEarth2.10的例子根据其帮助文档进行书写最终完成。

代码如下(示例):

//头文件
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_osg32qt.h"
#include "GraphicsWindowQt.h"

#include <QTimer>
#include <osg/Notify>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osg/Group>
#include <osg/Node>
#include <osg/Camera>
#include <osg/PositionAttitudeTransform>
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/Viewer>


#include <osgEarth/MapNode>
#include <osgEarth/GDAL>
#include <osgEarth/ExampleResources>
#include <osgEarth/EarthManipulator>
#include <osgEarth/SpatialReference>

#include <osgEarth/GeoTransForm>
#include <osgEarth/GeoCommon>


#include <osgEarth/Ephemeris>
#include <osgEarth/Sky>

#include <osgUtil/Tessellator>
#include <osgEarth/GLUtils>
#include <osg/Geode>
#include <osg/Geometry>

//要素类
#include <osgEarth/Style>
#include <osgEarth/OGRFeatureSource>
#include <osgEarth/FeatureModelLayer>
#include <osgEarth/FeatureImageLayer>

#include <QList>
#include <QGroupBox>
#include <ctime>
#include <QStatusBar>
#include <QCheckBox>
#include <QPushButton>
#include <QSpinBox>
#include <QLineEdit>


class osg32qt : public QMainWindow
{
    Q_OBJECT

public:
    osg32qt(QWidget *parent = Q_NULLPTR);
	~osg32qt();
private:
    Ui::osg32qtClass ui;

private:
	QTimer* _timer;		// 计时器,每5ms触发一次事件
	osgViewer::Viewer* viewer;
	osg::ref_ptr<osg::Group> root;
	osg::ref_ptr<osg::Camera> camera;
	osg::ref_ptr<osg::Node> earthNode;
	osg::ref_ptr<osgEarth::MapNode> mapNode;
	osg::ref_ptr<osgEarth::Map> map;
	osg::ref_ptr <osg::MatrixTransform> earthForm;
	osg::ref_ptr<osgEarth::EarthManipulator> em;
	tm* t_tm;
	osgEarth::SkyNode* m_pSkyNode;
	time_t now_time;
private:
	void InitOSG();// 初始化设置osg
	void InitUI();//界面初始化
	void InitTimer();//屏幕刷新初始化
	void InitOsgearth();//初始化osgearth
	void InitSky();//天空初始化
private slots:
	// 定时更新帧的槽函数
	void updateFrame();

};

//cpp文件

#include "osg32qt.h"
#include <osg/TexGen>
osg32qt::osg32qt(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
	InitOSG();
	InitOsgearth();
	InitUI();
	InitTimer();
}
osg32qt::~osg32qt()
{

}
void osg32qt::InitOSG()// 初始化设置osg
{
	viewer = new osgViewer::Viewer;
	// 设置模型
	root = new osg::Group;
	// 显示 .earth 文件中的地球模型
	

	//获取屏幕分辨率 长宽
	osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
	if (!wsi)
		return;
	unsigned int width, height;
	wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
	//设置图形环境特性
	osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
	traits->windowDecoration = false;//声明是否显示窗口的描述
	traits->x = 0;
	traits->y = 0;
	traits->width = width;
	traits->height = height;
	traits->doubleBuffer = true;//创建图形窗口是否使用双缓存

	//设置照相机
	camera = new osg::Camera;
	camera->setGraphicsContext(new osgQt::GraphicsWindowQt(traits.get()));
	camera->setClearColor(osg::Vec4(0.2, 0.2, 0.6, 1.0));
	camera->setViewport(new osg::Viewport(0, 0, width, height));
	camera->setProjectionMatrixAsPerspective(30.0f, (double(traits->width)) / (double(traits->height)), 1.0f, 10000.0f);

	//设置渲染器
	viewer->setCamera(camera);
	viewer->setSceneData(root);
	viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);//创建为单线程
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
}
void osg32qt::InitOsgearth()
{
	
	//earthNode = new osg::Node;
	//earthNode = osgDB::readNodeFile("./feature_labels.earth");
	//从底图影像图层开始;我们将使用 GDAL 驱动程序加载本地 GeoTIFF 文件:
	map = new osgEarth::Map();
	osgEarth::GDALImageLayer* basemap = new osgEarth::GDALImageLayer();
	basemap->setURL("G:\\QT\\osgt\\osgearth-3.2\\data\\world.tif");
	map->addLayer(basemap);

	//接下来,我们添加一个图层以提供要素数据。
	osgEarth::OGRFeatureSource* features = new osgEarth::OGRFeatureSource();
	features->setURL("G:\\QT\\osgt\\osgearth-3.2\\data\\world.shp");
	//features->setURL()
	map->addLayer(features);

	//定义要素数据的样式。由于我们将渲染矢量作为线,配置线符号化器:
	osgEarth::Style style;

	//可见性
	osgEarth::RenderSymbol* rs = style.getOrCreate<osgEarth::RenderSymbol>();
	rs->depthTest() = false;

	//贴地设置
	osgEarth::AltitudeSymbol* alt = style.getOrCreate<osgEarth::AltitudeSymbol>();
	alt->clamping() = alt->CLAMP_TO_TERRAIN;
	alt->technique() = alt->TECHNIQUE_DRAPE;

	osgEarth::LineSymbol* ls = style.getOrCreateSymbol<osgEarth::LineSymbol>();
	ls->stroke()->color() = osgEarth::Color::Yellow;
	ls->stroke()->width() = 2.0f;
	ls->tessellationSize()->set(100, osgEarth::Units::KILOMETERS);

	osgEarth::PolygonSymbol * polygonsymol = style.getOrCreateSymbol<osgEarth::PolygonSymbol>();
	polygonsymol->fill()->color() = osgEarth::Color(152.0f / 255, 251.0f / 255, 152.0f / 255, 0.8f); //238 230 133
	polygonsymol->outline() = true;
	
	//将要素的路径添加到图层里
	osgEarth::FeatureImageLayer* layer = new osgEarth::FeatureImageLayer();
	layer->setFeatureSource(features);
	//将style风格加载到图层中
	osgEarth::StyleSheet* sheet = new osgEarth::StyleSheet();
	sheet->addStyle(style);
	layer->setStyleSheet(sheet);
	map->addLayer(layer);


	osgEarth::LayerVector layers;
	map->getLayers(layers);
	for (osgEarth::LayerVector::const_iterator i = layers.begin(); i != layers.end(); ++i)
	{
		osgEarth::Layer* layer = i->get();
		if (layer->getStatus().isError() &&
			layer->getEnabled())
		{
			OE_WARN << layer->getName() << " : " << layer->getStatus().toString() << std::endl;
		}
	}


	mapNode = new  osgEarth::MapNode(map.get());
	//mapnode初始化
	//mapNode = osgEarth::MapNode::findMapNode(earthNode.get());
	//优化场景数据
	




	earthForm = new osg::MatrixTransform;
	//osgearth操作器 用来设置osgearh
	em = new osgEarth::Util::EarthManipulator;
	if (mapNode.valid())
	{
		em->setNode(mapNode);
	}

	em->getSettings()->setArcViewpointTransitions(true);
	//设置osg渲染窗口
	viewer->setCameraManipulator(em);

	//获取地球半径 设置视点
	//double earth_R = mapNode->getMap()->getSRS()->getEllipsoid()->getRadiusEquator();
	const char* viewPointName = QString::fromLocal8Bit("北京").toStdString().c_str();
	//em->setViewpoint(osgEarth::Viewpoint(viewPointName, 112.44, 33.75, 0.0, 0.0, -90.0, 5 * earth_R), 5);
	//初始化天空
	InitSky();
}
void osg32qt::InitSky()
{
	//获取当前时间 初始化天空
	now_time = time(0);
	t_tm = localtime(&now_time);
	osgEarth::DateTime cur_date_time(now_time);
	osgEarth::Ephemeris* ephemeris = new osgEarth::Ephemeris;

	//设置黑夜明暗程度
	osgEarth::Util::SkyOptions skyOptions;
	skyOptions.ambient() = 0.3;

	m_pSkyNode = osgEarth::SkyNode::create(skyOptions);
	m_pSkyNode->setName("SkyNode");
	m_pSkyNode->setEphemeris(ephemeris);
	m_pSkyNode->setDateTime(cur_date_time);
	viewer->setLightingMode(osg::View::SKY_LIGHT);
	m_pSkyNode->attach(viewer, 0);
	m_pSkyNode->setLighting(true);

	//添加到场景
	m_pSkyNode->addChild(mapNode);
	root->addChild(m_pSkyNode);

}
void osg32qt::InitUI()//界面初始化
{
	//osg 与 qt链接
	osgQt::GraphicsWindowQt* gw = dynamic_cast<osgQt::GraphicsWindowQt*>(camera->getGraphicsContext());
	//ui布局
	ui.horizontalLayout->addWidget((QWidget*)(gw->getGLWidget()));
	
	//QWidget* osg_widget = (QWidget*)(gw->getGLWidget());
	//this->setCentralWidget(osg_widget);

	//窗口最大化
	this->setWindowState(Qt::WindowMaximized);
	this->setWindowTitle(QString::fromLocal8Bit("数字地球"));
}
void osg32qt::InitTimer()//屏幕刷新初始化
{
	_timer = new QTimer;
	QObject::connect(_timer, SIGNAL(timeout()), this, SLOT(updateFrame()));
	_timer->start(10);

}
void osg32qt::updateFrame()
{

	viewer->frame();
}

效果图:
在这里插入图片描述


总结

OsgEarth3.2相关教程特别少,现在网络上大多都是osgEarth2.10的版本,因为我配置OsgEarth2.10和qt的环境出了一些问题,不然也不会用OsgEarth3.2了,继续加油。

标签:shp,osgearth3.2,QT,Vs2017,osg32qt,osgEarth,new,include,osg
来源: https://blog.csdn.net/weixin_44413499/article/details/121480542