diff --git a/Code/IO/otbMapProjectionWrapper.cxx b/Code/IO/otbMapProjectionWrapper.cxx index bba8a4c44830ddc1cfbed7f483b9853440bb1eec..2ba007c6e4631c48ca7988ec319f238450774706 100644 --- a/Code/IO/otbMapProjectionWrapper.cxx +++ b/Code/IO/otbMapProjectionWrapper.cxx @@ -21,6 +21,7 @@ #include <cassert> #include "otbMacro.h" +#include "otbUtils.h" #include "projection/ossimMapProjection.h" #include "projection/ossimMapProjectionFactory.h" @@ -73,8 +74,7 @@ MapProjectionWrapper::InternalMapProjectionConstPointer MapProjectionWrapper::Ge return this->m_MapProjection; } - -std::string MapProjectionWrapper::GetWkt() +std::string MapProjectionWrapper::GetWkt() const { ossimKeywordlist kwl; this->GetMapProjection(); @@ -93,7 +93,7 @@ void MapProjectionWrapper::SetWkt(std::string projectionRefWkt) { this->m_ProjectionRefWkt = projectionRefWkt; m_ReinstanciateProjection = true; -// this->InstanciateProjection(); Should not be needed... + this->InstanciateProjection(); //Should not be needed, but it is... this->Modified(); } @@ -101,9 +101,78 @@ void MapProjectionWrapper::SetParameter(std::string key, std::string value) { m_ParameterStore[key] = value; m_ReinstanciateProjection = true; + this->InstanciateProjection(); //Should not be needed, but it is... this->Modified(); } +std::string MapProjectionWrapper::GetParameter(std::string key) const +{ + // Please refer to the note in the header filer + // we do NOT want to read from m_ParameterStore here! + + std::string projectionName = this->GetMapProjection()->getClassName(); + + // Start by matching generic parameters + const ossimMapProjection* projection = dynamic_cast<const ossimMapProjection*>(this->GetMapProjection()); + if (key.compare("Origin") == 0) + { + return Utils::ConvertToString(projection->origin()); + } + if (key.compare("FalseNorthing") == 0) + { + return Utils::ConvertToString(projection->getFalseNorthing()); + } + if (key.compare("FalseEasting") == 0) + { + return Utils::ConvertToString(projection->getFalseEasting()); + } + if (key.compare("StandardParallel1") == 0) + { + return Utils::ConvertToString(projection->getStandardParallel1()); + } + if (key.compare("StandardParallel2") == 0) + { + return Utils::ConvertToString(projection->getStandardParallel2()); + } + if (key.compare("A") == 0) + { + return Utils::ConvertToString(projection->getA()); + } + if (key.compare("B") == 0) + { + return Utils::ConvertToString(projection->getB()); + } + if (key.compare("F") == 0) + { + return Utils::ConvertToString(projection->getF()); + } + if (key.compare("MetersPerPixel") == 0) + { + return Utils::ConvertToString(projection->getMetersPerPixel()); + } + if (key.compare("DecimalDegreesPerPixel") == 0) + { + return Utils::ConvertToString(projection->getDecimalDegreesPerPixel()); + } + + + // Apply parameters to Utm + if (projectionName.compare("ossimUtmProjection") == 0) + { + const ossimUtmProjection* projection = dynamic_cast<const ossimUtmProjection*>(this->GetMapProjection()); + if (key.compare("Zone") == 0) + { + return Utils::ConvertToString(projection->getZone()); + } + if (key.compare("Hemisphere") == 0) + { + return Utils::ConvertToString(projection->getHemisphere()); + } + } + + return ""; +} + bool MapProjectionWrapper::InstanciateProjection() { if ((this->m_ReinstanciateProjection) || (m_MapProjection == NULL)) @@ -244,4 +313,20 @@ void MapProjectionWrapper::PrintMap() const std::cout << " " << (*it).first << ": " << (*it).second << "\n"; } } + + +namespace Utils +{ + +int GetZoneFromGeoPoint(double lon, double lat) +{ + //use ossim to handle the special case of UTM + ossimGpt point(lat, lon); + ossimUtmProjection projection; + int zone = projection.computeZone(point); + return zone; +} + +} + } // namespace otb diff --git a/Code/IO/otbMapProjectionWrapper.h b/Code/IO/otbMapProjectionWrapper.h index d9ac41736b14a7916c48a2fd0a553c781cf4d41e..eb4923df5e3f6494a67436d30e5c64faa99e03ef 100644 --- a/Code/IO/otbMapProjectionWrapper.h +++ b/Code/IO/otbMapProjectionWrapper.h @@ -34,7 +34,8 @@ namespace otb * \brief Wrapper class to group all dependencies to ossim for map projection * * This class is NOT intented to be used outside of OTB. Use the - * GenericMapProjection. + * GenericMapProjection. If you feel that you need to use it directly, + * think again! * * \sa GenericMapProjection * \ingroup Projection @@ -62,9 +63,11 @@ public: InternalMapProjectionPointer GetMapProjection(); InternalMapProjectionConstPointer GetMapProjection() const; - std::string GetWkt(); + std::string GetWkt() const; void SetWkt(std::string projectionRefWkt); + void SetParameter(std::string key, std::string value); + std::string GetParameter(std::string key) const; bool InstanciateProjection(); @@ -88,11 +91,23 @@ private: InternalMapProjectionPointer m_MapProjection; std::string m_ProjectionRefWkt; + // Hold the parameters specified directly from the user of the class + // Consistency is done from ParameterStore -> MapProjection + // But NOT MapProjection -> ParameterStore + // so DO NOT use that to read the projection parameters typedef std::map<std::string, std::string> StoreType; StoreType m_ParameterStore; bool m_ReinstanciateProjection; }; + +// Some usefull free functions related to ossim +namespace Utils +{ +int GetZoneFromGeoPoint(double lon, double lat); +} + + } // namespace otb #endif diff --git a/Code/Projections/otbGenericMapProjection.h b/Code/Projections/otbGenericMapProjection.h index 48dd835b3044aac8030e53ba46f5c88f749da81f..58614d1d95eca8cde1a29be20393692816ebd0fe 100644 --- a/Code/Projections/otbGenericMapProjection.h +++ b/Code/Projections/otbGenericMapProjection.h @@ -103,6 +103,9 @@ public: virtual bool IsProjectionDefined() const; + void SetParameter(std::string key, std::string value); + std::string GetParameter(std::string key) const; + protected: GenericMapProjection(); virtual ~GenericMapProjection(); diff --git a/Code/Projections/otbGenericMapProjection.txx b/Code/Projections/otbGenericMapProjection.txx index f530a1116e360d5d52cbaa43d5517acc0fd6b388..f02c899c85c4e36c1511c4acc77c5581b5c56ab0 100644 --- a/Code/Projections/otbGenericMapProjection.txx +++ b/Code/Projections/otbGenericMapProjection.txx @@ -133,6 +133,23 @@ GenericMapProjection<TDirectionOfMapping, TScalarType, NInputDimensions, NOutput return (m_MapProjection->GetMapProjection() != NULL); } +template<TransformDirection::TransformationDirection TDirectionOfMapping, class TScalarType, unsigned int NInputDimensions, + unsigned int NOutputDimensions> + void +GenericMapProjection<TDirectionOfMapping, TScalarType, NInputDimensions, NOutputDimensions> +::SetParameter(std::string key, std::string value) +{ + m_MapProjection->SetParameter(key, value); +} + +template<TransformDirection::TransformationDirection TDirectionOfMapping, class TScalarType, unsigned int NInputDimensions, + unsigned int NOutputDimensions> +std::string +GenericMapProjection<TDirectionOfMapping, TScalarType, NInputDimensions, NOutputDimensions> +::GetParameter(std::string key) const +{ + return m_MapProjection->GetParameter(key); +} template<TransformDirection::TransformationDirection TDirectionOfMapping, class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions> @@ -141,7 +158,6 @@ GenericMapProjection<TDirectionOfMapping, TScalarType, NInputDimensions, NOutput ::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); - os << indent << "ProjectionRefWkt: " << m_MapProjection->GetWkt() << std::endl; } diff --git a/Code/Projections/otbUtmMapProjection.h b/Code/Projections/otbUtmMapProjection.h index b031c63ba05f9d1af083d8a87db9774d4dd34a51..ae5d9a243749f047223757e8bc732cd793d3b3c3 100644 --- a/Code/Projections/otbUtmMapProjection.h +++ b/Code/Projections/otbUtmMapProjection.h @@ -18,8 +18,7 @@ #ifndef __otbUtmMapProjection_h #define __otbUtmMapProjection_h -#include "projection/ossimUtmProjection.h" -#include "otbMapProjection.h" +#include "otbGenericMapProjection.h" namespace otb { @@ -30,15 +29,15 @@ namespace otb * */ template <TransformDirection::TransformationDirection TTransform> -class ITK_EXPORT UtmMapProjection : public MapProjection<ossimUtmProjection, TTransform> +class ITK_EXPORT UtmMapProjection : public GenericMapProjection<TTransform> { public: /** Standard class typedefs. */ - typedef UtmMapProjection Self; - typedef MapProjection<ossimUtmProjection, TTransform> Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; + typedef UtmMapProjection Self; + typedef GenericMapProjection<TTransform> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; typedef typename Superclass::ScalarType ScalarType; typedef itk::Point<ScalarType, 2> InputPointType; @@ -48,7 +47,7 @@ public: itkNewMacro(Self); /** Run-time type information (and related methods). */ - itkTypeMacro(UtmMapProjection, MapProjection); + itkTypeMacro(UtmMapProjection, GenericMapProjection); virtual void SetZone(long zone); virtual void SetHemisphere(char hemisphere); @@ -56,10 +55,10 @@ public: virtual char GetHemisphere() const; virtual void SetZoneAndHemisphereFromGeoPoint(const InputPointType& geoPoint); - virtual int GetZoneFromGeoPoint(const InputPointType& geoPoint) const; + itkLegacyMacro(virtual int GetZoneFromGeoPoint(const InputPointType& geoPoint) const); protected: - UtmMapProjection() {}; + UtmMapProjection(); virtual ~UtmMapProjection() {}; private: diff --git a/Code/Projections/otbUtmMapProjection.txx b/Code/Projections/otbUtmMapProjection.txx index 450e166099ed39206dfaeda9483066bc5a1e91db..b1bbd30a74b715e09492672b8dbb42af6f7999d1 100644 --- a/Code/Projections/otbUtmMapProjection.txx +++ b/Code/Projections/otbUtmMapProjection.txx @@ -21,15 +21,25 @@ #include "otbUtmMapProjection.h" +#include "otbUtils.h" + namespace otb { +template <TransformDirection::TransformationDirection TTransform> +UtmMapProjection<TTransform> +::UtmMapProjection() +{ + this->SetWkt("ossimUtmProjection"); +} + + ///Set the zone template <TransformDirection::TransformationDirection TTransform> void UtmMapProjection<TTransform> ::SetZone(long zone) { - this->m_MapProjection->setZone(zone); + this->SetParameter("Zone", Utils::ConvertToString(zone)); this->Modified(); } @@ -38,7 +48,7 @@ template <TransformDirection::TransformationDirection TTransform> void UtmMapProjection<TTransform> ::SetHemisphere(char hemisphere) { - this->m_MapProjection->setHemisphere(hemisphere); + this->SetParameter("Hemisphere", Utils::ConvertToString(hemisphere)); this->Modified(); } @@ -46,14 +56,11 @@ template <TransformDirection::TransformationDirection TTransform> void UtmMapProjection<TTransform> ::SetZoneAndHemisphereFromGeoPoint(const InputPointType& geoPoint) { - char hemisphere; - - if (geoPoint[1] > 0.) hemisphere = 'N'; - else hemisphere = 'S'; - this->SetHemisphere(hemisphere); + if (geoPoint[1] > 0.) this->SetParameter("Hemisphere", "N"); + else this->SetParameter("Hemisphere", "S"); - int zone = this->GetZoneFromGeoPoint(geoPoint); - this->SetZone(zone); + int zone = Utils::GetZoneFromGeoPoint(geoPoint[0], geoPoint[1]); + this->SetParameter("Zone", Utils::ConvertToString(zone)); } ///\return the zone @@ -61,8 +68,7 @@ template <TransformDirection::TransformationDirection TTransform> int UtmMapProjection<TTransform> ::GetZone() const { - int zone = this->m_MapProjection->getZone(); - + int zone = atoi(this->GetParameter("Zone").c_str()); return zone; } @@ -71,7 +77,10 @@ template <TransformDirection::TransformationDirection TTransform> char UtmMapProjection<TTransform> ::GetHemisphere() const { - char hemisphere = this->m_MapProjection->getHemisphere(); + //If this happens, we have to better control the instanciation of + //the projection. + assert(this->GetParameter("Hemisphere").size() > 0); + char hemisphere = this->GetParameter("Hemisphere")[0]; return hemisphere; } @@ -80,11 +89,7 @@ template <TransformDirection::TransformationDirection TTransform> int UtmMapProjection<TTransform> ::GetZoneFromGeoPoint(const InputPointType& geoPoint) const { - //use ossim to handle the special case of UTM - ossimGpt point(geoPoint[1], geoPoint[0]); - int zone = this->m_MapProjection->computeZone(point); - - return zone; + return Utils::GetZoneFromGeoPoint(geoPoint[0], geoPoint[1]); } } diff --git a/Testing/Code/IO/otbMapProjectionWrapperTest.cxx b/Testing/Code/IO/otbMapProjectionWrapperTest.cxx index 7b0f7e5f52a8528b48d0e8b973c6deb43f0bbd2e..9318fbc0c5f5f3880e2dc923c75dea0c33e2c4bd 100644 --- a/Testing/Code/IO/otbMapProjectionWrapperTest.cxx +++ b/Testing/Code/IO/otbMapProjectionWrapperTest.cxx @@ -179,7 +179,7 @@ int otbMapProjectionWrapperTest(int argc, char* argv[]) genericMapProjection->SetWkt(projectionRefWkt); genericMapProjection->SetParameter("Zone", "46"); genericMapProjection->SetParameter("Hemisphere", "S"); - file << "Instanciating from : " << projectionRefWkt << std::endl; + file << "Instanciating from : " << projectionRefWkt << " with some extra parameters" << std::endl; file << genericMapProjection->GetWkt() << std::endl << std::endl; double lon = 91.44; diff --git a/Testing/Code/Projections/otbMapProjection.cxx b/Testing/Code/Projections/otbMapProjection.cxx index 9953bf368dc95d1e94d718046a8757beb766a471..2e21b5aacb871a6e7bf989671f2ca485c687d56a 100644 --- a/Testing/Code/Projections/otbMapProjection.cxx +++ b/Testing/Code/Projections/otbMapProjection.cxx @@ -51,20 +51,22 @@ int otbMapProjection(int argc, char* argv[]) otb::MercatorForwardProjection::Pointer lMercatorProjection2 = otb::MercatorForwardProjection::New(); file << lMercatorProjection2->GetWkt() << std::endl << std::endl; + + // Moving to GenericMapProjection, change the access file << "\n\n *** Test accessors *** \n\n"; file << std::setprecision(15); - file << "Origin: \t" << lUtmProjection->Origin() << std::endl; - file << "False northing: \t" << lUtmProjection->GetFalseNorthing() << std::endl; - file << "False easting: \t" << lUtmProjection->GetFalseEasting() << std::endl; - file << "Parallel 1: \t" << lUtmProjection->GetStandardParallel1() << std::endl; - file << "Parallel 2: \t" << lUtmProjection->GetStandardParallel2() << std::endl; - file << "Name: \t" << lUtmProjection->GetProjectionName() << std::endl; - file << "Geo: \t" << lUtmProjection->IsGeographic() << std::endl; - file << "A: \t" << lUtmProjection->GetA() << std::endl; - file << "B: \t" << lUtmProjection->GetB() << std::endl; - file << "F: \t" << lUtmProjection->GetF() << std::endl; - file << "m per pix: \t" << lUtmProjection->GetMetersPerPixel() << std::endl; - file << "degree per pix: \t" << lUtmProjection->GetDecimalDegreesPerPixel() << std::endl; + file << "Origin: \t" << lUtmProjection->GetParameter("Origin") << std::endl; + file << "False northing: \t" << lUtmProjection->GetParameter("FalseNorthing") << std::endl; + file << "False easting: \t" << lUtmProjection->GetParameter("FalseEasting") << std::endl; + file << "Parallel 1: \t" << lUtmProjection->GetParameter("StandardParallel1") << std::endl; + file << "Parallel 2: \t" << lUtmProjection->GetParameter("StandardParallel2") << std::endl; +// file << "Name: \t" << lUtmProjection->GetProjectionName() << std::endl; +// file << "Geo: \t" << lUtmProjection->IsGeographic() << std::endl; + file << "A: \t" << lUtmProjection->GetParameter("A") << std::endl; + file << "B: \t" << lUtmProjection->GetParameter("B") << std::endl; + file << "F: \t" << lUtmProjection->GetParameter("F") << std::endl; + file << "m per pix: \t" << lUtmProjection->GetParameter("MetersPerPixel") << std::endl; + file << "degree per pix: \t" << lUtmProjection->GetParameter("DecimalDegreesPerPixel") << std::endl; file.close(); return EXIT_SUCCESS;