关于osgEarth中的空间参考系的一些理解

文章详细解释了osgEarth中的SpatialReference类,以及空间参考系的基本内容,包括坐标系的选择(地理、投影、地心)和水平、垂直基准面的选择。geocentric指的是地心坐标系,常用于表示地固系的X,Y,Z坐标。同时,文章提到了WGS84作为默认的水平基准,并讨论了不同坐标系之间的转换和组合可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在利用osgEarth进行开发的过程中,尤其是在编写*.earth的过程中,如下:

<map name="test" type="geocentric">
	………………
</map>

你可能会出现跟我类似的疑惑,这个geocentric,到底是个什么东西。
通过翻阅osgEarth2.10的帮助文档(帮助文档是个好东西),会发现这么一个类osgEarth::SpatialReference,顾名思义,翻译成中文,就是空间参考。你还会发现一个出现频率很高的英文缩写,SRS,即Spatial Reference System,即空间参考系。找到这个,就有眉目了。

如何确定一个空间参考系

1 空间参考系应该包含的基本内容

1.1 坐标系的选择

1.2 水平和垂直基准面的选择

2 一些个人理解


1 空间参考系应该包含的基本内容

首先强调一点,一个完整的空间参考系,他应该至少要确定两部分内容:

  1. 坐标系的选择。
  2. 水平和垂直基准面的选择。

因此,确定一个完整的空间参考系,首要的就是解决这两个问题。
坐标系的选择,决定了空间某点位置的表示方式,即用BLH或者XYZ或者XY的表示方式
水平和垂直基准面的选择,确定了该点的值的起算基准,即坐标系的原点的位置和高程的起算位置。

1.1 坐标系的选择

翻阅osgEarth::SpatialReference类,可以发现很多有意思的东西:

virtual bool  isGeographic () const 
//True if this is a geographic SRS (lat/long/msl)  
virtual bool  isGeodetic () const  
//True if this is a geodetic SRS (lat/long/hae) 
virtual bool  isProjected () const  
//True if this is a projected SRS (i.e. local coordinate system) 
virtual bool  isGeocentric () const   
//True if this is a planet-centered system (geocentric/meters) 

const SpatialReference * SpatialReference::getECEF() const 
//弃用:after 2.10 - call getGeocentricSRS() instead 

看到这四个函数,以及通过下面的注释,思路就清晰了。
我们先弄清楚,注释中括号里的内容的含义。
lat:纬度
long:经度
msl:距平均海平面高度,即海拔,对应大地水准面
hae:距离参考椭球体的高度,对应参考椭球
geocentric:geocentric coordinate system ,地心坐标系
meters:单位,米
如此一来,我们就清楚了,这个SRS类支持的几种坐标系:

地理坐标系(Geographic):以实现通过经纬度对地球表面点位引用的坐标系。表现形式为,B代表经度,L代表纬度,H代表高程。(B,L,H)。
投影坐标系(Projected):投影坐标系使用基于X,Y值的坐标系统来描述地球上某个点所处的位置,我们截取图片时,就是在投影坐标系。表示形式为(X,Y)。
地心地固坐标系(Geocentric):而根据getECEF()函数,可以确定,这里的geocentric,指的是地固系,即基于X,Y,Z值的坐标系统来描述地球上某个点所处的位置。表现形式为(X,Y,Z)。

1.2 水平和垂直基准面的选择

水平基准面,就是对应的参考椭球的参数(定位和定向),一般就是从参心椭球质心椭球之中选择,54和80的椭球定义就是参心椭球,而WGS84CGCS2000就是质心椭球,osgEarth应该默认的WGS84的。
垂直基准面,主要包含的是所谓的大地高(物体到椭球的法线距离)和正高(垂线到大地水准面的距离)
翻阅资料,github上的用户指南

