diff --git a/examples/osgterrain/osgterrain.cpp b/examples/osgterrain/osgterrain.cpp index 6418b0d39..cc539e0db 100644 --- a/examples/osgterrain/osgterrain.cpp +++ b/examples/osgterrain/osgterrain.cpp @@ -640,7 +640,7 @@ int main(int argc, char** argv) osg::ref_ptr lastAppliedLayer; locator->setCoordinateSystemType(osgTerrain::Locator::GEOCENTRIC); - locator->setExtents(-osg::PI, -osg::PI*0.5, osg::PI, osg::PI*0.5); + locator->setTransformAsExtents(-osg::PI, -osg::PI*0.5, osg::PI, osg::PI*0.5); unsigned int layerNum = 0; @@ -672,7 +672,7 @@ int main(int argc, char** argv) { // define the extents. locator->setCoordinateSystemType(osgTerrain::Locator::GEOCENTRIC); - locator->setExtents(x,y,x+w,y+h); + locator->setTransformAsExtents(x,y,x+w,y+h); readParameter = true; } @@ -686,7 +686,7 @@ int main(int argc, char** argv) { // define the extents. locator->setCoordinateSystemType(osgTerrain::Locator::PROJECTED); - locator->setExtents(x,y,x+w,y+h); + locator->setTransformAsExtents(x,y,x+w,y+h); } else if (arguments.read(pos, "--hf",filename)) diff --git a/include/osgTerrain/Locator b/include/osgTerrain/Locator index bd578fb93..48b8e784e 100644 --- a/include/osgTerrain/Locator +++ b/include/osgTerrain/Locator @@ -76,24 +76,14 @@ class OSGTERRAIN_EXPORT Locator : public osg::Object const osg::EllipsoidModel* getEllipsoidModel() const { return _ellipsoidModel.get(); } + /** Set the transformation from local coordinates to model coordinates.*/ + void setTransform(osg::Matrixd& transform) { _transform = transform; _inverse.invert(_transform); } + + /** Set the transformation from local coordinates to model coordinates.*/ + const osg::Matrixd& getTransform() const { return _transform; } /** Set the extents of the local coords.*/ - void setExtents(double minX, double minY, double maxX, double maxY); - - /** Get the extents of the local coords.*/ - void getExtents(double& minX, double& minY, double& maxX, double& maxY) const; - - void setMinX(double minX) { _minX = minX; } - double getMinX() const { return _minX; } - - void setMinY(double minY) { _minY = minY; } - double getMinY() const { return _minY; } - - void setMaxX(double maxX) { _maxX = maxX; } - double getMaxX() const { return _maxX; } - - void setMaxY(double maxY) { _maxY = maxY; } - double getMaxY() const { return _maxY; } + void setTransformAsExtents(double minX, double minY, double maxX, double maxY); virtual bool orientationOpenGL() const; @@ -123,10 +113,8 @@ class OSGTERRAIN_EXPORT Locator : public osg::Object std::string _cs; osg::ref_ptr _ellipsoidModel; - double _minX; - double _minY; - double _maxX; - double _maxY; + osg::Matrixd _transform; + osg::Matrixd _inverse; }; diff --git a/src/osgPlugins/gdal/DataSetLayer.cpp b/src/osgPlugins/gdal/DataSetLayer.cpp index 386f14548..bae12685f 100644 --- a/src/osgPlugins/gdal/DataSetLayer.cpp +++ b/src/osgPlugins/gdal/DataSetLayer.cpp @@ -14,6 +14,11 @@ #include "DataSetLayer.h" #include +#include + +#include +#include +#include using namespace GDALPlugin; @@ -82,4 +87,98 @@ osgTerrain::ImageLayer* DataSetLayer::extractImageLayer(unsigned int sourceMinX, void DataSetLayer::setUpLocator() { osg::notify(osg::NOTICE)<<"DataSetLayer::setUpLocator()"<GetProjectionRef(); + if (!pszSourceSRS || strlen(pszSourceSRS)==0) pszSourceSRS = _dataset->GetGCPProjection(); + + + osg::ref_ptr locator = new osgTerrain::Locator; + + if (pszSourceSRS) + { + locator->setFormat("WKT"); + locator->setCoordinateSystem(pszSourceSRS); + } + + osg::Matrixd matrix; + + double geoTransform[6]; + if (_dataset->GetGeoTransform(geoTransform)==CE_None) + { +#ifdef SHIFT_RASTER_BY_HALF_CELL + // shift the transform to the middle of the cell if a raster interpreted as vector + if (data->_dataType == VECTOR) + { + geoTransform[0] += 0.5 * geoTransform[1]; + geoTransform[3] += 0.5 * geoTransform[5]; + } +#endif + + matrix.set( geoTransform[1], geoTransform[4], 0.0, 0.0, + geoTransform[2], geoTransform[5], 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + geoTransform[0], geoTransform[3], 0.0, 1.0); + + } + else if (_dataset->GetGCPCount()>0 && _dataset->GetGCPProjection()) + { + osg::notify(osg::NOTICE) << " Using GCP's"<< std::endl; + + + /* -------------------------------------------------------------------- */ + /* Create a transformation object from the source to */ + /* destination coordinate system. */ + /* -------------------------------------------------------------------- */ + void *hTransformArg = + GDALCreateGenImgProjTransformer( _dataset, pszSourceSRS, + NULL, pszSourceSRS, + TRUE, 0.0, 1 ); + + if ( hTransformArg == NULL ) + { + osg::notify(osg::NOTICE)<<" failed to create transformer"<getTransform()<setCoordinateSystemType(osgTerrain::Locator::GEOCENTRIC); else if (fr[1].matchWord("GEOGRAPHIC")) locator->setCoordinateSystemType(osgTerrain::Locator::GEOGRAPHIC); else locator->setCoordinateSystemType(osgTerrain::Locator::PROJECTED); - locator->setExtents(x,y,x+w,y+h); + locator->setTransformAsExtents(x,y,x+w,y+h); fr += 6; itrAdvanced = true; @@ -189,6 +199,21 @@ osgTerrain::Layer* readLayer(osgDB::Input& fr) localAdvanced = true; } + if (fr.matchSequence("Transform %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f")) + { + osg::Matrixd matrix; + for(unsigned int i=1; i<=16; ++i) + { + fr[i].getFloat(matrix(i%4,i/4)); + } + + locator->setTransform(matrix); + + fr += 17; + localAdvanced = true; + } + + if (fr.matchSequence("Extents %f %f %f %f")) { double minX,minY,maxX,maxY; @@ -197,7 +222,7 @@ osgTerrain::Layer* readLayer(osgDB::Input& fr) fr[3].getFloat(maxX); fr[4].getFloat(maxY); - locator->setExtents(minX, minY, maxX, maxY); + locator->setTransformAsExtents(minX, minY, maxX, maxY); fr += 5; localAdvanced = true; @@ -221,7 +246,7 @@ osgTerrain::Layer* readLayer(osgDB::Input& fr) locator = new osgTerrain::Locator; locator->setCoordinateSystemType(osgTerrain::Locator::GEOCENTRIC); - locator->setExtents(x,y,x+w,y+h); + locator->setTransformAsExtents(x,y,x+w,y+h); fr += 5; itrAdvanced = true; @@ -237,7 +262,7 @@ osgTerrain::Layer* readLayer(osgDB::Input& fr) locator = new osgTerrain::Locator; locator->setCoordinateSystemType(osgTerrain::Locator::PROJECTED); - locator->setExtents(x,y,x+w,y+h); + locator->setTransformAsExtents(x,y,x+w,y+h); fr += 5; itrAdvanced = true; @@ -426,64 +451,37 @@ bool Terrain_readLocalData(osg::Object& obj, osgDB::Input &fr) bool writeLocator(const osgTerrain::Locator& locator, osgDB::Output& fw) { - if (locator.getCoordinateSystem().empty()) - { - fw.indent()<<"Locator "; - switch(locator.getCoordinateSystemType()) - { - case(osgTerrain::Locator::GEOCENTRIC): - { - fw<<"GEOCENTRIC"; - break; - } - case(osgTerrain::Locator::GEOGRAPHIC): - { - fw<<"GEOGRPAHIC"; - break; - } - case(osgTerrain::Locator::PROJECTED): - { - fw<<"PROJECTED"; - break; - } - } + fw.indent()<<"Locator {"<= 0.0; + return _transform(0,0) * _transform(1,1) >= 0.0; } bool Locator::convertLocalToModel(const osg::Vec3d& local, osg::Vec3d& world) const @@ -109,27 +102,21 @@ bool Locator::convertLocalToModel(const osg::Vec3d& local, osg::Vec3d& world) co switch(_coordinateSystemType) { case(GEOCENTRIC): - { - double longitude = _minX * (1.0-local.x()) + _maxX * local.x(); - double latitude = _minY * (1.0-local.y()) + _maxY * local.y(); - double height = local.z(); - - _ellipsoidModel->convertLatLongHeightToXYZ(latitude, longitude, height, + { + osg::Vec3d geographic = local * _transform; + + _ellipsoidModel->convertLatLongHeightToXYZ(geographic.x(), geographic.y(), geographic.z(), world.x(), world.y(), world.z()); return true; } case(GEOGRAPHIC): { - world.x() = _minX * (1.0-local.x()) + _maxX * local.x(); - world.y() = _minY * (1.0-local.y()) + _maxY * local.y(); - world.z() = local.z(); + world = local * _transform; return true; } case(PROJECTED): { - world.x() = _minX * (1.0-local.x()) + _maxX * local.x(); - world.y() = _minY * (1.0-local.y()) + _maxY * local.y(); - world.z() = local.z(); + world = local * _transform; return true; } } @@ -148,25 +135,19 @@ bool Locator::convertModelToLocal(const osg::Vec3d& world, osg::Vec3d& local) co _ellipsoidModel->convertXYZToLatLongHeight(world.x(), world.y(), world.z(), latitude, longitude, height ); - - local.x() = (longitude - _minX) / (_maxX - _minX); - local.y() = (latitude - _minY) / (_maxY - _minY); - local.z() = height; + local = osg::Vec3d(longitude, latitude, height) * _inverse; return true; } case(GEOGRAPHIC): { - local.x() = (world.x() - _minX) / (_maxX - _minX); - local.y() = (world.y() - _minY) / (_maxY - _minY); - local.z() = world.z(); + local = world * _inverse; + return true; } case(PROJECTED): { - local.x() = (world.x() - _minX) / (_maxX - _minX); - local.y() = (world.y() - _minY) / (_maxY - _minY); - local.z() = world.z(); + local = world * _inverse; return true; } } diff --git a/src/osgWrappers/osgTerrain/Locator.cpp b/src/osgWrappers/osgTerrain/Locator.cpp index 69a3a9407..c3f8e9e2b 100644 --- a/src/osgWrappers/osgTerrain/Locator.cpp +++ b/src/osgWrappers/osgTerrain/Locator.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -111,56 +112,21 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Locator) __C5_osg_EllipsoidModel_P1__getEllipsoidModel, "Get the const EllipsoidModel. ", ""); - I_Method4(void, setExtents, IN, double, minX, IN, double, minY, IN, double, maxX, IN, double, maxY, + I_Method1(void, setTransform, IN, osg::Matrixd &, transform, Properties::NON_VIRTUAL, - __void__setExtents__double__double__double__double, + __void__setTransform__osg_Matrixd_R1, + "Set the transformation from local coordinates to model coordinates. ", + ""); + I_Method0(const osg::Matrixd &, getTransform, + Properties::NON_VIRTUAL, + __C5_osg_Matrixd_R1__getTransform, + "Set the transformation from local coordinates to model coordinates. ", + ""); + I_Method4(void, setTransformAsExtents, IN, double, minX, IN, double, minY, IN, double, maxX, IN, double, maxY, + Properties::NON_VIRTUAL, + __void__setTransformAsExtents__double__double__double__double, "Set the extents of the local coords. ", ""); - I_Method4(void, getExtents, IN, double &, minX, IN, double &, minY, IN, double &, maxX, IN, double &, maxY, - Properties::NON_VIRTUAL, - __void__getExtents__double_R1__double_R1__double_R1__double_R1, - "Get the extents of the local coords. ", - ""); - I_Method1(void, setMinX, IN, double, minX, - Properties::NON_VIRTUAL, - __void__setMinX__double, - "", - ""); - I_Method0(double, getMinX, - Properties::NON_VIRTUAL, - __double__getMinX, - "", - ""); - I_Method1(void, setMinY, IN, double, minY, - Properties::NON_VIRTUAL, - __void__setMinY__double, - "", - ""); - I_Method0(double, getMinY, - Properties::NON_VIRTUAL, - __double__getMinY, - "", - ""); - I_Method1(void, setMaxX, IN, double, maxX, - Properties::NON_VIRTUAL, - __void__setMaxX__double, - "", - ""); - I_Method0(double, getMaxX, - Properties::NON_VIRTUAL, - __double__getMaxX, - "", - ""); - I_Method1(void, setMaxY, IN, double, maxY, - Properties::NON_VIRTUAL, - __void__setMaxY__double, - "", - ""); - I_Method0(double, getMaxY, - Properties::NON_VIRTUAL, - __double__getMaxY, - "", - ""); I_Method0(bool, orientationOpenGL, Properties::VIRTUAL, __bool__orientationOpenGL, @@ -197,17 +163,8 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Locator) I_SimpleProperty(const std::string &, Format, __C5_std_string_R1__getFormat, __void__setFormat__C5_std_string_R1); - I_SimpleProperty(double, MaxX, - __double__getMaxX, - __void__setMaxX__double); - I_SimpleProperty(double, MaxY, - __double__getMaxY, - __void__setMaxY__double); - I_SimpleProperty(double, MinX, - __double__getMinX, - __void__setMinX__double); - I_SimpleProperty(double, MinY, - __double__getMinY, - __void__setMinY__double); + I_SimpleProperty(osg::Matrixd &, Transform, + 0, + __void__setTransform__osg_Matrixd_R1); END_REFLECTOR