1. 概述

ContextCapture(Smart3D)生成的倾斜摄影模型数据一般都形如如下组织结构:

在Data目录下包含了分块的瓦片数据,每个瓦片都是一个LOD文件夹。osg能够直接读取osgb格式,理论上只需要依次加载每个LOD的金字塔层级最高的osgb,整个倾斜摄影模型数据就加载进来了。不过有点麻烦的是这类数据缺乏一个整体加载的入口,如果每次加载都遍历整个文件夹加载的话,会影响加载的效率。所以一般的数据查看软件都会为其增加一个索引。

这里就给倾斜摄影数据添加一个osgb格式的索引文件,生成后就可以通过OSG直接加载整个倾斜摄影模型数据。

2. 实例

2.1. 代码

具体的实现代码如下:

#include <iostream>
#include <string> #include <QDir> #include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile> using namespace std; //查找目录下所有的文件夹
static void findDir(string dir, vector<string>& subDirs)
{
//
subDirs.clear();
QDir fromDir(QString::fromLocal8Bit(dir.c_str()));
QStringList filters; //
QFileInfoList fileInfoList = fromDir.entryInfoList(filters, QDir::AllDirs | QDir::Files);
foreach(QFileInfo fileInfo, fileInfoList)
{
if (fileInfo.fileName() == "." || fileInfo.fileName() == "..")
{
continue;
} if (fileInfo.isDir())
{
QByteArray dir = fileInfo.filePath().toLocal8Bit();
subDirs.push_back(dir.data());
}
}
} //得到文件路径的文件名 C:\\b\\a(.txt) -> a
static std::string DirOrPathGetName(std::string filePath)
{
size_t m = filePath.find_last_of('/');
if (m == string::npos)
{
return filePath;
} size_t p = filePath.find_last_of('.');
if (p != string::npos && p > m) //没有点号或者
{
filePath.erase(p);
} std::string dirPath = filePath;
dirPath.erase(0, m + 1);
return dirPath;
} void createObliqueIndexes(std::string fileDir)
{
string dataDir = fileDir + "/Data"; osg::ref_ptr<osg::Group> group = new osg::Group();
vector<string> subDirs;
findDir(dataDir, subDirs); for (size_t i = 0; i < subDirs.size(); i++)
{
string name = DirOrPathGetName(subDirs[i]);
string path = subDirs[i] + "/" + name + ".osgb"; osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(path);
osg::ref_ptr<osg::PagedLOD> lod = new osg::PagedLOD(); auto bs = node->getBound();
auto c = bs.center();
auto r = bs.radius();
lod->setCenter(c);
lod->setRadius(r);
lod->setRangeMode(osg::LOD::RangeMode::PIXEL_SIZE_ON_SCREEN);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->getOrCreateStateSet();
lod->addChild(geode.get()); std::string relativeFilePath = "./Data/" + name + "/" + name + ".osgb"; //相对路径 lod->setFileName(0, "");
lod->setFileName(1, relativeFilePath); lod->setRange(0, 0, 1.0); //第一层不可见
lod->setRange(1, 1.0, FLT_MAX); lod->setDatabasePath(""); group->addChild(lod);
}
std::string outputLodFile = fileDir + "/Data.osgb";
osgDB::writeNodeFile(*group, outputLodFile);
} int main(int argc, char *argv[])
{
string fileDir = "D:/Data/scene/city";
std::string outputLodFile = fileDir + "/Data.osgb";
createObliqueIndexes(fileDir); osgViewer::Viewer viewer;
osg::Node * node = new osg::Node;
node = osgDB::readNodeFile(outputLodFile);
viewer.setSceneData(node); return viewer.run();
}

2.2. 解析

如果直接读取每一块的LOD然后通过osgDB::writeNodeFile写入到一个osgb文件,这个文件就会保存所有块的LOD第一层信息。这样在第二册加载的时候还是会比较慢,所以这里就创建了一个空的节点,形成了索引所有LOD块的数据结构。对于每一块数据,新建两层LOD,第一层为自身的空白节点,第二层为分块LOD的第一层数据:

osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(path);
osg::ref_ptr<osg::PagedLOD> lod = new osg::PagedLOD(); auto bs = node->getBound();
auto c = bs.center();
auto r = bs.radius();
lod->setCenter(c);
lod->setRadius(r);
lod->setRangeMode(osg::LOD::RangeMode::PIXEL_SIZE_ON_SCREEN);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->getOrCreateStateSet();
lod->addChild(geode.get()); std::string relativeFilePath = "./Data/" + name + "/" + name + ".osgb"; //相对路径 lod->setFileName(0, "");
lod->setFileName(1, relativeFilePath); lod->setRange(0, 0, 1.0); //第一层不可见
lod->setRange(1, 1.0, FLT_MAX); lod->setDatabasePath(""); group->addChild(lod);

LOD的Center和Radius都非常重要,需要预先设置好;setRangeMode设置了细节层级调度的模式,一般都为PIXEL_SIZE_ON_SCREEN;setFileName设置了每一层的数据路径,setRange确定了当前层级的范围。由于这个LOD只是个索引文件,所以会设置第二层为极大的可见范围值。

