osgearth加载mapbox在线高程数据
先看一下效果:
osgearth加載在線地圖這里就不介紹了,比如osm、mapbox、天地圖等,如果有哪位同學需要,我可以下次介紹一下~~~
眾所周知,高程數據一直是比較珍貴的,之前是加載谷歌地球的高程,但是近期由于谷歌地址均無法訪問,所以考慮加載mapbox的在線高程數據,說到這里,不得不感謝一下mapbox,不僅提供了豐富的可編輯的在線地圖數據,還提供了高程數據~~~??Maps, geocoding, and navigation APIs & SDKs | Mapbox
首先先看一張mapbox的高程圖:
可以看到,mapbox的高程數據數據是rgba四通道的png格式柵格圖像數據,而一般的高程數據HeightField是單通道的,
因此,在請求到源數據之后只需要做一次osg::Image -> osg::HeightField?的轉換即可。
轉換公式官網就有,很貼心:
height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)通過繼承?TileSource?重寫?createImage?和?createHeightField 即可實現功能,繼承了QObject是想后續完善功能,將數據保存至數據庫中,便于后續離線讀取,QObject可有可無,詳細可參考 Plugin osgearth_tileindex:
using namespace osgEarth; using namespace osgEarth::Drivers;class XYZExSource : public QObject, public TileSource {Q_OBJECTpublic:XYZExSource(const TileSourceOptions& options);Status initialize(const osgDB::Options* dbOptions);osg::Image* createImage(const TileKey& key, ProgressCallback* progress);virtual std::string getExtension() const{return _format;}osg::HeightField* createHeightField(const TileKey& key, ProgressCallback* progress); private:const XYZExOptions _options;std::string _format;std::string _template;std::string _rotateChoices;std::string _rotateString;std::string::size_type _rotateStart, _rotateEnd;OpenThreads::Atomic _rotate_iter;osg::ref_ptr<osgDB::Options> _dbOptions; };createImage函數與xyz驅動基本一致,照抄即可,這里介紹createHeightField函數:
osg::HeightField* XYZExSource::createHeightField(const TileKey& key, ProgressCallback* progress) {// MapBox encoded elevation PNG.// https://www.mapbox.com/blog/terrain-rgb/if (1/*_options.elevationEncoding().value() == "mapbox"*/){if (getStatus().isError())return 0L;osg::HeightField *hf = 0;osg::ref_ptr<osg::Image> image = createImage(key, progress);if (image.valid()){// Allocate the heightfield.hf = new osg::HeightField();hf->allocate(image->s(), image->t());ImageUtils::PixelReader reader(image.get());for (unsigned int c = 0; c < image->s(); c++){for (unsigned int r = 0; r < image->t(); r++){osg::Vec4 pixel = reader(c, r);pixel.r() *= 255.0;pixel.g() *= 255.0;pixel.b() *= 255.0;float h = -10000.0f + ((pixel.r() * 256.0f * 256.0f + pixel.g() * 256.0f + pixel.b()) * 0.1f);hf->setHeight(c, r, h);}}}return hf;}else{return TileSource::createHeightField(key, progress);} }使用:
osgEarth::Drivers::XYZExOptions exyz; exyz.url() = "http://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token=pk.eyJ1IjoicnpvbGxlciIsImEiOiIzQ1V3clI4In0.2TF5_QTXSR3T7F_dyPd1rg"; exyz.profile()->namedProfile() = "spherical-mercator"; XYZExSource* etileSource = new XYZExSource(exyz); auto eStatus = etileSource->open(); ElevationLayerOptions eoptions("mapboxEle"); map->addLayer(new ElevationLayer(eoptions, etileSource));access_token可在mapbox官網自行申請~~~
總結
以上是生活随笔為你收集整理的osgearth加载mapbox在线高程数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tree 命令
- 下一篇: BUUCTF-Crypto-rabbit