From c18cb4d29bdb43fe21f9363a1d01b572a2e5222b Mon Sep 17 00:00:00 2001 From: Julien Michel <julien.michel@orfeo-toolbox.org> Date: Mon, 3 Dec 2012 15:50:08 +0100 Subject: [PATCH] REFAC: Adding a cleaner class to wrap rpc solver --- .../OssimAdapters/otbRPCSolverAdapter.cxx | 135 ++++++++++++++++++ .../OssimAdapters/otbRPCSolverAdapter.h | 85 +++++++++++ 2 files changed, 220 insertions(+) create mode 100644 Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.cxx create mode 100644 Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.h diff --git a/Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.cxx b/Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.cxx new file mode 100644 index 0000000000..f2970042c3 --- /dev/null +++ b/Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.cxx @@ -0,0 +1,135 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "otbRPCSolverAdapter.h" +#include "otbImageKeywordlist.h" + +#include "ossim/projection/ossimRpcSolver.h" +#include "ossim/projection/ossimProjection.h" +#include "ossim/projection/ossimRpcProjection.h" +#include "ossim/imaging/ossimImageGeometry.h" + +namespace otb +{ + +RPCSolverAdapter::RPCSolverAdapter() +{} + +RPCSolverAdapter::~RPCSolverAdapter() +{} + +void +RPCSolverAdapter::Solve(const GCPsContainerType& gcpContainer, + const Point2DType& ulImagePoint, + const Point2DType& lrImagePoint, + double& rmsError, + ImageKeywordlist& otb_kwl) +{ + // TODO: for now, this is a simple transfer of what was done in the + // GCPsToRPCSensorModelImageFilter. We might find some way to improve that. + + // The vector where geo and sensor points are stored + std::vector<ossimDpt> sensorPoints; + std::vector<ossimGpt> geoPoints; + + // Temporary points variable + ossimDpt sensorPoint; + ossimGpt geoPoint; + + // Retrieve the additional GCPs + GCPsContainerType::const_iterator gcpIt; + for (gcpIt = gcpContainer.begin(); gcpIt != gcpContainer.end(); ++gcpIt) + { + // Check if point is inside bounds + if(gcpIt->first[0] >= ulImagePoint[0] && gcpIt->first[1] >= ulImagePoint[1] + && gcpIt->first[0] <= lrImagePoint[0] && gcpIt->first[1] <= lrImagePoint[1]) + { + // Fill sensor point + sensorPoint = ossimDpt(gcpIt->first[0], gcpIt->first[1]); + + // Fill geo point (lat, lon, elev) + geoPoint = ossimGpt(gcpIt->second[1], gcpIt->second[0], gcpIt->second[2]); + + // Add the sensor point to the list + sensorPoints.push_back(sensorPoint); + + // Add the geo point to the list + geoPoints.push_back(geoPoint); + } + } + + // Check for enough points + if(sensorPoints.size() < 40) + { + itkGenericExceptionMacro(<<"At least 40 points are required to estimate the 80 parameters of the RPC model, but only "<<sensorPoints.size()<<" were given."); + } + + // Build the ossim rpc solver + ossimRefPtr<ossimRpcSolver> rpcSolver = new ossimRpcSolver(true, false); + + // Call the solve method + rpcSolver->solveCoefficients(sensorPoints, geoPoints); + + rmsError = rpcSolver->getRmsError(); + + // Retrieve the output RPC projection + ossimRefPtr<ossimRpcModel> rpcModel = dynamic_cast<ossimRpcModel*>(rpcSolver->createRpcModel()->getProjection()); + + // Add spacings + rpcModel->setMetersPerPixel(rpcSolver->createRpcProjection()->getProjection()->getMetersPerPixel()); + + // Add ground rectangle + ossimDrect imageRectangle(ulImagePoint[0],ulImagePoint[1],lrImagePoint[0],lrImagePoint[1]); + + ossimGpt ulGround, lrGround, urGround, llGround; + + rpcModel->lineSampleToWorld(imageRectangle.ul(),ulGround); + rpcModel->lineSampleToWorld(imageRectangle.lr(),lrGround); + rpcModel->lineSampleToWorld(imageRectangle.ur(),urGround); + rpcModel->lineSampleToWorld(imageRectangle.ll(),llGround); + + rpcModel->setGroundRect(ulGround, urGround, lrGround, llGround); + + // Export the sensor model in an ossimKeywordlist + ossimKeywordlist geom_kwl; + rpcModel->saveState(geom_kwl); + + // Build an otb::ImageKeywordList + otb_kwl.SetKeywordlist(geom_kwl); +} + +bool RPCSolverAdapter::Solve(const GCPsContainerType& gcpContainer, + const Point2DType& ulImagePoint, + const Point2DType& lrImagePoint, + double& rmsError, + const std::string & outgeom) + { + // Declare an empty keywordlist + ImageKeywordlist otb_kwl; + + // Call the Solve method that actually does the solving + Solve(gcpContainer,ulImagePoint,lrImagePoint,rmsError,otb_kwl); + + // Write the keywordlist to disk + ossimKeywordlist kwl; + otb_kwl.convertToOSSIMKeywordlist(kwl); + return kwl.write(outgeom.c_str()); + } + + +} // namespace otb diff --git a/Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.h b/Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.h new file mode 100644 index 0000000000..049b6a9b9f --- /dev/null +++ b/Code/UtilitiesAdapters/OssimAdapters/otbRPCSolverAdapter.h @@ -0,0 +1,85 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __otbRPCSolverAdapter_h +#define __otbRPCSolverAdapter_h + +#include <vector> + +#include "itkObject.h" +#include "itkObjectFactory.h" + +#include "itkPoint.h" +#include "itkSize.h" + + +class ossimRpcSolver; + +namespace otb { + +class ImageKeywordlist; + +/** \class RPCSolverAdapter + * \brief This is a dummy class to expose the RPC solving function + * + * This class defines some typedefs and exposes the RPC solving functions. + * + * \sa GCPsToRPCSensorModelImageFilter + **/ + +class RPCSolverAdapter +{ +public: + /** Standard class typedefs. */ + typedef RPCSolverAdapter Self; + typedef itk::Point<double, 2> Point2DType; + typedef itk::Point<double, 3> Point3DType; + typedef std::pair<Point2DType, Point3DType> GCPType; + typedef std::vector<GCPType> GCPsContainerType; + + /** Solve RPC modelling from a set of GCPs and image bounds. + * The estimated RPC model is written in a keywordlist understood + * by other OTB and classes (like GenericRSTransform for instance). + */ + static void Solve(const GCPsContainerType& gcpContainer, + const Point2DType& ulImagePoint, + const Point2DType& lrImagePoint, + double& rmsError, + ImageKeywordlist& otb_kwl); + + /** Solve RPC modelling from a set of GCPs and image bounds. The + * estimated RPC model is written to a geom file + */ + static bool Solve(const GCPsContainerType& gcpContainer, + const Point2DType& ulImagePoint, + const Point2DType& lrImagePoint, + double& rmsError, + const std::string & outgeom); + + +private: + RPCSolverAdapter(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + RPCSolverAdapter(); // purposely not implemented, this class defines + // typedefs and exposes static methods + virtual ~RPCSolverAdapter(); // purposely not implemented, this class defines + // typedefs and exposes static methods +}; + +} // namespace otb + +#endif -- GitLab