osgEarth支持.earth格式的文件,里面保存了数字地球相关信息的配置XML,只须要读取这个配置文件,就能够直接获得相应的数字地球相关效果。但实际使用中仍是感受到有些不便,有些效果没办法保存下来,因此不少时候仍是使用代码实现比较好。osgEarth最基础的就是显示一个数字地球了。html
具体的实现代码以下:ios
#include <Windows.h> #include <iostream> #include <string> #include <osgViewer/Viewer> #include <osgDB/ReadFile> #include <osgEarth/MapNode> #include <osgEarthDrivers/gdal/GDALOptions> #include <osgEarthDrivers/cache_filesystem/FileSystemCache> #include <osgEarth/ImageLayer> #include <osgEarthUtil/EarthManipulator> using namespace std; int main() { osgEarth::ProfileOptions profileOpts; //地图配置:设置缓存目录 osgEarth::Drivers::FileSystemCacheOptions cacheOpts; string cacheDir = "D:/Work/OSGNewBuild/tmp"; cacheOpts.rootPath() = cacheDir; // osgEarth::MapOptions mapOpts; mapOpts.cache() = cacheOpts; mapOpts.profile() = profileOpts; //建立地图节点 osg::ref_ptr<osgEarth::Map> map = new osgEarth::Map(mapOpts); osg::ref_ptr<osgEarth::MapNode> mapNode = new osgEarth::MapNode(map); osgEarth::Drivers::GDALOptions gdal; gdal.url() = "D:/Work/OSGNewBuild/osgearth-2.10.1/data/world.tif"; osg::ref_ptr<osgEarth::ImageLayer> layer = new osgEarth::ImageLayer("BlueMarble", gdal); map->addLayer(layer); osgViewer::Viewer viewer; viewer.setSceneData(mapNode); osg::ref_ptr< osgEarth::Util::EarthManipulator> mainManipulator = new osgEarth::Util::EarthManipulator; viewer.setCameraManipulator(mainManipulator); viewer.setUpViewInWindow(100, 100, 800, 600); return viewer.run(); }
这里有两个点值得注意,其一是使用了缓存机制,能够在浏览的时候变浏览边生成缓存,因此设置了一个缓存目录;其二是加载了一个底图数据,是osgEarth中自带的。运行的效果以下:web
除了显示三维数字地球以外,osgEarth其实还能够显示成平面地图,只须要设置具体的参数就能够了。例如这里显示成web墨卡托投影的二维平面地图:缓存
#include <Windows.h> #include <iostream> #include <string> #include <osgViewer/Viewer> #include <osgDB/ReadFile> #include <osgEarth/MapNode> #include <osgEarthDrivers/gdal/GDALOptions> #include <osgEarthDrivers/cache_filesystem/FileSystemCache> #include <osgEarth/ImageLayer> #include <osgEarthUtil/EarthManipulator> #include <gdal_priv.h> using namespace std; int main() { CPLSetConfigOption("GDAL_DATA", "D:/Work/OSGNewBuild/OpenSceneGraph-3.6.4/3rdParty/x64/gdal-data"); string wktString = "EPSG:3857"; //web墨卡托投影 //string wktString = "EPSG:4326"; //wgs84 osgEarth::ProfileOptions profileOpts; profileOpts.srsString() = wktString; //osgEarth::Bounds bs(535139, 3365107, 545139, 3375107); //osgEarth::Bounds bs(73, 3, 135, 53); //profileOpts.bounds() = bs; //地图配置:设置缓存目录 osgEarth::Drivers::FileSystemCacheOptions cacheOpts; string cacheDir = "D:/Work/OSGNewBuild/tmp"; cacheOpts.rootPath() = cacheDir; // osgEarth::MapOptions mapOpts; mapOpts.cache() = cacheOpts; mapOpts.coordSysType() = osgEarth::MapOptions::CSTYPE_PROJECTED; mapOpts.profile() = profileOpts; //建立地图节点 osg::ref_ptr<osgEarth::Map> map = new osgEarth::Map(mapOpts); osg::ref_ptr<osgEarth::MapNode> mapNode = new osgEarth::MapNode(map); osgEarth::Drivers::GDALOptions gdal; gdal.url() = "D:/Work/OSGNewBuild/osgearth-2.10.1/data/world.tif"; osg::ref_ptr<osgEarth::ImageLayer> layer = new osgEarth::ImageLayer("BlueMarble", gdal); map->addLayer(layer); osgViewer::Viewer viewer; viewer.setSceneData(mapNode); osg::ref_ptr< osgEarth::Util::EarthManipulator> mainManipulator = new osgEarth::Util::EarthManipulator; viewer.setCameraManipulator(mainManipulator); viewer.setUpViewInWindow(100, 100, 800, 600); return viewer.run(); }
Web墨卡托投影平面坐标系的EPSG代码是3857,因此只须要直接传入相应的代码就好了。对于比较复杂或者自定义的坐标系,其实也能够直接传入wkt字符串,由于osgEarth是经过GDAL来处理空间坐标参考的,GDAL又是经过proj4来处理空间坐标参考的,因此这个时候须要经过GDAL设置一下环境变量GDAL_DATA(具体能够参见《GDAL坐标转换》)。ui
显示的效果以下所示:
url
显然,跟Web墨卡托投影的特性同样,椭球被投影成了方形的平面地图。spa