Horizontal Datum
A datum is a reference point (or set of points) against which geospatial measurements are made. The same location on earth can have different coordinates depending on which datum is in use. There are two classes of datum:
A horizontal datum measures positions on the earth. Since the earth is not a perfect sphere or even a perfect ellipsoid, particular datums are usually designed to approximate the shape of the earth in a particular region. Common datums include WGS84 and NAD83 in North America, and ETR89 in Europe.
Vertical Datum
A vertical datum measures elevation. There are several classes of vertical datum; osgEarth supports geodetic (based on an ellipsoid) and geoid (based on a sample set of elevation points around the planet).
osgEarth has the following vertical datums built in:
Geodetic - the default; osgEarth uses the Horizontal datum ellipsoid as a reference
EGM84 geoid
EGM96 geoid - commonly called MSL; used in DTED and KML
EGM2008 geoid
By default, SRS’s in osgEarth use a geodetic vertical datum; i.e., altitude is measured as “height above ellipsoid (HAE)”.

上述内容翻译成中文:

水平基准
基准是针对其地理空间测量制成的参考点(或一组点)。地球上的同一位置可能具有不同的坐标,具体取决于使用的数据。有两类数据:
一个水平基准测量地球上的位置。由于地球不是一个完美的球体,甚至不是一个完美的椭球体,因此通常设计特定的基准面来近似特定区域中地球的形状。常见的基准面包括北美的WGS84和NAD83,以及 欧洲的ETR89。
垂直基准
一个垂直基准措施提升。有几类垂直基准;osgEarth 支持大地测量(基于椭球)和大地水准面(基于地球周围高程点的样本集)。
osgEarth 内置了以下垂直基准:
大地测量 - 默认;osgEarth 使用水平基准椭球作为参考
EGM84大地水准面
EGM96 大地水准面 - 通常称为MSL;在 DTED 和 KML 中使用
EGM2008大地水准面
默认情况下,osgEarth 中的 SRS 使用大地垂直基准;即,高度被测量为“椭球以上的高度(HAE)”。

根据上述内容,就很明确了,在默认的情况下,垂直基准为大地高程,而水平基准,是质心椭球

2 一些个人理解

      1. 地心坐标系,包含空间直角坐标系以及大地坐标系,其实质为,是以地心为质心的坐标系,都可以认为是地心坐标系。因此,地心坐标系,有两种表现形式,即一个点,在地心坐标系中,有即(X,Y,Z)和(B,L,H)两种表示方法。如图所示:

  2.一种坐标系可能归类到几种坐标系中。比如WGS84,当他是大地坐标系时,他也属于地理坐标系,最直观的原因就是,也用(B,L,N)表示,因此WGS也是参考椭球的一种。但是WGS84同时,也可以转换成(X,Y,Z)的表示方法,这个时候,他就是空间直角坐标系。

  3.在第一部分中,讲到有坐标系和水平、垂直基准面的选择,选择之间,并无绝对的关联,可以进行部分组合,会出现不同的搭配。

  4. 因此,关于文章开头的问题,可以给出答案,在osgEarth中,type="geocentric",意思是该部分影像使用的坐标系为地固系坐标系,即地心为质心的空间直角坐标系。

  5. 你在截取影像的时候,都是在投影的情况下截取的,所以可以看到,投影的横纵坐标,仍旧用经纬度的方式表示,这个时候的经纬度即他自带的参考椭球的经纬度值,如WGS84,这个时候他对应的值,即为该点高程,这个高程在参考椭球下,当然就是大地高程。

  6.因此,在读取WGS84的srtm数据时,可以设置为+proj=latlong +datum=WGS84(猜测,还没试过),直接读取为(B,L,H)值。也可以设置为type="geocentric"(因为同为地心为坐标系质心),直接读取后,转变为空间直接坐标系的(X,Y,Z)值。