3. 结果

可以像加载普通OSGB文件一样加载这个索引文件,通过osgviewer加载的效果如下:

OSG加载倾斜摄影数据的更多相关文章

  1. Cesium加载倾斜摄影数据

    (1)倾斜摄影数据仅支持 smart3d 格式的 osgb 组织方式, 数据目录必须有一个 “Data” 目录的总入口, “Data” 目录同级放置一个 metadata.xml 文件用来记录模型的位 ...

  2. osg gdal加载tif数据文件

    osg加载.tif地形数据文件 #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <iostream> ...

  3. geotrellis使用(二十三)动态加载时间序列数据

    目录 前言 实现方法 总结 一.前言        今天要介绍的绝对是华丽的干货.比如我们从互联网上下载到了一系列(每天或者月平均等)的MODIS数据,我们怎么能够对比同一区域不同时间的数据情况,采用 ...

  4. WPF DataGrid 性能加载大数据

    WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系 ...

  5. 基于zepto的H5/移动端tab切换触摸拖动加载更多数据

    以前实现移动端的滑动加载更多实现的方法是当滚动条快到页面底部时就自动加载更多的数据,在这方面很多人都用的是"西门的后花园"写的一个叫dropload的插件,这个插件用起来也很好,很 ...

  6. iOS --- UIWebView的加载本地数据的三种方式

    UIWebView是IOS内置的浏览器,可以浏览网页,打开文档  html/htm  pdf   docx  txt等格式的文件.  safari浏览器就是通过UIWebView做的. 服务器将MIM ...

  7. jQuery.ajax( options ) : 通过 HTTP 请求加载远程数据

    jQuery.ajax( options ) : 通过 HTTP 请求加载远程数据 这个是jQuery 的底层 AJAX 实现.简单易用的高层实现见 $.get, $.post 等. $.ajax() ...

  8. Tree:加载列表数据

    Tree控件,需要提供一个树形的JSON数据,才能正常显示. 通常,开发者在后台可以这样做: 1)从数据库查询出一个列表数据 2)在后台,将列表数据转换为树形数据 3)通过JSON方式返回 在前台页面 ...

  9. 实现winform DataGridView控件判断滚动条是否滚动到当前已加载的数据行底部

    判断 DataGridView控件滚动条是否滚动到当前已加载的数据行底部,其实方法很简单,就是为DataGridView控件添加Scroll事件,然后写入以下代码就可以了,应用范围:可实现分部加载数据 ...

随机推荐

  1. python:匿名函数lambda

    看个例子: a=list(map(lambda x:x*x,(1,2,3))) print(a) 输出:[1, 4, 9] lambda实际上就是匿名函数,相当于: def f(x): return ...

  2. Three.js 中的参数调试控制插件dat.GUI.JS - [Three.js] - [dat.GUI]

    不论是处于特殊功能的需要,还是处于效果调试方便,我们可能都需要修改模型中的参数值.在Three.js中,谷歌提供了一个js库,即dat.GUI.js用于处理这种需求. 通过该库,我们就不需要通过手动修 ...

  3. CountDownLatch是个啥?

    文章篇幅较短,对于一些AQS的顶级方法例如releaseShared并没有做过深的讲解,因为这些算是AQS的范畴,关于AQS可以看下另一篇文章--AQS.  CountDownLatch一般被称作&q ...

  4. 【Linux】nginx服务配置

    一. 部署LNMP环境 准备工作 Linux系统准备 设置IP 关闭防火墙 yum源配置 安装: 传输软件包 1. tar -zxvf lnmp1.2-full.tar.gz cd lnmp1.2-f ...

  5. python通过pymysql实现数据库的增删改查

    今天实现了python对于数据库的增删改查工作: 具体的每一步的数据库的增删盖茶自己都实验过了. 掌握了基本的数据库操作语言.然后就是对于tuple()的认识. 以及对于查询语句中的:fetchone ...

  6. webpack中引用jquery

    1.首先需要添加项目中jquery的依赖 npm install jquery --save-dev 2.参考配置代码: var webpack = require("webpack&quo ...

  7. Linux基础管理篇,软件管理程序,yum与rpm

    一.RPM 一般来说,rpm类型的文件在安装的时候,会检测当前的系统是否满足当前软件需要的环境.若符合,则该软件就会被安装,并且会把软件的相关信息写入/var/lib/rpm/目录下的数据库文件中. ...

  8. Docker php安装扩展步骤详解

    前言 此篇,主要是演示docker-php-source , docker-php-ext-install ,docker-php-enable-docker-configure 这四个命令到底是用来 ...

  9. 011-指针(上)-C语言笔记

    011-指针(上)-C语言笔记 学习目标 1.[掌握]字符串常用函数 2.[掌握]指针变量的声明 3.[掌握]指针变量的初始化 4.[掌握]函数与指针 5.[掌握]指针的数据类型 6.[掌握]多级指针 ...

  10. php.ini中文详解

    [PHP] ;;;;;;;;;;;;;;;;;;;;;;; ; 关于 php.ini 配置文件 ; ;;;;;;;;;;;;;;;;;;;;;;; ; PHP 的初始化文件, 必须命名为 php.in ...