From 5c1b0f1bbdc1a63269bde1fc11b81a12718baf97 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 4 Sep 2006 20:43:07 +0000 Subject: [PATCH] Added support for imagery and DEM's that wrap around the dateline, this required two passes over the copying of imagery and DEM's to the destination graphs, once for the original position, and once for the wrap around 360 degrees on or before. Also fixed the GeospationExtents constructor that was setting the _max to DBL_MIN rather than -DBL_MAX. This bug causesd the y axis to be computed incorrectly. --- include/osgTerrain/DataSet | 50 +- src/osgTerrain/DataSet.cpp | 950 ++++++++++++++++++++----------------- 2 files changed, 542 insertions(+), 458 deletions(-) diff --git a/include/osgTerrain/DataSet b/include/osgTerrain/DataSet index b49377916..de4257810 100644 --- a/include/osgTerrain/DataSet +++ b/include/osgTerrain/DataSet @@ -52,16 +52,19 @@ class GeospatialExtents { public: - osg::Vec2d _min; - osg::Vec2d _max; - + osg::Vec2d _min; + osg::Vec2d _max; + bool _isGeographic; + inline GeospatialExtents() : _min(DBL_MAX,DBL_MAX), - _max(DBL_MIN,DBL_MIN) {} + _max(-DBL_MAX,-DBL_MAX), + _isGeographic(false) {} - inline GeospatialExtents(double xmin, double ymin, double xmax, double ymax) : + inline GeospatialExtents(double xmin, double ymin, double xmax, double ymax, bool isGeographic) : _min(xmin, ymin), - _max(xmax, ymax){} + _max(xmax, ymax), + _isGeographic(isGeographic) {} inline double& xMin() { return _min.x(); } inline double xMin() const { return _min.x(); } @@ -96,19 +99,35 @@ public: return 0.25f*((_max-_min).length2()); } - GeospatialExtents intersect(const GeospatialExtents& e) const + GeospatialExtents intersection(const GeospatialExtents& e, double xoffset) const { - return GeospatialExtents(osg::maximum(xMin(),e.xMin()),osg::maximum(yMin(),e.yMin()), - osg::minimum(xMax(),e.xMax()),osg::minimum(yMax(),e.yMax())); + return GeospatialExtents(osg::maximum(xMin(),e.xMin()+xoffset),osg::maximum(yMin(),e.yMin()), + osg::minimum(xMax(),e.xMax()+xoffset),osg::minimum(yMax(),e.yMax()),_isGeographic); } /** Return true if this bounding box intersects the specified bounding box. */ bool intersects(const GeospatialExtents& bb) const { - return osg::maximum(xMin(),bb.xMin()) <= osg::minimum(xMax(),bb.xMax()) && - osg::maximum(yMin(),bb.yMin()) <= osg::minimum(yMax(),bb.yMax()); + if (_isGeographic) + { + // first check vertical axis overlap + if (osg::maximum(yMin(),bb.yMin()) > osg::minimum(yMax(),bb.yMax())) return false; + + // next check if overlaps directly without any 360 degree horizontal shifts. + if (osg::maximum(xMin(),bb.xMin()) <= osg::minimum(xMax(),bb.xMax())) return true; + + // next check if a 360 rotation will produce an overlap + float rotationAngle = (xMin() > bb.xMin()) ? 360.0 : -360; + return (osg::maximum(xMin(),bb.xMin()+rotationAngle) <= osg::minimum(xMax(),bb.xMax()+rotationAngle)); + } + else + { + return (osg::maximum(xMin(),bb.xMin()) <= osg::minimum(xMax(),bb.xMax()) && + osg::maximum(yMin(),bb.yMin()) <= osg::minimum(yMax(),bb.yMax())); + } } + void expandBy(const osg::BoundingSphere& sh) { if (!sh.valid()) return; @@ -187,14 +206,9 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced return *this; } - void computeExtents() - { - _extents.init(); - _extents.expandBy( osg::Vec3(0.0,0.0,0.0)*_geoTransform); - _extents.expandBy( osg::Vec3(_numValuesX,_numValuesY,0.0)*_geoTransform); - } + void computeExtents(); - osg::ref_ptr _cs; + osg::ref_ptr _cs; osg::Matrixd _geoTransform; GeospatialExtents _extents; unsigned int _numValuesX; diff --git a/src/osgTerrain/DataSet.cpp b/src/osgTerrain/DataSet.cpp index d1c7ce584..f1d2f3dbe 100644 --- a/src/osgTerrain/DataSet.cpp +++ b/src/osgTerrain/DataSet.cpp @@ -212,7 +212,15 @@ bool areCoordinateSystemEquivalent(const osg::CoordinateSystemNode* lhs,const os return result ? true : false; } +void DataSet::SpatialProperties::computeExtents() +{ + _extents.init(); + _extents.expandBy( osg::Vec3(0.0,0.0,0.0)*_geoTransform); + _extents.expandBy( osg::Vec3(_numValuesX,_numValuesY,0.0)*_geoTransform); + _extents._isGeographic = getCoordinateSystemType(_cs.get())==GEOGRAPHIC; + my_notify(osg::INFO)<<"DataSet::SpatialProperties::computeExtents() is geographic "<<_extents._isGeographic<s()*(intersect_bb.xMin()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),0); - int destY = osg::maximum((int)floorf((float)destination._image->t()*(intersect_bb.yMin()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),0); - int destWidth = osg::minimum((int)ceilf((float)destination._image->s()*(intersect_bb.xMax()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),(int)destination._image->s())-destX; - int destHeight = osg::minimum((int)ceilf((float)destination._image->t()*(intersect_bb.yMax()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),(int)destination._image->t())-destY; - - my_notify(osg::INFO)<<" copying from "<resizeTolerance || destWindowHeightRatio>resizeTolerance) && - windowWidth>=2 && windowHeight>=2) - { - readWidth = windowWidth; - readHeight = windowHeight; - doResample = true; - } - - bool hasRGB = _gdalDataset->GetRasterCount() >= 3; - bool hasAlpha = _gdalDataset->GetRasterCount() >= 4; - bool hasColorTable = _gdalDataset->GetRasterCount() >= 1 && _gdalDataset->GetRasterBand(1)->GetColorTable(); - bool hasGreyScale = _gdalDataset->GetRasterCount() == 1; - unsigned int numSourceComponents = hasAlpha?4:3; - - if (hasRGB || hasColorTable || hasGreyScale) - { - // RGB - - unsigned int numBytesPerPixel = 1; - GDALDataType targetGDALType = GDT_Byte; - - int pixelSpace=numSourceComponents*numBytesPerPixel; - - my_notify(osg::INFO) << "reading RGB"<GetRasterBand(1); - GDALRasterBand* bandGreen = _gdalDataset->GetRasterBand(2); - GDALRasterBand* bandBlue = _gdalDataset->GetRasterBand(3); - GDALRasterBand* bandAlpha = hasAlpha ? _gdalDataset->GetRasterBand(4) : 0; + int windowX = osg::maximum((int)floorf((float)_numValuesX*(intersect_bb.xMin()-xoffset-s_bb.xMin())/(s_bb.xMax()-s_bb.xMin())),0); + int windowY = osg::maximum((int)floorf((float)_numValuesY*(intersect_bb.yMin()-s_bb.yMin())/(s_bb.yMax()-s_bb.yMin())),0); + int windowWidth = osg::minimum((int)ceilf((float)_numValuesX*(intersect_bb.xMax()-xoffset-s_bb.xMin())/(s_bb.xMax()-s_bb.xMin())),(int)_numValuesX)-windowX; + int windowHeight = osg::minimum((int)ceilf((float)_numValuesY*(intersect_bb.yMax()-s_bb.yMin())/(s_bb.yMax()-s_bb.yMin())),(int)_numValuesY)-windowY; - bandRed->RasterIO(GF_Read, - windowX,_numValuesY-(windowY+windowHeight), - windowWidth,windowHeight, - (void*)(tempImage+0),readWidth,readHeight, - targetGDALType,pixelSpace,pixelSpace*readWidth); - bandGreen->RasterIO(GF_Read, - windowX,_numValuesY-(windowY+windowHeight), - windowWidth,windowHeight, - (void*)(tempImage+1),readWidth,readHeight, - targetGDALType,pixelSpace,pixelSpace*readWidth); - bandBlue->RasterIO(GF_Read, + int destX = osg::maximum((int)floorf((float)destination._image->s()*(intersect_bb.xMin()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),0); + int destY = osg::maximum((int)floorf((float)destination._image->t()*(intersect_bb.yMin()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),0); + int destWidth = osg::minimum((int)ceilf((float)destination._image->s()*(intersect_bb.xMax()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),(int)destination._image->s())-destX; + int destHeight = osg::minimum((int)ceilf((float)destination._image->t()*(intersect_bb.yMax()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),(int)destination._image->t())-destY; + + my_notify(osg::INFO)<<" copying from "<resizeTolerance || destWindowHeightRatio>resizeTolerance) && + windowWidth>=2 && windowHeight>=2) + { + readWidth = windowWidth; + readHeight = windowHeight; + doResample = true; + } + + bool hasRGB = _gdalDataset->GetRasterCount() >= 3; + bool hasAlpha = _gdalDataset->GetRasterCount() >= 4; + bool hasColorTable = _gdalDataset->GetRasterCount() >= 1 && _gdalDataset->GetRasterBand(1)->GetColorTable(); + bool hasGreyScale = _gdalDataset->GetRasterCount() == 1; + unsigned int numSourceComponents = hasAlpha?4:3; + + if (hasRGB || hasColorTable || hasGreyScale) + { + // RGB + + unsigned int numBytesPerPixel = 1; + GDALDataType targetGDALType = GDT_Byte; + + int pixelSpace=numSourceComponents*numBytesPerPixel; + + my_notify(osg::INFO) << "reading RGB"<GetRasterBand(1); + GDALRasterBand* bandGreen = _gdalDataset->GetRasterBand(2); + GDALRasterBand* bandBlue = _gdalDataset->GetRasterBand(3); + GDALRasterBand* bandAlpha = hasAlpha ? _gdalDataset->GetRasterBand(4) : 0; + + bandRed->RasterIO(GF_Read, + windowX,_numValuesY-(windowY+windowHeight), + windowWidth,windowHeight, + (void*)(tempImage+0),readWidth,readHeight, + targetGDALType,pixelSpace,pixelSpace*readWidth); + bandGreen->RasterIO(GF_Read, + windowX,_numValuesY-(windowY+windowHeight), + windowWidth,windowHeight, + (void*)(tempImage+1),readWidth,readHeight, + targetGDALType,pixelSpace,pixelSpace*readWidth); + bandBlue->RasterIO(GF_Read, + windowX,_numValuesY-(windowY+windowHeight), + windowWidth,windowHeight, + (void*)(tempImage+2),readWidth,readHeight, + targetGDALType,pixelSpace,pixelSpace*readWidth); + + if (bandAlpha) + { + bandAlpha->RasterIO(GF_Read, + windowX,_numValuesY-(windowY+windowHeight), + windowWidth,windowHeight, + (void*)(tempImage+3),readWidth,readHeight, + targetGDALType,pixelSpace,pixelSpace*readWidth); + } + } + + else if( hasColorTable ) + { + // Pseudocolored image. Convert 1 band + color table to 24bit RGB. + + GDALRasterBand *band; + GDALColorTable *ct; + int i; + + + band = _gdalDataset->GetRasterBand(1); + + + band->RasterIO(GF_Read, + windowX,_numValuesY-(windowY+windowHeight), + windowWidth,windowHeight, + (void*)(tempImage+0),readWidth,readHeight, + targetGDALType,pixelSpace,pixelSpace*readWidth); + + + ct = band->GetColorTable(); + + + for( i = 0; i < readWidth * readHeight; i++ ) + { + GDALColorEntry sEntry; + + + // default to greyscale equilvelent. + sEntry.c1 = tempImage[i*3]; + sEntry.c2 = tempImage[i*3]; + sEntry.c3 = tempImage[i*3]; + + + ct->GetColorEntryAsRGB( tempImage[i*3], &sEntry ); + + + // Apply RGB back over destination image. + tempImage[i*3 + 0] = sEntry.c1; + tempImage[i*3 + 1] = sEntry.c2; + tempImage[i*3 + 2] = sEntry.c3; + } + } + + + else if (hasGreyScale) + { + // Greyscale image. Convert 1 band to 24bit RGB. + GDALRasterBand *band; + + + band = _gdalDataset->GetRasterBand(1); + + + band->RasterIO(GF_Read, + windowX,_numValuesY-(windowY+windowHeight), + windowWidth,windowHeight, + (void*)(tempImage+0),readWidth,readHeight, + targetGDALType,pixelSpace,pixelSpace*readWidth); + band->RasterIO(GF_Read, + windowX,_numValuesY-(windowY+windowHeight), + windowWidth,windowHeight, + (void*)(tempImage+1),readWidth,readHeight, + targetGDALType,pixelSpace,pixelSpace*readWidth); + band->RasterIO(GF_Read, windowX,_numValuesY-(windowY+windowHeight), windowWidth,windowHeight, (void*)(tempImage+2),readWidth,readHeight, targetGDALType,pixelSpace,pixelSpace*readWidth); - - if (bandAlpha) - { - bandAlpha->RasterIO(GF_Read, - windowX,_numValuesY-(windowY+windowHeight), - windowWidth,windowHeight, - (void*)(tempImage+3),readWidth,readHeight, - targetGDALType,pixelSpace,pixelSpace*readWidth); - } - } - - else if( hasColorTable ) - { - // Pseudocolored image. Convert 1 band + color table to 24bit RGB. - - GDALRasterBand *band; - GDALColorTable *ct; - int i; - - - band = _gdalDataset->GetRasterBand(1); - - - band->RasterIO(GF_Read, - windowX,_numValuesY-(windowY+windowHeight), - windowWidth,windowHeight, - (void*)(tempImage+0),readWidth,readHeight, - targetGDALType,pixelSpace,pixelSpace*readWidth); - - - ct = band->GetColorTable(); - - - for( i = 0; i < readWidth * readHeight; i++ ) - { - GDALColorEntry sEntry; - - - // default to greyscale equilvelent. - sEntry.c1 = tempImage[i*3]; - sEntry.c2 = tempImage[i*3]; - sEntry.c3 = tempImage[i*3]; - - - ct->GetColorEntryAsRGB( tempImage[i*3], &sEntry ); - - - // Apply RGB back over destination image. - tempImage[i*3 + 0] = sEntry.c1; - tempImage[i*3 + 1] = sEntry.c2; - tempImage[i*3 + 2] = sEntry.c3; } - } - - else if (hasGreyScale) - { - // Greyscale image. Convert 1 band to 24bit RGB. - GDALRasterBand *band; - - - band = _gdalDataset->GetRasterBand(1); - - - band->RasterIO(GF_Read, - windowX,_numValuesY-(windowY+windowHeight), - windowWidth,windowHeight, - (void*)(tempImage+0),readWidth,readHeight, - targetGDALType,pixelSpace,pixelSpace*readWidth); - band->RasterIO(GF_Read, - windowX,_numValuesY-(windowY+windowHeight), - windowWidth,windowHeight, - (void*)(tempImage+1),readWidth,readHeight, - targetGDALType,pixelSpace,pixelSpace*readWidth); - band->RasterIO(GF_Read, - windowX,_numValuesY-(windowY+windowHeight), - windowWidth,windowHeight, - (void*)(tempImage+2),readWidth,readHeight, - targetGDALType,pixelSpace,pixelSpace*readWidth); - } - - if (doResample || readWidth!=destWidth || readHeight!=destHeight) - { - unsigned char* destImage = new unsigned char[destWidth*destHeight*pixelSpace]; - - // rescale image by hand as glu seem buggy.... - for(int j=0;j=readWidth) read_i=readWidth-1; - - float flt_read_ir = flt_read_i-read_i; - if (read_i==readWidth-1) flt_read_ir=0.0f; - - int read_j = (int)flt_read_j; - if (read_j>=readHeight) read_j=readHeight-1; - - float flt_read_jr = flt_read_j-read_j; - if (read_j==readHeight-1) flt_read_jr=0.0f; - - unsigned char* dest = destImage + (j*destWidth + i) * pixelSpace; - if (flt_read_ir==0.0f) // no need to interpolate i axis. + float t_d = (float)j/((float)destHeight-1); + for(int i=0;i=readWidth) read_i=readWidth-1; + + float flt_read_ir = flt_read_i-read_i; + if (read_i==readWidth-1) flt_read_ir=0.0f; + + int read_j = (int)flt_read_j; + if (read_j>=readHeight) read_j=readHeight-1; + + float flt_read_jr = flt_read_j-read_j; + if (read_j==readHeight-1) flt_read_jr=0.0f; + + unsigned char* dest = destImage + (j*destWidth + i) * pixelSpace; + if (flt_read_ir==0.0f) // no need to interpolate i axis. { - // copy pixels - unsigned char* src = tempImage + (read_j*readWidth + read_i) * pixelSpace; - dest[0] = src[0]; - dest[1] = src[1]; - dest[2] = src[2]; - if (numSourceComponents==4) dest[3] = src[3]; - //std::cout<<"copy"<data(destX,destY+destHeight-1); + int destinationRowDelta = -(int)(destination._image->getRowSizeInBytes()); + int destination_pixelSpace = destination._image->getPixelSizeInBits()/8; + bool destination_hasAlpha = osg::Image::computeNumComponents(destination._image->getPixelFormat())==4; + + // copy image to destination image + for(int row=0; + rowdata(destX,destY+destHeight-1); - int destinationRowDelta = -(int)(destination._image->getRowSizeInBytes()); - int destination_pixelSpace = destination._image->getPixelSizeInBits()/8; - bool destination_hasAlpha = osg::Image::computeNumComponents(destination._image->getPixelFormat())==4; - - // copy image to destination image - for(int row=0; - rowgetNumColumns()*(intersect_bb.xMin()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),0); - int destY = osg::maximum((int)floorf((float)destination._heightField->getNumRows()*(intersect_bb.yMin()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),0); - int destWidth = osg::minimum((int)ceilf((float)destination._heightField->getNumColumns()*(intersect_bb.xMax()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),(int)destination._heightField->getNumColumns())-destX; - int destHeight = osg::minimum((int)ceilf((float)destination._heightField->getNumRows()*(intersect_bb.yMax()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),(int)destination._heightField->getNumRows())-destY; - - - // which band do we want to read from... - int numBands = _gdalDataset->GetRasterCount(); - GDALRasterBand* bandGray = 0; - GDALRasterBand* bandRed = 0; - GDALRasterBand* bandGreen = 0; - GDALRasterBand* bandBlue = 0; - GDALRasterBand* bandAlpha = 0; - - for(int b=1;b<=numBands;++b) - { - GDALRasterBand* band = _gdalDataset->GetRasterBand(b); - if (band->GetColorInterpretation()==GCI_GrayIndex) bandGray = band; - else if (band->GetColorInterpretation()==GCI_RedBand) bandRed = band; - else if (band->GetColorInterpretation()==GCI_GreenBand) bandGreen = band; - else if (band->GetColorInterpretation()==GCI_BlueBand) bandBlue = band; - else if (band->GetColorInterpretation()==GCI_AlphaBand) bandAlpha = band; - else if (bandGray == 0) bandGray = band; - } - - - GDALRasterBand* bandSelected = 0; - if (!bandSelected && bandGray) bandSelected = bandGray; - else if (!bandSelected && bandAlpha) bandSelected = bandAlpha; - else if (!bandSelected && bandRed) bandSelected = bandRed; - else if (!bandSelected && bandGreen) bandSelected = bandGreen; - else if (!bandSelected && bandBlue) bandSelected = bandBlue; - - if (bandSelected) + // note, we have to handle the possibility of goegraphic datasets wrapping over on themselves when they pass over the dateline + // to do this we have to test geographic datasets via two passes, each with a 360 degree shift of the source cata. + double xoffset = d_bb.xMin() < s_bb.xMin() ? -360.0 : 0.0; + unsigned int numXChecks = d_bb._isGeographic ? 2 : 1; + for(unsigned int ic = 0; ic < numXChecks; ++ic, xoffset += 360.0) { - if (bandSelected->GetUnitType()) my_notify(osg::INFO) << "bandSelected->GetUnitType()=" << bandSelected->GetUnitType()<GetUnitType()= null" <GetNoDataValue(&success); - if (success) + if (!intersect_bb.valid()) { - my_notify(osg::INFO)<<"We have NoDataValue = "<GetOffset(&success); - if (success) + int destX = osg::maximum((int)floorf((float)destination._heightField->getNumColumns()*(intersect_bb.xMin()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),0); + int destY = osg::maximum((int)floorf((float)destination._heightField->getNumRows()*(intersect_bb.yMin()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),0); + int destWidth = osg::minimum((int)ceilf((float)destination._heightField->getNumColumns()*(intersect_bb.xMax()-d_bb.xMin())/(d_bb.xMax()-d_bb.xMin())),(int)destination._heightField->getNumColumns())-destX; + int destHeight = osg::minimum((int)ceilf((float)destination._heightField->getNumRows()*(intersect_bb.yMax()-d_bb.yMin())/(d_bb.yMax()-d_bb.yMin())),(int)destination._heightField->getNumRows())-destY; + + + // which band do we want to read from... + int numBands = _gdalDataset->GetRasterCount(); + GDALRasterBand* bandGray = 0; + GDALRasterBand* bandRed = 0; + GDALRasterBand* bandGreen = 0; + GDALRasterBand* bandBlue = 0; + GDALRasterBand* bandAlpha = 0; + + for(int b=1;b<=numBands;++b) { - my_notify(osg::INFO)<<"We have Offset = "<GetRasterBand(b); + if (band->GetColorInterpretation()==GCI_GrayIndex) bandGray = band; + else if (band->GetColorInterpretation()==GCI_RedBand) bandRed = band; + else if (band->GetColorInterpretation()==GCI_GreenBand) bandGreen = band; + else if (band->GetColorInterpretation()==GCI_BlueBand) bandBlue = band; + else if (band->GetColorInterpretation()==GCI_AlphaBand) bandAlpha = band; + else if (bandGray == 0) bandGray = band; } - float scale = bandSelected->GetScale(&success); - if (success) + + GDALRasterBand* bandSelected = 0; + if (!bandSelected && bandGray) bandSelected = bandGray; + else if (!bandSelected && bandAlpha) bandSelected = bandAlpha; + else if (!bandSelected && bandRed) bandSelected = bandRed; + else if (!bandSelected && bandGreen) bandSelected = bandGreen; + else if (!bandSelected && bandBlue) bandSelected = bandBlue; + + if (bandSelected) { - my_notify(osg::INFO)<<"We have Scale = "<getVerticalScale(); - my_notify(osg::INFO)<<"We have no Scale from file so use DataSet vertical scale of "<GetUnitType()=" << bandSelected->GetUnitType()<GetUnitType()= null" <getOrigin().x(); - double orig_Y = hf->getOrigin().y(); - double delta_X = hf->getXInterval(); - double delta_Y = hf->getYInterval(); - - for (int c = destX; c < endX; ++c) + int success = 0; + float noDataValue = bandSelected->GetNoDataValue(&success); + if (success) { - double geoX = orig_X + (delta_X * (double)c); - for (int r = destY; r < endY; ++r) - { - double geoY = orig_Y + (delta_Y * (double)r); - float h = getInterpolatedValue(bandSelected, geoX, geoY); - if (h!=noDataValue) hf->setHeight(c,r,offset + h*scale); - else if (!ignoreNoDataValue) hf->setHeight(c,r,noDataValueFill); - } + my_notify(osg::INFO)<<"We have NoDataValue = "<RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,floatdata,destWidth,destHeight,GDT_Float32,numBytesPerZvalue,lineSpace); - bandSelected->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,heightData,destWidth,destHeight,GDT_Float32,0,0); - - float* heightPtr = heightData; - - for(int r=destY+destHeight-1;r>=destY;--r) + else { - for(int c=destX;csetHeight(c,r,offset + h*scale); - else if (!ignoreNoDataValue) hf->setHeight(c,r,noDataValueFill); - - h = hf->getHeight(c,r); - } + my_notify(osg::INFO)<<"We have no NoDataValue"<GetOffset(&success); + if (success) + { + my_notify(osg::INFO)<<"We have Offset = "<GetScale(&success); + if (success) + { + my_notify(osg::INFO)<<"We have Scale = "<getVerticalScale(); + my_notify(osg::INFO)<<"We have no Scale from file so use DataSet vertical scale of "<RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,floatdata,destWidth,destHeight,GDT_Float32,numBytesPerZvalue,lineSpace); + bandSelected->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,heightData,destWidth,destHeight,GDT_Float32,0,0); + + float* heightPtr = heightData; + + for(int r=destY+destHeight-1;r>=destY;--r) + { + for(int c=destX;csetHeight(c,r,offset + h*scale); + else if (!ignoreNoDataValue) hf->setHeight(c,r,noDataValueFill); + + h = hf->getHeight(c,r); + } + } + + delete [] heightData; + } + } } } } @@ -4023,10 +4060,10 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(CompositeDestinat { my_notify(osg::INFO)<<"Need to Divide X + Y for level "<_children.push_back(createDestinationGraph(destinationGraph, cs, @@ -4084,8 +4121,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(CompositeDestinat my_notify(osg::INFO)<<"Need to Divide X only"<_children.push_back(createDestinationGraph(destinationGraph, cs, @@ -4124,8 +4161,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(CompositeDestinat my_notify(osg::INFO)<<"Need to Divide Y only"<_children.push_back(createDestinationGraph(destinationGraph, cs, @@ -4222,6 +4259,8 @@ void DataSet::computeDestinationGraphFromSources(unsigned int numLevels) // get the extents of the sources and GeospatialExtents extents(_extents); + extents._isGeographic = destinateCoordSytemType==GEOGRAPHIC; + if (!extents.valid()) { for(CompositeSource::source_iterator itr(_sourceGraph.get());itr.valid();++itr) @@ -4232,10 +4271,41 @@ void DataSet::computeDestinationGraphFromSources(unsigned int numLevels) GeospatialExtents local_extents(sd->getExtents(_intermediateCoordinateSystem.get())); my_notify(osg::INFO)<<"local_extents = xMin()"<180.0) + { + // shift back to -180 to 180 range + local_extents.xMin() -= 360.0; + local_extents.xMax() -= 360.0; + } + else if (local_extents.xMin()<-180.0) + { + // shift back to -180 to 180 range + local_extents.xMin() += 360.0; + local_extents.xMax() += 360.0; + } + } + extents.expandBy(local_extents); } } } + + + if (destinateCoordSytemType==GEOGRAPHIC) + { + double xRange = extents.xMax() - extents.xMin(); + if (xRange>360.0) + { + // clamp to proper 360 range. + extents.xMin() = -180.0; + extents.xMax() = 180.0; + } + } + // compute the number of texture layers required. unsigned int maxTextureUnit = 0;