ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-11-22 22:01:36  阅读:362  来源: 互联网

标签:shp osgearth3.2 QT Vs2017 osg32qt osgEarth new include osg


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

文章目录


前言

经过两个星期,从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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有