Skip to content
Snippets Groups Projects
Commit c18cb4d2 authored by Julien Michel's avatar Julien Michel
Browse files

REFAC: Adding a cleaner class to wrap rpc solver

parent 7130dfa5
No related branches found
No related tags found
No related merge requests found
/*=========================================================================
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
/*=========================================================================
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment