OSG加载倾斜摄影数据
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加载倾斜摄影数据的更多相关文章
- Cesium加载倾斜摄影数据
(1)倾斜摄影数据仅支持 smart3d 格式的 osgb 组织方式, 数据目录必须有一个 “Data” 目录的总入口, “Data” 目录同级放置一个 metadata.xml 文件用来记录模型的位 ...
- osg gdal加载tif数据文件
osg加载.tif地形数据文件 #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <iostream> ...
- geotrellis使用(二十三)动态加载时间序列数据
目录 前言 实现方法 总结 一.前言 今天要介绍的绝对是华丽的干货.比如我们从互联网上下载到了一系列(每天或者月平均等)的MODIS数据,我们怎么能够对比同一区域不同时间的数据情况,采用 ...
- WPF DataGrid 性能加载大数据
WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系 ...
- 基于zepto的H5/移动端tab切换触摸拖动加载更多数据
以前实现移动端的滑动加载更多实现的方法是当滚动条快到页面底部时就自动加载更多的数据,在这方面很多人都用的是"西门的后花园"写的一个叫dropload的插件,这个插件用起来也很好,很 ...
- iOS --- UIWebView的加载本地数据的三种方式
UIWebView是IOS内置的浏览器,可以浏览网页,打开文档 html/htm pdf docx txt等格式的文件. safari浏览器就是通过UIWebView做的. 服务器将MIM ...
- jQuery.ajax( options ) : 通过 HTTP 请求加载远程数据
jQuery.ajax( options ) : 通过 HTTP 请求加载远程数据 这个是jQuery 的底层 AJAX 实现.简单易用的高层实现见 $.get, $.post 等. $.ajax() ...
- Tree:加载列表数据
Tree控件,需要提供一个树形的JSON数据,才能正常显示. 通常,开发者在后台可以这样做: 1)从数据库查询出一个列表数据 2)在后台,将列表数据转换为树形数据 3)通过JSON方式返回 在前台页面 ...
- 实现winform DataGridView控件判断滚动条是否滚动到当前已加载的数据行底部
判断 DataGridView控件滚动条是否滚动到当前已加载的数据行底部,其实方法很简单,就是为DataGridView控件添加Scroll事件,然后写入以下代码就可以了,应用范围:可实现分部加载数据 ...
随机推荐
- IntelliJ IDEA 激活码 [已购买,分享给码友]
一.前言 笔者在网上找了一圈,各种方法都试过了,之前那种在网上随便找个注册码,过了一段时间就被封了,想了想还是经常用的和朋友一起购买了,方便日后使用 二.下载最新的 IDEA 其实也可以从老版本直接升 ...
- 《Three.js 入门指南》2.3.1- 照相机 - 正交投影demo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Blocked Billboard II题解--模拟到崩溃的模拟
前言 比赛真的状态不好(腐了一小会),导致差点爆0. 这个题解真的是在非常非常专注下写出来的,要不然真的心态崩. 题目 题目描述 奶牛Bassie想要覆盖一大块广告牌,她在之前已经覆盖了一小部分广告牌 ...
- Linux:启动http服务
1.安装apache yum install httpd #根据提示,输入Y安装即可成功安装 systemctl start httpd.service #启动apache systemctl sto ...
- 基于redis的订单号生成方案
目前,比较火的nosql数据库,如MongoDB,Redis,Riak都提供了类似incr原子行操作. 下面是PHP版的一种实现方式: <?php /** * 基于Redis的全局订单号id * ...
- 【php】PDO
一.PDO的定义 1.pdo(php data object)是一个数据库的抽象层 二.PDO的特点 1.跨数据库 2.支持预处理 3.支持事务处理 三.PDO的使用 1.基本使用 (1)实例化pdo ...
- zabbix模板的自动发现规则(ldd)实现被监控项自动发现
zabbix模板的自动发现规则(ldd)实现被监控项自动发现 自动发现规则(ldd)用途说明 在zabbix自带的linux模板的自动发现规则中,有一个Mounted filesystem disco ...
- 数据结构篇-数组(TypeScript版+Java版)
1.TypeScript版本 export default class MyArray<E> { public data: E[]; public size: number = 0; /* ...
- Markdown自动生成目录
Markdown自动生成目录 使用npm语法生成 1.安装npm 2.安装doctoc插件 3.执行生成 参考 Markdown自动生成目录 使用npm语法生成 1.安装npm 我的系统是deepin ...
- Java编程最差实践常见问题详细说明(1)转
Java编程最差实践常见问题详细说明(1)转 原文地址:http://www.odi.ch/prog/design/newbies.php 每天在写Java程序, 其实里面有一些细节大家可能没 ...