Commit e2eaac45 authored by Julien Osman's avatar Julien Osman
Browse files

ENH: Implement a factory for the transformations

parent 94f46374
Pipeline #8123 failed with stages
in 109 minutes and 26 seconds
......@@ -120,8 +120,8 @@ void GenericRSTransform<TScalarType, NInputDimensions, NOutputDimensions>::Insta
// If not, try to make a RPC sensor model
if ((m_InputTransform.IsNull()) && (m_InputImd != nullptr) && (m_InputImd->Has(MDGeom::RPC)))
{
typedef otb::SensorTransformFactory<double, InputSpaceDimension, OutputSpaceDimension> SensorTransformModelFactoryType;
auto sensorModel = SensorTransformModelFactoryType::CreateTransform(*m_InputImd,TransformDirection::FORWARD);
auto sensorModel = otb::SensorTransformFactory::GetInstance().CreateTransform
<double, InputSpaceDimension, OutputSpaceDimension>(*m_InputImd,TransformDirection::FORWARD);
if (sensorModel != nullptr)
{
......@@ -150,8 +150,8 @@ void GenericRSTransform<TScalarType, NInputDimensions, NOutputDimensions>::Insta
// If not, try to make a RPC sensor model
if ((m_OutputTransform.IsNull()) && (m_OutputImd != nullptr) && (m_OutputImd->Has(MDGeom::RPC)))
{
typedef otb::SensorTransformFactory<double, InputSpaceDimension, OutputSpaceDimension> SensorTransformModelFactoryType;
auto sensorModel = SensorTransformModelFactoryType::CreateTransform(*m_OutputImd,TransformDirection::INVERSE);
auto sensorModel = otb::SensorTransformFactory::GetInstance().CreateTransform
<double, InputSpaceDimension, OutputSpaceDimension>(*m_OutputImd,TransformDirection::INVERSE);
if (sensorModel != nullptr)
{
......
......@@ -62,9 +62,10 @@ public:
/** Method to transform a point. */
OutputPointType TransformPoint(const InputPointType& point) const override;
protected:
RPCForwardTransform() : Superclass(TransformDirection::FORWARD) {} ;
RPCForwardTransform();
~RPCForwardTransform() = default;
protected:
void PrintSelf(std::ostream& os, itk::Indent indent) const override;
private:
......
......@@ -25,6 +25,9 @@
namespace otb
{
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
RPCForwardTransform<TScalarType, NInputDimensions, NOutputDimensions>::RPCForwardTransform() : Superclass(TransformDirection::FORWARD)
{}
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
typename RPCForwardTransform<TScalarType, NInputDimensions, NOutputDimensions>::OutputPointType
......
/*
* Copyright (C) 2005-2021 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbRPCForwardTransformFactory_h
#define otbRPCForwardTransformFactory_h
#include "itkObjectFactoryBase.h"
#include "itkImageIOBase.h"
namespace otb
{
/** \class RPCForwardTransformFactory
* \brief Creates an instance of RPCForwardTransform using itk object factory.
*
* \ingroup OTBTransform
*/
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
class ITK_EXPORT RPCForwardTransformFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef RPCForwardTransformFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
const char* GetITKSourceVersion(void) const override;
const char* GetDescription(void) const override;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(RPCForwardTransformFactory, itk::ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
RPCForwardTransformFactory<TScalarType,NInputDimensions,NOutputDimensions>::Pointer RPCForwardFactory = RPCForwardTransformFactory::New();
itk::ObjectFactoryBase::RegisterFactory(RPCForwardFactory);
}
protected:
RPCForwardTransformFactory();
~RPCForwardTransformFactory() override = default;
private:
RPCForwardTransformFactory(const Self&) = delete;
void operator=(const Self&) = delete;
};
}
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbRPCForwardTransformFactory.hxx"
#endif
#endif // OTBRPCFORWARDTRANSFORMFACTORY_H
......@@ -62,9 +62,10 @@ public:
/** Method to transform a point. */
OutputPointType TransformPoint(const InputPointType& point) const override;
protected:
RPCInverseTransform() : Superclass(TransformDirection::INVERSE) {};
RPCInverseTransform();
~RPCInverseTransform() = default;
protected:
void PrintSelf(std::ostream& os, itk::Indent indent) const override;
private:
......
......@@ -25,6 +25,9 @@
namespace otb
{
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
RPCInverseTransform<TScalarType, NInputDimensions, NOutputDimensions>::RPCInverseTransform() : Superclass(TransformDirection::INVERSE)
{}
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
typename RPCInverseTransform<TScalarType, NInputDimensions, NOutputDimensions>::OutputPointType
......
/*
* Copyright (C) 2005-2021 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbRPCInverseTransformFactory_h
#define otbRPCInverseTransformFactory_h
#include "itkObjectFactoryBase.h"
#include "itkImageIOBase.h"
namespace otb
{
/** \class RPCInverseTransformFactory
* \brief Creates an instance of RPCInverseTransform using itk object factory.
*
* \ingroup OTBTransform
*/
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
class ITK_EXPORT RPCInverseTransformFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef RPCInverseTransformFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
const char* GetITKSourceVersion(void) const override;
const char* GetDescription(void) const override;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(RPCInverseTransformFactory, itk::ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
RPCInverseTransformFactory<TScalarType,NInputDimensions,NOutputDimensions>::Pointer RPCInverseFactory = RPCInverseTransformFactory::New();
itk::ObjectFactoryBase::RegisterFactory(RPCInverseFactory);
}
protected:
RPCInverseTransformFactory();
~RPCInverseTransformFactory() override = default;
private:
RPCInverseTransformFactory(const Self&) = delete;
void operator=(const Self&) = delete;
};
}
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbRPCInverseTransformFactory.hxx"
#endif
#endif // OTBRPCINVERSETRANSFORMFACTORY_H
......@@ -19,10 +19,9 @@
*/
#ifndef otbSensorTransformFactory_h
#define otbSensorTransformFactory_h
#include "otbSensorTransformBase.h"
#include "itkObject.h"
#include "itkObjectFactory.h"
#include "itkMutexLock.h"
#include "itkMacro.h"
namespace otb
{
......@@ -31,43 +30,26 @@ namespace otb
*
* \ingroup OTBTransform
*/
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
class SensorTransformFactory : public itk::Object
//template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
class ITK_EXPORT SensorTransformFactory : boost::noncopyable
{
public:
/** Standard class typedefs. */
typedef SensorTransformFactory Self;
typedef itk::Object Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef typename SensorTransformBase<TScalarType, NInputDimensions,NOutputDimensions>::Pointer SensorTransformTypePointer;
/** Standard class typedefs. */
using Self = SensorTransformFactory;
/** Run-time type information (and related methods). */
itkTypeMacro(SensorTransformFactory, itk::Object);
/** Retrieve the singleton instance */
static SensorTransformFactory & GetInstance();
/** Create the appropriate transform. */
static SensorTransformTypePointer CreateTransform(const ImageMetadata &imd,TransformDirection d);
static void CleanFactories();
protected:
SensorTransformFactory();
~SensorTransformFactory() override;
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
typename otb::SensorTransformBase<TScalarType, NInputDimensions, NOutputDimensions>::Pointer
CreateTransform(const ImageMetadata &imd, TransformDirection d) const;
private:
SensorTransformFactory() = default;
~SensorTransformFactory() = default;
SensorTransformFactory(const Self&) = delete;
void operator=(const Self&) = delete;
static itk::SimpleMutexLock m_mutex;
/** Register Built-in factories */
static void RegisterBuiltInFactories();
/** Register a single factory, ensuring it has not been registered
* twice */
static void RegisterFactory(itk::ObjectFactoryBase* factory);
static void DoRegisterBuiltInFactories();
void operator=(const Self&) = delete;
Please register or sign in to reply
};
}
......@@ -75,4 +57,4 @@ private:
#include "otbSensorTransformFactory.hxx"
#endif
#endif // OTBSENSORTRANSFORMFACTORY_H
#endif // otbSensorTransformFactory_h
......@@ -20,97 +20,44 @@
#ifndef otbSensorTransformFactory_hxx
#define otbSensorTransformFactory_hxx
#include "otbImageMetadata.h"
#include "otbSensorTransformFactory.h"
#include "otbRPCTransformBase.h"
#include "otbRPCForwardTransformFactory.h"
#include "otbRPCInverseTransformFactory.h"
#include "itkMutexLockHolder.h"
#include "otbTransformFactories.h"
#include <functional>
namespace otb
{
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
itk::SimpleMutexLock SensorTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::m_mutex;
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
typename SensorTransformBase<TScalarType, NInputDimensions,NOutputDimensions>::Pointer
SensorTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::CreateTransform(const ImageMetadata &imd,TransformDirection direction)
typename otb::SensorTransformBase<TScalarType, NInputDimensions, NOutputDimensions>::Pointer
SensorTransformFactory::CreateTransform(const ImageMetadata &imd, TransformDirection direction) const
{
RegisterBuiltInFactories();
auto possibleobjects = itk::ObjectFactoryBase::CreateAllInstance("otbRPCTransformBase");
//TODO: add a list of possible SAR objects and concatenate rpc and sar list in one main list
for (auto && po : possibleobjects)
// Instanciate the factories
std::vector<
std::function<
typename otb::SensorTransformBase<double, NInputDimensions, NOutputDimensions>::Pointer (const ImageMetadata &)
>
> factories;
factories.push_back(TransformFactories::RPCForwardTransformFactory<TScalarType, NInputDimensions, NOutputDimensions>);
factories.push_back(TransformFactories::RPCInverseTransformFactory<TScalarType, NInputDimensions, NOutputDimensions>);
typename otb::SensorTransformBase<TScalarType, NInputDimensions, NOutputDimensions>::Pointer transformPointer;
for (auto& transformFactory : factories)
{
SensorTransformBase<TScalarType, NInputDimensions,NOutputDimensions>* io = dynamic_cast<SensorTransformBase<TScalarType, NInputDimensions,NOutputDimensions>*>(po.GetPointer());
if (io)
transformPointer = transformFactory(imd);
if (transformPointer)
{
io->SetMetadata(imd);
if (io->IsValidSensorModel() && io->getDirection() == direction)
{
return io;
}
if (transformPointer->IsValidSensorModel() && transformPointer->getDirection() == direction)
{
return transformPointer;
}
}
//io is null is possible because createAllInstance will return all known instances with different types like SensorTransform<double,2,2> SensorTransform<double,3,3> which has been registered before
}
// if no object has been found, we have to warn the user
otbLogMacro(Warning, << "The SensorTransform factory could not find a compatible Sensor Transform");
return nullptr;
}
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
void SensorTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::DoRegisterBuiltInFactories()
{
itk::ObjectFactoryBase::RegisterFactory(RPCForwardTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::New());
itk::ObjectFactoryBase::RegisterFactory(RPCInverseTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::New());
}
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
void SensorTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::RegisterBuiltInFactories()
{
static std::once_flag reg_flag;
std::call_once(reg_flag, &SensorTransformFactory<TScalarType, NInputDimensions, NOutputDimensions>::DoRegisterBuiltInFactories);
}
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
void SensorTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::RegisterFactory(itk::ObjectFactoryBase* factory)
{
// Unregister any previously registered factory of the same class
// Might be more intensive but static bool is not an option due to
// ld error.
itk::ObjectFactoryBase::UnRegisterFactory(factory);
itk::ObjectFactoryBase::RegisterFactory(factory);
}
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
void SensorTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::CleanFactories()
{
itk::MutexLockHolder<itk::SimpleMutexLock> lockHolder(m_mutex);
std::list<itk::ObjectFactoryBase*> factories = itk::ObjectFactoryBase::GetRegisteredFactories();
std::list<itk::ObjectFactoryBase*>::iterator itFac;
for (itFac = factories.begin(); itFac != factories.end(); ++itFac)
{
RPCForwardTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>* rpcForwardFactory =
dynamic_cast<RPCForwardTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>*>(*itFac);
if (rpcForwardFactory)
{
itk::ObjectFactoryBase::UnRegisterFactory(rpcForwardFactory);
continue;
}
RPCInverseTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>* rpcInverseFactory =
dynamic_cast<RPCInverseTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>*>(*itFac);
if (rpcInverseFactory)
{
itk::ObjectFactoryBase::UnRegisterFactory(rpcInverseFactory);
continue;
}
}
}
} // end namespace otb
#endif
/*
* Copyright (C) 2005-2021 Centre National d'Etudes Spatiales (CNES)
* Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
......@@ -17,35 +17,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbRPCInverseTransformFactory_hxx
#define otbRPCInverseTransformFactory_hxx
#include "otbRPCInverseTransformFactory.h"
#ifndef otbTransformFactory_h
#define otbTransformFactory_h
#include "otbCast.h"
#include "otbImageMetadata.h"
#include "otbSensorTransformBase.h"
#include "otbRPCForwardTransform.h"
#include "otbRPCInverseTransform.h"
#include "itkCreateObjectFunction.h"
#include "itkVersion.h"
namespace otb
{
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
RPCInverseTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::RPCInverseTransformFactory()
{
this->RegisterOverride("otbRPCTransformBase", "otbRPCInverseTransform", "RPC Inverse Transform", 1,
itk::CreateObjectFunction<RPCInverseTransform<TScalarType,NInputDimensions,NOutputDimensions>>::New());
}
namespace otb {
/** \namespace TransformFactories
* \brief Contains the functions (factories) used to instanciate the transformation classes.
*
* Each function is in charge of instanciating a specific transformation classes. It is
* templated with the scalar type used in the Sensor Model, the dimension of the
* inpute space, and the dimension of the output space. It takes as parameter a
* reference to the ImageMetadata object used to instanciate the Sensor Model.
* It returns an instance of otb::SensorTransformBase.
*
* \ingroup OTBTransform
*/
namespace TransformFactories {
/**
* Factory for the forward transformer based of the RPC sensor model
*/
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
const char* RPCInverseTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::GetITKSourceVersion(void) const
typename otb::SensorTransformBase<double, NInputDimensions, NOutputDimensions>::Pointer
RPCForwardTransformFactory(const ImageMetadata &imd)
{
return ITK_SOURCE_VERSION;
if(imd.Has(MDGeom::RPC))
{
auto transform = RPCForwardTransform<TScalarType, NInputDimensions,NOutputDimensions>::New();
transform->SetMetadata(imd);
return DynamicCast<typename otb::SensorTransformBase<double, NInputDimensions, NOutputDimensions>>(transform);
}
return nullptr;
}
/**
* Factory for the inverse transformer based of the RPC sensor model
*/
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
const char* RPCInverseTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::GetDescription() const
typename otb::SensorTransformBase<double, NInputDimensions, NOutputDimensions>::Pointer
RPCInverseTransformFactory(const ImageMetadata &imd)
{
return "RPC Inverse Transform factory";
if(imd.Has(MDGeom::RPC))
{
auto transform = RPCInverseTransform<TScalarType, NInputDimensions,NOutputDimensions>::New();
transform->SetMetadata(imd);
return DynamicCast<typename otb::SensorTransformBase<double, NInputDimensions, NOutputDimensions>>(transform);
}
return nullptr;
}
}
}
#endif
......@@ -21,6 +21,7 @@
set(OTBTransform_SRC
otbSensorModelAdapter.cxx
otbSarSensorModelAdapter.cxx
otbSensorTransformFactory.cxx
)
add_library(OTBTransform ${OTBTransform_SRC})
......
/*
* Copyright (C) 2005-2021 Centre National d'Etudes Spatiales (CNES)
* Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
......@@ -17,35 +17,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbRPCForwardTransformFactory_hxx
#define otbRPCForwardTransformFactory_hxx
#include "otbRPCForwardTransformFactory.h"
#include "otbRPCForwardTransform.h"
#include "itkCreateObjectFunction.h"
#include "itkVersion.h"
#include "otbSensorTransformFactory.h"
namespace otb
{
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
RPCForwardTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::RPCForwardTransformFactory()
{
this->RegisterOverride("otbRPCTransformBase", "otbRPCForwardTransform", "RPC Forward Transform", 1,
itk::CreateObjectFunction<RPCForwardTransform<TScalarType,NInputDimensions,NOutputDimensions>>::New());
}
namespace otb {
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
const char* RPCForwardTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::GetITKSourceVersion(void) const
// Meyer singleton design pattern
SensorTransformFactory & SensorTransformFactory::GetInstance()
{
return ITK_SOURCE_VERSION;
static SensorTransformFactory s_instance;
return s_instance;
}
template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
const char* RPCForwardTransformFactory<TScalarType, NInputDimensions,NOutputDimensions>::GetDescription() const
{
return "RPC Forward Transform factory";
}
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment