📄 readerwritergdal.cpp
字号:
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2007 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details.*/#include <osg/Image>#include <osg/Notify>#include <osg/Geode>#include <osg/GL>#include <osgDB/Registry>#include <osgDB/FileNameUtils>#include <osgDB/FileUtils>#include <osgDB/ImageOptions>#include <OpenThreads/ScopedLock>#include <OpenThreads/ReentrantMutex>#include <memory>#include <gdal_priv.h>#include "DataSetLayer.h"#define SERIALIZER() OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex) // From easyrgb.comfloat Hue_2_RGB( float v1, float v2, float vH ){ if ( vH < 0 ) vH += 1; if ( vH > 1 ) vH -= 1; if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH ); if ( ( 2 * vH ) < 1 ) return ( v2 ); if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 ); return ( v1 );}class ReaderWriterGDAL : public osgDB::ReaderWriter{ public: ReaderWriterGDAL() { supportsExtension("gdal","GDAL Image reader"); } virtual const char* className() const { return "GDAL Image Reader"; } virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const { if (osgDB::equalCaseInsensitive(osgDB::getFileExtension(file),"gdal")) { return readObject(osgDB::getNameLessExtension(file),options); } OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex); std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; initGDAL(); // open a DataSetLayer. osg::ref_ptr<GDALPlugin::DataSetLayer> dataset = new GDALPlugin::DataSetLayer(fileName); dataset->setGdalReader(this); if (dataset->isOpen()) return dataset.release(); return ReadResult::FILE_NOT_HANDLED; } virtual ReadResult readImage(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const { if (osgDB::equalCaseInsensitive(osgDB::getFileExtension(fileName),"gdal")) { return readImage(osgDB::getNameLessExtension(fileName),options); } OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex); return const_cast<ReaderWriterGDAL*>(this)->local_readImage(fileName, options); } virtual ReadResult readHeightField(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const { if (osgDB::equalCaseInsensitive(osgDB::getFileExtension(fileName),"gdal")) { return readHeightField(osgDB::getNameLessExtension(fileName),options); } OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex); return const_cast<ReaderWriterGDAL*>(this)->local_readHeightField(fileName, options); } virtual ReadResult local_readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) { // Looks like gdal's GDALRasterBand::GetColorInterpretation() // is not giving proper values for ecw images. There is small // hack to get around bool ecwLoad = osgDB::equalCaseInsensitive(osgDB::getFileExtension(file),"ecw"); //if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; osg::notify(osg::INFO) << "GDAL : " << file << std::endl; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; initGDAL(); std::auto_ptr<GDALDataset> dataset((GDALDataset*)GDALOpen(fileName.c_str(),GA_ReadOnly)); if (!dataset.get()) return ReadResult::FILE_NOT_HANDLED; int dataWidth = dataset->GetRasterXSize(); int dataHeight = dataset->GetRasterYSize(); int windowX = 0; int windowY = 0; int windowWidth = dataWidth; int windowHeight = dataHeight; int destX = 0; int destY = 0; int destWidth = osg::minimum(dataWidth,4096); int destHeight = osg::minimum(dataHeight,4096);// int destWidth = osg::minimum(dataWidth,4096);// int destHeight = osg::minimum(dataHeight,4096); osgDB::ImageOptions::TexCoordRange* texCoordRange = 0; osgDB::ImageOptions* imageOptions = dynamic_cast<osgDB::ImageOptions*>(const_cast<osgDB::ReaderWriter::Options*>(options)); if (imageOptions) { osg::notify(osg::INFO)<<"Got ImageOptions"<<std::endl; int margin = 0; switch(imageOptions->_sourceImageWindowMode) { case(osgDB::ImageOptions::RATIO_WINDOW): { double desiredX = (double)dataWidth * imageOptions->_sourceRatioWindow.windowX; double desiredY = (double)dataHeight * imageOptions->_sourceRatioWindow.windowY; double desiredWidth = (double)dataWidth * imageOptions->_sourceRatioWindow.windowWidth; double desiredHeight = (double)dataHeight * imageOptions->_sourceRatioWindow.windowHeight; windowX = osg::maximum((int)(floor(desiredX))-margin,0); windowY = osg::maximum((int)(floor(desiredY))-margin,0); windowWidth = osg::minimum((int)(ceil(desiredX + desiredWidth))+margin,dataWidth)-windowX; windowHeight = osg::minimum((int)(ceil(desiredY + desiredHeight))+margin,dataHeight)-windowY; texCoordRange = new osgDB::ImageOptions::TexCoordRange; texCoordRange->set((desiredX-(double)windowX)/(double)windowWidth, ((double)(windowY+windowHeight) -(desiredY+desiredHeight))/(double)windowHeight, (desiredWidth)/(double)windowWidth, (desiredHeight)/(double)windowHeight); osg::notify(osg::INFO)<<"tex coord range "<<texCoordRange->_x<<" "<<texCoordRange->_y<<" "<<texCoordRange->_w<<" "<<texCoordRange->_h<<std::endl; } break; case(osgDB::ImageOptions::PIXEL_WINDOW): windowX = imageOptions->_sourcePixelWindow.windowX; windowY = imageOptions->_sourcePixelWindow.windowY; windowWidth = imageOptions->_sourcePixelWindow.windowWidth; windowHeight = imageOptions->_sourcePixelWindow.windowHeight; break; default: // leave source window dimensions as whole image. break; } // reapply the window coords to the pixel window so that calling code // knows the original pixel size imageOptions->_sourcePixelWindow.windowX = windowX; imageOptions->_sourcePixelWindow.windowY = windowY; imageOptions->_sourcePixelWindow.windowWidth = windowWidth; imageOptions->_sourcePixelWindow.windowHeight = windowHeight; switch(imageOptions->_destinationImageWindowMode) { case(osgDB::ImageOptions::RATIO_WINDOW): destX = (unsigned int)(floor((double)dataWidth * imageOptions->_destinationRatioWindow.windowX)); destY = (unsigned int)(floor((double)dataHeight * imageOptions->_destinationRatioWindow.windowY)); destWidth = (unsigned int)(ceil((double)dataWidth * (imageOptions->_destinationRatioWindow.windowX + imageOptions->_destinationRatioWindow.windowWidth)))-windowX; destHeight = (unsigned int)(ceil((double)dataHeight * (imageOptions->_destinationRatioWindow.windowY + imageOptions->_destinationRatioWindow.windowHeight)))-windowY; break; case(osgDB::ImageOptions::PIXEL_WINDOW): destX = imageOptions->_destinationPixelWindow.windowX; destY = imageOptions->_destinationPixelWindow.windowY; destWidth = imageOptions->_destinationPixelWindow.windowWidth; destHeight = imageOptions->_destinationPixelWindow.windowHeight; break; default: // leave source window dimensions as whole image. break; } } // windowX = 0; // windowY = 0; // windowWidth = destWidth;// windowHeight = destHeight; osg::notify(osg::INFO) << " windowX = "<<windowX<<std::endl; osg::notify(osg::INFO) << " windowY = "<<windowY<<std::endl; osg::notify(osg::INFO) << " windowWidth = "<<windowWidth<<std::endl; osg::notify(osg::INFO) << " windowHeight = "<<windowHeight<<std::endl; osg::notify(osg::INFO) << std::endl; osg::notify(osg::INFO) << " destX = "<<destX<<std::endl; osg::notify(osg::INFO) << " destY = "<<destY<<std::endl; osg::notify(osg::INFO) << " destWidth = "<<destWidth<<std::endl; osg::notify(osg::INFO) << " destHeight = "<<destHeight<<std::endl; osg::notify(osg::INFO) << std::endl; osg::notify(osg::INFO) << " GetRaterCount() "<< dataset->GetRasterCount()<<std::endl; osg::notify(osg::INFO) << " GetProjectionRef() "<< dataset->GetProjectionRef()<<std::endl; double geoTransform[6]; if (dataset->GetGeoTransform(geoTransform)==CE_None) { osg::notify(osg::INFO) << " GetGeoTransform "<< std::endl; osg::notify(osg::INFO) << " Origin = "<<geoTransform[0]<<" "<<geoTransform[3]<<std::endl; osg::notify(osg::INFO) << " Pixel X = "<<geoTransform[1]<<" "<<geoTransform[4]<<std::endl; osg::notify(osg::INFO) << " Pixel Y = "<<geoTransform[2]<<" "<<geoTransform[5]<<std::endl; } int numBands = dataset->GetRasterCount(); GDALRasterBand* bandGray = 0; GDALRasterBand* bandRed = 0; GDALRasterBand* bandGreen = 0; GDALRasterBand* bandBlue = 0; GDALRasterBand* bandAlpha = 0; GDALRasterBand* bandPalette = 0; int internalFormat = GL_LUMINANCE; unsigned int pixelFormat = GL_LUMINANCE; unsigned int dataType = 0; unsigned int numBytesPerPixel = 0; GDALDataType targetGDALType = GDT_Byte; for(int b=1;b<=numBands;++b) { GDALRasterBand* band = dataset->GetRasterBand(b); osg::notify(osg::INFO) << " Band "<<b<<std::endl; osg::notify(osg::INFO) << " GetOverviewCount() = "<< band->GetOverviewCount()<<std::endl; osg::notify(osg::INFO) << " GetColorTable() = "<< band->GetColorTable()<<std::endl; osg::notify(osg::INFO) << " DataTypeName() = "<< GDALGetDataTypeName(band->GetRasterDataType())<<std::endl; osg::notify(osg::INFO) << " ColorIntepretationName() = "<< GDALGetColorInterpretationName(band->GetColorInterpretation())<<std::endl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -