osgEarth在地图里读取飞机模型

一、思路

先设置地图节点,把.earth地图文件读取到地图节点里,然后再创建一个模型节点,读取.osg模型文件进入模型节点,并通过computeLocalToWorldTransformFromLatLongHeight函数设置模型出现的坐标及高度,最终显示

setViewpoint方向角是顺时针旋转的,默认朝向正北,旋转90朝向正东,旋转-90朝向正西。

 matrix的旋转和 setViewpoint相反,matrix为顺时针。

俯仰角-90度为垂直向下,0度为水平方向。

二、代码

earth+model.cpp文件

#include <Windows.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <cstring>
#include <time.h>
#include <osgEarth/MapNode>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>
//键盘事件
#include<osgViewer/ViewerEventHandlers>
//osgGA相关的库
#include<osgGA/StateSetManipulator>

#include <osgViewer/Viewer>
#include <osgDB/WriteFile>

using namespace std;


int main(int argc, char* argv[])
{
	osg::ref_ptr<osgViewer::Viewer>viewer = new osgViewer::Viewer;
	//添加状态事件,可以相应键盘和鼠标事件,响应L T B W
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
	//窗口大小变化,响应F
	viewer->addEventHandler(new osgViewer::WindowSizeHandler);
	//添加路径记录 Z
	viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
	//帮助文档显示H
	viewer->addEventHandler(new osgViewer::HelpHandler);
	//截屏 C
	viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
	//添加一些常用状态设置,响应S
	viewer->addEventHandler(new osgViewer::StatsHandler);

	//操作器
	osg::ref_ptr<osgEarth::Util::EarthManipulator> earthManipulator = new osgEarth::Util::EarthManipulator;
	//设置相机操作器
	viewer->setCameraManipulator(earthManipulator);
	//根节点
	osg::ref_ptr<osg::Group>root = new osg::Group;

	//加载地球节点
	osg::Node* earthNode = osgDB::readNodeFile("clear.earth");
	//将地球节点加入根节点
	root->addChild(earthNode);
	//设置现场数据
	viewer->setSceneData(root.get());
	//实现
	viewer->realize();

	//检测地图节点是否创建好
	osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode(earthNode);
	if (!mapNode) return 0;

	//空间设置,水平和垂直
	const osgEarth::SpatialReference* geoSRS = mapNode->getMapSRS()->getGeographicSRS();

	//添加模型
	osg::Node* model = osgDB::readNodeFile("cessna.osg");
	//osg中光照只会对有法线的模型起作用,而模型经过缩放后法线是不会变得,
	//所以需要手动设置属性,让法线随着模型大小变化而变化。GL_NORMALIZE 或 GL_RESCALE_NORMAL
	model->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);

	osg::Matrix Lmatrix;
	geoSRS->getEllipsoid()->computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(40.0), osg::DegreesToRadians(116.0), 500000.0, Lmatrix);  //维度,经度,高度,localToWorld
	//放大一些,方便看到
	Lmatrix.preMult(osg::Matrix::scale(osg::Vec3(30000, 30000, 30000)));//x,y,z轴放大倍数

	osg::MatrixTransform* mt = new osg::MatrixTransform;
	mt->setMatrix(Lmatrix);
	mt->addChild(model);
	root->addChild(mt);

	viewer->setSceneData(root);

	//视点定位北京地区,此句代码运行后可以直接定位到该坐标,注释后仍能正常显示模型,不过不会自动定位
	earthManipulator->setViewpoint(osgEarth::Viewpoint("模拟无人机", 116, 40, 0.0, 0.0, -90.0, 1.5e6));
	return viewer->run();
}

world.earth里面读取的是world.tif文件,所以地图信息相当于在地球上贴了一张图片,如果想像谷歌地球那样看到细节信息,需要读取其他在线地图文件,例如arcgisonline.earth,加载速度会相对慢一些。

world.earh文件

<map>
	<image name="bluemarble" driver="gdal">  
	<url>world.tif</url>  
	</image>  	
</map>

三、结果展示

演示视频

osgearth读取多个osg模型文件

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用GDAL库读取S57地图的代码示例: ```c++ #include <iostream> #include <gdal_priv.h> #include <ogrsf_frmts.h> int main() { GDALAllRegister(); // 输入S57文件路径 const char* filePath = "path/to/s57/file"; // 打开S57文件 GDALDataset* dataset = (GDALDataset*)GDALOpenEx(filePath, GDAL_OF_READONLY | GDAL_OF_VECTOR, NULL, NULL, NULL); if (dataset == NULL) { std::cout << "Failed to open S57 file." << std::endl; return 1; } // 获取第一个图层 OGRLayer* layer = dataset->GetLayer(0); if (layer == NULL) { std::cout << "Failed to get layer." << std::endl; GDALClose(dataset); return 1; } // 输出图层属性信息 OGRFeatureDefn* featureDefn = layer->GetLayerDefn(); std::cout << "Layer Name: " << featureDefn->GetName() << std::endl; std::cout << "Field Count: " << featureDefn->GetFieldCount() << std::endl; // 逐个读取图层要素 OGRFeature* feature = NULL; layer->ResetReading(); while ((feature = layer->GetNextFeature()) != NULL) { // 获取要素几何信息 OGRGeometry* geometry = feature->GetGeometryRef(); if (geometry != NULL) { // 输出要素几何信息 std::cout << "Geometry Type: " << geometry->getGeometryName() << std::endl; } // 获取要素属性信息 OGRFeatureDefn* featureDefn = layer->GetLayerDefn(); int fieldCount = featureDefn->GetFieldCount(); for (int i = 0; i < fieldCount; ++i) { OGRFieldDefn* fieldDefn = featureDefn->GetFieldDefn(i); std::cout << fieldDefn->GetNameRef() << ": " << feature->GetFieldAsString(i) << std::endl; } // 释放要素内存 OGRFeature::DestroyFeature(feature); } // 关闭S57文件 GDALClose(dataset); return 0; } ``` 该代码主要使用了GDAL库和OGR库,首先通过GDALOpenEx函数打开S57文件,然后获取第一个图层并输出其属性信息,最后逐个读取图层要素,输出要素的几何信息和属性信息,释放内存并关闭文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aspiretop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值