<think>嗯,用户想找关于使用osgEarth实现贴地面绘制的方法或教程。首先,我需要回忆一下osgEarth的相关知识。osgEarth是基于OpenSceneGraph的一个地理空间SDK,主要用于三维地球应用的开发。贴地面绘制通常指的是将图像或几何体准确地贴合到地形表面,避免漂浮或穿透的问题。 用户提到的引用中有一个是关于在osgEarth上实时显示无人机传回的图片,这可能涉及到动态纹理贴图或者投影技术。另外,引用中提到了Qt中使用OpenGL和贴图的方法,但用户的问题更偏向于osgEarth的具体实现。 首先,我应该考虑贴地面绘制的常见方法。可能的方法包括使用osgEarth的投影坐标系,确保添加的节点与地形正确对齐。另外,osgEarth的FeatureNode可以用来绘制矢量数据,可能会用到。地形匹配技术如高程查询也是关键,可能需要实时获取高程数据来调整位置。 然后,教程方面,用户提供的引用[^2]提到了lesson01,是关于实时显示无人机图片的,这可能是一个实际的例子。需要结合这个例子,说明如何将图片贴到地形上。此外,可能还需要参考osgEarth的官方文档和示例,比如处理坐标系、使用地形遮挡、动态更新纹理等。 用户可能需要具体的步骤,比如设置地图的坐标系,创建FeatureNode,使用高程查询等。代码示例可能有助于用户理解,比如如何创建图像覆盖层,如何设置投影参数,或者如何动态更新位置。 此外,用户可能遇到的问题包括性能优化、动态数据的实时处理和坐标转换的精度问题。需要提醒用户注意地形数据的细节层次和坐标系的一致性,避免渲染错误。 最后,生成的相关问题需要围绕用户的需求扩展,比如如何优化性能、如何处理动态数据、如何结合其他库如GDAL进行数据处理,以及如何实现交互编辑功能。这些问题可以帮助用户更深入地理解和应用贴地面绘制技术。</think>### osgEarth实现贴地面绘制的方法及教程 #### 一、核心实现原理 1. **坐标系匹配**:需使用$map\_SRS$(地图空间参考系统)确保绘制对象与地形坐标系一致,避免偏移 2. **地形匹配技术**:通过高程查询接口$getHeight()$获取地形表面高程值,公式可表示为: $$ z = f(x,y) + \Delta h $$ 其中$\Delta h$为人工设定的贴地偏移量[^2] 3. **渲染策略**:使用$osg::Depth$测试确保绘制对象与地形表面精确贴合,防止Z-fighting现象 #### 二、具体实现步骤 ```cpp // 创建贴地图像层 osgEarth::ImageLayer* imageLayer = new osgEarth::ImageLayer(); imageLayer->setURL("path/to/georeferenced_image.tif"); // 需包含地理坐标信息的图像 // 设置投影参数 osgEarth::TileLayerOptions opt; opt.profile() = osgEarth::ProfileOptions("global-geodetic"); // 使用WGS84坐标系 // 创建地形匹配节点 osgEarth::FeatureNode* featureNode = new osgEarth::FeatureNode(mapNode); featureNode->setStyle(osgEarth::Style()); // 设置样式参数 featureNode->attachTo(mapNode); // 关联到地图节点 ``` #### 三、关键优化技术 1. **LOD控制**:根据视点距离动态调整绘制精度 ```cpp osg::LOD* lod = new osg::LOD(); lod->addChild(highDetailModel, 0.0, 10000.0); // 10公里内显示高模 lod->addChild(lowDetailModel, 10000.0, 50000.0); // 10-50公里显示低模 ``` 2. **动态更新机制**:通过回调函数实时更新位置 ```cpp class TerrainCallback : public osg::NodeCallback { public: virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { osgEarth::GeoPoint position = /* 获取最新位置 */; mapNode->getMap()->getProfile()->getSRS()->transform(...); } }; ``` #### 四、注意事项 1. 地形数据精度应不低于$0.5m$时才能保证亚米级贴合效果 2. 建议使用$osgEarth::Drivers::GDAL$插件处理地理空间数据 3. 需处理坐标系转换时的浮点精度误差,推荐使用双精度计算
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值