osgEarth示例分析——osgearth_srstest

前言

osgearth_srstest示例,主要涉及到两个坐标系转换,wgs84→egm96  wgs84→plate-carre

wgs84:World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统。导航系统、GPS系统,都在使用此坐标。

egm96:EGM9模型是美国bai推出的一种适用于全球范围,并综合利用现有全球大量重力数据所计算出来的高精度大地水准面模型。但是因其发布年代较早并且缺乏中国地区重力数据所以高程转换精度较低,难以满足工程测量需要。而近年来由美国NGA重力场研发小组发布了EGM2008大地水准面模型,改善了这一情况。

plate-carre:简易圆柱投影是一种等距圆柱投影,其标准纬线位于赤道处。 经纬线的格网从东到西并从极点到极点形成完美的方形。(此链接实为宝藏,对于不理解各种坐标和投影关系的小伙伴,特别有帮助)

// cmd 命令框 输入以下代码:
osgearth_srstestd.exe

执行结果

Convert geodetic Z to EGM96: transform succeed for texst #output[0]: 0, 0, 1.5258789076710854715202e-07
Convert geodetic Z to EGM96: output doesn't match for test #1; expected Z=0, got Z=-0.0100004577636738645196601
Convert geodetic Z to EGM96: transform succeed for texst #output[2]: 180, 0, 3.814697251414145284798e-07
Convert geodetic Z to EGM96: transform succeed for texst #output[3]: -90, 0, -0.00999979019165042615213679
Convert geodetic Z to EGM96: output doesn't match for test #4; expected Z=0, got Z=44.06999969482421875

result = -20037508.3427892476320267, -10018754.1713946219533682, 0
result = -20037508.3427892476320267, 10018754.1713946219533682, 0
result = 20037508.3427892476320267, -10018754.1713946219533682, 0
result = 20037508.3427892476320267, 10018754.1713946219533682, 0
result = 10018754.1713946238160133, 3339584.72379820747300982, 1000

根据执行结果猜测:第一种转换是为了验证两种坐标系获取的同一位置高程值是否相同。

第二种转换,猜测是将椭球投影后,在平面上,获取XY的位置,Z值意义不大。毕竟投影后就不关心高程值了。

代码分析

#include <osgEarth/SpatialReference>
#include <osgEarth/StringUtils>
#include <osgEarth/Profile>
#include <iostream>

bool eq(const double& a, const double& b, double e =1e-6) {
    return fabs(a - b) <= e;
}

bool eq(const osg::Vec3d& a, const osg::Vec3d& b, double e =1e-6) {
    return fabs(a.x() - b.x()) <= e && fabs(a.y() - b.y()) <= e && fabs(a.z() - b.z()) <= e;
}

int fail(const std::string& test, const std::string& msg) {
    std::cout << test << ": " << msg << std::endl;
    return -1;
}

int
main(int argc, char** argv)
{
    using namespace osgEarth;

    std::string test;

    // Vertical datum tests.
    // Reference: http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/intpt.html
    {
		// wgs84坐标 转换到 EGM96坐标。这是两个不同的坐标系统。
		// 在osgearth中,还有epsg:4326 plate-carre
        test = "Convert geodetic Z to EGM96";
        const SpatialReference* wgs84 = SpatialReference::get("wgs84");
        const SpatialReference* wgs84_egm96 = SpatialReference::get("wgs84", "egm96");        
        osg::Vec3d input[5] = {
            osg::Vec3d( 0,  0,  17.16),// 赤道上的点
            osg::Vec3d( 90, 0, -63.24),
            osg::Vec3d(180, 0,  21.15),
            osg::Vec3d(-90, 0,  -4.29),
			osg::Vec3d(90,30,10)// 一般值测试
        };
        osg::Vec3d output;
        for (int i = 0; i<5; ++i) {
            osg::Vec3d output;
            if (!wgs84->transform(input[i], wgs84_egm96, output))
                std::cout << test << ": transform failed for texst #" << i << std::endl;
            else if (!eq(output.z(), 0.0, 0.01)) { // 判断转换后的值,高度z是否为0
                std::cout << test << ": output doesn't match for test #" << i << "; expected Z=0, got Z=" << output.z() << std::endl;
			}
			else
			{	
				// 转换成功
				std::cout << test << ": transform succeed for texst #output[" << i <<"]: "<<
					std::setprecision(24) << output.x() << ", " << output.y() << ", " << output.z() << std::endl;
			}
        }
    }
	std::cout << std::endl;
    // Plate Carre EQC Test.
    {
		// plate-carre: WGS84 projected flat (X=longitude, Y=latitude),WGS84投影平面
        test = "Plate Carre EQC Test";
        const SpatialReference* wgs84 = SpatialReference::get("wgs84");
        const SpatialReference* pceqc = SpatialReference::get("plate-carre");// 二维坐标
        osg::Vec3d input[5] = {
            osg::Vec3d(-180, -90, 0),// 极值测试
            osg::Vec3d(-180, +90, 0),
            osg::Vec3d( 180, -90, 0),
            osg::Vec3d( 180, +90, 0),
			osg::Vec3d(90,30,1000)// 一般值测试
        };
        osg::Vec3d output;
        for (int i = 0; i<5; ++i) {
            osg::Vec3d output;
            if (!wgs84->transform(input[i], pceqc, output)) {
                std::cout << test << ": transform failed for test #" << i << std::endl;
            }
            else  {
                std::cout << "result = " << std::setprecision(24) << output.x() << ", " << output.y() << ", " << output.z() << std::endl;
            }
        }
    }

    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是在 Visual Studio 2022 中使用 osgEarth示例: 1. 安装 osgEarth 首先需要在你的系统中安装 osgEarth。可以从官网下载安装包进行安装,也可以使用 CMake 进行源码编译安装。 2. 创建一个 osgEarth 应用程序 在 Visual Studio 2022 中创建一个新的 C++ 控制台应用程序项目。然后,将 osgEarth 的 include 和 library 路径添加到项目中: - 右键单击项目,选择“属性”。 - 在“VC++ 目录”中添加包含路径和库路径。 - 在“链接器 -> 输入”中添加 osgEarth 的库文件。 3. 创建一个 osgEarth 地图节点 在应用程序中创建一个 osgEarth 地图节点,并将其添加到场景图中: ```cpp #include <osgEarth/MapNode> #include <osgEarthUtil/EarthManipulator> int main(int argc, char** argv) { // 初始化 osgEarthosgEarth::initialize(); // 创建一个 osgEarth 地图节点 osg::ref_ptr<osgEarth::MapNode> mapNode = osgEarth::MapNode::create(osgEarth::MapNodeOptions()); // 创建一个 osgEarth 视图并添加地图节点 osg::ref_ptr<osgViewer::View> view = new osgViewer::View; view->setSceneData(mapNode); // 设置地球操纵器 osg::ref_ptr<osgEarth::Util::EarthManipulator> manipulator = new osgEarth::Util::EarthManipulator; view->setCameraManipulator(manipulator); // 显示视图 osgViewer::Viewer viewer; viewer.addView(view); return viewer.run(); } ``` 以上代码创建了一个 osgEarth 地图节点,并使用 EarthManipulator 对其进行控制。注意要在程序结束前调用 osgEarth::shutdown(),以释放资源。 4. 运行应用程序 点击“生成”按钮编译应用程序,并运行应用程序。如果一切正常,应该可以看到一个 osgEarth 地球视图。 以上是在 Visual Studio 2022 中使用 osgEarth 的简单示例。根据需要,还可以使用 osgEarth 的其他功能来创建更复杂的地图应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值