Commit c4a1e7c1 authored by Sébastien Dinot's avatar Sébastien Dinot

MRG

parents fe26b79a aa77830b
......@@ -148,14 +148,15 @@ private:
void DoExecute()
{
otb::ogr::DataSource::Pointer ogrDS;
UInt8ImageType::Pointer referenceImage;
m_OgrDS = otb::ogr::DataSource::New(GetParameterString("in"), otb::ogr::DataSource::Modes::read);
ogrDS = otb::ogr::DataSource::New(GetParameterString("in"), otb::ogr::DataSource::Modes::read);
bool validInputProjRef = false;
std::string inputProjectionRef = "";
otb::ogr::DataSource::const_iterator lit = m_OgrDS->begin();
otb::ogr::DataSource::const_iterator lit = ogrDS->begin();
// Retrieve extent
double ulx, uly, lrx, lry;
......@@ -163,9 +164,9 @@ private:
try
{
inputProjectionRef = m_OgrDS->GetGlobalExtent(ulx,uly,lrx,lry);
inputProjectionRef = ogrDS->GetGlobalExtent(ulx,uly,lrx,lry);
}
catch(itk::ExceptionObject & err)
catch(const itk::ExceptionObject&)
{
extentAvailable = false;
}
......@@ -178,7 +179,7 @@ private:
try
{
inputProjectionRef = m_OgrDS->GetGlobalExtent(ulx,uly,lrx,lry,true);
inputProjectionRef = ogrDS->GetGlobalExtent(ulx,uly,lrx,lry,true);
extentAvailable = true;
}
catch(itk::ExceptionObject & err)
......@@ -310,7 +311,7 @@ private:
}
m_OGRDataSourceRendering = OGRDataSourceToMapFilterType::New();
m_OGRDataSourceRendering->AddOGRDataSource(m_OgrDS);
m_OGRDataSourceRendering->AddOGRDataSource(ogrDS);
m_OGRDataSourceRendering->SetOutputSize(size);
m_OGRDataSourceRendering->SetOutputOrigin(origin);
m_OGRDataSourceRendering->SetOutputSpacing(spacing);
......@@ -342,7 +343,6 @@ private:
}
otb::ogr::DataSource::Pointer m_OgrDS;
OGRDataSourceToMapFilterType::Pointer m_OGRDataSourceRendering;
};
......
......@@ -179,8 +179,8 @@ void otb::ReprojectTransformationFunctor::apply_inplace(OGRGeometry * inout) con
/*===========================================================================*/
otb::GeometriesProjectionFilter::GeometriesProjectionFilter()
: InputImageReference(*this)
, OutputImageReference(*this)
: m_InputImageReference(*this)
, m_OutputImageReference(*this)
{
}
......@@ -215,10 +215,10 @@ void otb::GeometriesProjectionFilter::DoFinalizeInitialisation()
m_Transform->SetGeoidFile(m_GeoidFile);
m_Transform->SetAverageElevation(k_averageElevation);
m_Transform->SetInputSpacing(InputImageReference.GetSpacing());
m_Transform->SetInputOrigin(InputImageReference.GetOrigin());
m_Transform->SetOutputSpacing(OutputImageReference.GetSpacing());
m_Transform->SetOutputOrigin(OutputImageReference.GetOrigin());
m_Transform->SetInputSpacing(m_InputImageReference.GetSpacing());
m_Transform->SetInputOrigin(m_InputImageReference.GetOrigin());
m_Transform->SetOutputSpacing(m_OutputImageReference.GetSpacing());
m_Transform->SetOutputOrigin(m_OutputImageReference.GetOrigin());
// As the InputProjectionRef can't be known yet, InstanciateTransform() will
// be called from DoProcessLayer
......@@ -233,7 +233,7 @@ void otb::GeometriesProjectionFilter::DoFinalizeInitialisation()
// InputGeometriesType::ConstPointer input = this->GetInput();
OutputGeometriesType::Pointer output = this->GetOutput();
output->SetImageReference(OutputImageReference);
output->SetImageReference(m_OutputImageReference);
}
/*virtual*/
......@@ -260,7 +260,6 @@ void otb::GeometriesProjectionFilter::DoProcessLayer(ogr::Layer const& source, o
m_Transform->SetInputProjectionRef(source.GetProjectionRef());
m_Transform->InstanciateTransform();
// std::cout << "GPF::DoProcessLayer: L("<<source.GetName()<<") -> L("<<destination.GetName()<<") ...\n";
if (source != destination)
{
m_TransformationFunctor(source, destination); // if TransformedElementType == layer
......@@ -275,6 +274,5 @@ void otb::GeometriesProjectionFilter::DoProcessLayer(ogr::Layer const& source, o
void otb::GeometriesProjectionFilter::DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const
{
std::cout << "otb::GeometriesProjectionFilter::DoDefineNewLayerFields\n";
m_TransformationFunctor.DefineFields(source, dest);
}
......@@ -29,10 +29,25 @@ class OGRCoordinateTransformation;
namespace otb
{
/**\ingroup Projection GeometriesFilters
* Internal functor used to reproject a \c OGRGeometry.
*
* \internal
* As \c OGRGeometry isn't open to new functions through a \em Visitor design
* pattern, this class use a nasty hack: it try to downcast to any possible
* subtype of \c OGRGeometry.
*
* \since OTB v 3.14.0
* \todo Move into an \c internal namespace.
*/
struct ReprojectTransformationFunctor
{
typedef OGRGeometry TransformedElementType;
/**\ingroup Projection GeometriesFilters
* Internal functor used to reproject a \c OGRGeometry: \em By-Copy transformation policy.
* \since OTB v 3.14.0
*/
struct ByCopy
{
ByCopy(ReprojectTransformationFunctor const& reprojector) : m_Reprojector(reprojector){}
......@@ -42,6 +57,10 @@ struct ReprojectTransformationFunctor
ReprojectTransformationFunctor const& m_Reprojector;
};
/**\ingroup Projection GeometriesFilters
* Internal functor used to reproject a \c OGRGeometry: \em In-Place transformation policy.
* \since OTB v 3.14.0
*/
struct InPlace
{
InPlace(ReprojectTransformationFunctor const& reprojector) : m_Reprojector(reprojector){}
......@@ -80,6 +99,28 @@ private:
};
/**\ingroup Projection GeometriesFilters
* \class GeometriesProjectionFilter
* Projection filter for OGR geometries sets.
* \since OTB v 3.14.0
*
* \param[in] InputGeometriesSet
* \param[in] InputKeywordList if the \em InputGeometriesSet doesn't have a
* projection reference (i.e. a \c OGRSpatialReference), this filter will use
* the \em InputKeywordList to describe the positionning of the geometries set.
*
* \param[in,out] OutputGeometriesSet This set of geometries needs to be given to
* the filter (in order to set the exact output file/OGR driver). However the
* filter is in charge of filling the geometries set.
* \param[in] OutputProjectionRef wkt description of the \c OGRSpatialReference
* to project the \em InputGeometriesSet into.
* \param[in] OutputKeywordList if no \em OutputProjectionRef is set, the
* projection will be done according to the \em OutputKeywordList.
*
* \note Unlike \c VectorDataProjectionFilter, we have to explicitly set which
* to use between projection reference or keyword list. There is no \em
* MetaDataDictionary property.
*/
class ITK_EXPORT GeometriesProjectionFilter : public GeometriesToGeometriesFilter
{
public:
......@@ -106,11 +147,8 @@ public:
// typedef Superclass::InputGeometriesPointer InputGeometriesPointer;
typedef Superclass::OutputGeometriesType OutputGeometriesType;
// typedef Superclass::OutputGeometriesPointer OutputGeometriesPointer;
//@}
typedef ogr::ImageReference<double> ImageReference;
/**\name Class typedefs */
//@{
typedef ogr::ImageReference<double> ImageReference;
//@}
private:
......@@ -128,9 +166,25 @@ protected:
virtual void GenerateOutputInformation(void);
public:
ImageReference InputImageReference;
ImageReference OutputImageReference;
/**\name Image Reference (origin, spacing) */
//@{
void SetInputSpacing(ImageReference::SpacingType const& spacing)
{
m_InputImageReference.SetSpacing(spacing);
}
void SetOutputSpacing(ImageReference::SpacingType const& spacing)
{
m_OutputImageReference.SetSpacing(spacing);
}
void SetInputOrigin(ImageReference::OriginType const& origin)
{
m_InputImageReference.SetOrigin(origin);
}
void SetOutputOrigin(ImageReference::OriginType const& origin)
{
m_OutputImageReference.SetOrigin(origin);
}
//@}
/**\name Keywords lists accessors and mutators */
//@{
itkGetMacro(InputKeywordList, ImageKeywordlist);
......@@ -176,6 +230,12 @@ private:
InternalTransformPointerType m_Transform;
//@}
/**\name Image Reference (origin, spacing) */
//@{
ImageReference m_InputImageReference;
ImageReference m_OutputImageReference;
//@}
std::string m_OutputProjectionRef; // in WKT format!
ImageKeywordlist m_InputKeywordList;
ImageKeywordlist m_OutputKeywordList;
......
......@@ -151,30 +151,3 @@ void otb::GeometriesSet::PrintSelf(std::ostream& os, itk::Indent indent) const
{
this->apply(Printer(os, indent));
}
#if 0
/*===========================================================================*/
/*=========================[ GetMetaDataDictionary ]=========================*/
/*===========================================================================*/
struct MetaDataDictionaryGetter : boost::static_visitor<itk::MetaDataDictionary&>
{
itk::MetaDataDictionary& operator()(otb::ogr::Layer layer) const
{
return layer.GetMetaDataDictionary();
}
itk::MetaDataDictionary& operator()(otb::ogr::DataSource::Pointer datasource) const
{
return datasource->GetMetaDataDictionary();
}
};
itk::MetaDataDictionary & otb::GeometriesSet::GetMetaDataDictionary()
{
return this->apply(MetaDataDictionaryGetter());
}
itk::MetaDataDictionary const& otb::GeometriesSet::GetMetaDataDictionary() const
{
return const_cast <GeometriesSet *>(this)->GetMetaDataDictionary();
}
#endif
......@@ -113,14 +113,6 @@ public:
*/
bool IsSet() const;
#if 0
/**\name Meta data dictionary */
//@{
itk::MetaDataDictionary & GetMetaDataDictionary();
itk::MetaDataDictionary const& GetMetaDataDictionary() const;
//@}
#endif
/**\name Image reference (spacing + origin) */
//@{
typedef ogr::ImageReference<double> ImageReference;
......
......@@ -139,13 +139,6 @@ otb::GeometriesToGeometriesFilter::GetInput(void )
void otb::GeometriesToGeometriesFilter::GenerateOutputInformation(void )
{
Superclass::GenerateOutputInformation();
#if 0
// Apply only with data sources
OutputGeometriesType::Pointer output = this->GetOutput();
InputGeometriesType::Pointer input = this->GetInput();
output->SetMetaDataDictionary(input->GetMetaDataDictionary());
#endif
}
/*virtual*/
......
......@@ -120,6 +120,11 @@ private:
*/
virtual std::vector<std::string> DoDefineNewLayerOptions(ogr::Layer const& source) const;
/**
* Hook used to define the fields of the new layer.
* \param[in] source source \c Layer -- for reference
* \param[in,out] dest destination \c Layer
*/
virtual void DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const = 0;
/** Hook used to conclude the initialization phase.
......@@ -134,33 +139,55 @@ private:
friend struct ::ProcessVisitor;
};
/**\ingroup GeometriesFilters
* Helper class to operate an exact copy of the fields from a source layer.
* \since OTB v 3.14.0
*/
struct FieldCopyTransformation
{
OGRFeatureDefn & getDefinition(ogr::Layer & outLayer) const
{
return outLayer.GetLayerDefn();
}
/**
* In-place transformation: does nothing.
* \param[in] inoutFeature \c Feature to change.
* \throw Nothing
*/
void fieldsTransform(ogr::Feature const& inoutFeature) const
{
// default => do nothing for in-place transformation
}
/**
* By-Copy transformation: copies all fields.
* \param[in] inFeature input \c Feature
* \param[in,out] outFeature output \c Feature
*
* \throw itk::ExceptionObject if the fields cannot be copied.
*/
void fieldsTransform(ogr::Feature const& inFeature, ogr::Feature & outFeature) const
{
// default => copy all fields for copy transformation
assert(inFeature.GetSize() == outFeature.GetSize());
//assert(inFeature.GetSize() == outFeature.GetSize());
for (size_t i=0,N=inFeature.GetSize(); i!=N; ++i)
{
outFeature[i].Assign(inFeature[i]);
outFeature[inFeature[i].GetName()].Assign(inFeature[i]);
}
}
/**
* Defines the fields in the destination layer.
* \param[in] source source \c Layer
* \param[in,out] dest destination \c Layer
* \throw itk::ExceptionObject in case the operation can't succeed.
*/
void DefineFields(ogr::Layer const& source, ogr::Layer & dest) const
{
std::cout << " FieldCopyTransformation::DefineFields()\n";
OGRFeatureDefn & inDefinition = source.GetLayerDefn();
for (int i=0,N=inDefinition.GetFieldCount(); i!=N; ++i)
{
std::cout << " - " << ogr::FieldDefn(*inDefinition.GetFieldDefn(i)) << "\n";
dest.CreateField(*inDefinition.GetFieldDefn(i));
}
}
......
......@@ -132,52 +132,101 @@ otb::ogr::DataSource::DataSource(OGRDataSource * source)
{
}
otb::ogr::DataSource::Pointer otb::ogr::DataSource::CreateDataSourceFromDriver(std::string const& filename)
{
// Hand made factory based on file extension.
char const* driverName = DeduceDriverName(filename);
if (!driverName)
{
itkGenericExceptionMacro(<< "No OGR driver known to OTB to create and handle a DataSource named <"
<<filename<<">.");
}
OGRSFDriver * d = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName);
assert(d && "OGR driver not found");
OGRDataSource * source = d->CreateDataSource(filename.c_str());
if (!source) {
itkGenericExceptionMacro(<< "Failed to create OGRDataSource <"<<filename
<<"> (driver name: " << driverName<<">: " << CPLGetLastErrorMsg());
}
source->SetDriver(d);
otb::ogr::DataSource::Pointer res = new otb::ogr::DataSource(source);
res->UnRegister();
return res;
}
otb::ogr::DataSource::Pointer
otb::ogr::DataSource::New(std::string const& filename, Modes::type mode)
{
Drivers::Init();
const bool update = mode & Modes::write;
const bool write = mode & Modes::write;
// std::cout << "Opening datasource " << filename << " update=" << update << "\n";
if (itksys::SystemTools::FileExists(filename.c_str()))
{
OGRDataSource * source = OGRSFDriverRegistrar::Open(filename.c_str(), update);
if (!source)
if (mode & Modes::read)
{
itkGenericExceptionMacro(<< "Failed to open OGRDataSource file "
<< filename<<": " << CPLGetLastErrorMsg());
// Open in read mode
OGRDataSource * source = OGRSFDriverRegistrar::Open(filename.c_str(), FALSE);
if (!source)
{
itkGenericExceptionMacro(<< "Failed to open OGRDataSource file "
<< filename<<": " << CPLGetLastErrorMsg());
}
Pointer res = new DataSource(source);
res->UnRegister();
return res;
}
Pointer res = new DataSource(source);
res->UnRegister();
return res;
}
else if (mode & Modes::append)
{
// Open in "update" mode
OGRDataSource * source = OGRSFDriverRegistrar::Open(filename.c_str(), TRUE);
if (!source)
{
itkGenericExceptionMacro(<< "Failed to open OGRDataSource file "
<< filename<<": " << CPLGetLastErrorMsg());
}
Pointer res = new DataSource(source);
res->UnRegister();
return res;
}
else if (mode & Modes::write)
{
// Attempt to delete the datasource if it already exists
OGRDataSource * poDS = OGRSFDriverRegistrar::Open(filename.c_str(), TRUE);
if (poDS != NULL)
{
OGRSFDriver * ogrDriver = poDS->GetDriver();
OGRDataSource::DestroyDataSource(poDS);
//Erase the data if possible
if (ogrDriver->TestCapability(ODrCDeleteDataSource))
{
//Delete datasource
OGRErr ret = ogrDriver->DeleteDataSource(filename.c_str());
if (ret != OGRERR_NONE)
{
itkGenericOutputMacro(<< "Deletion of data source " << filename
<< " failed: " << CPLGetLastErrorMsg());
}
}
else
{
itkGenericOutputMacro(<< "Cannot delete data source " << filename);
}
} // if (poDS != NULL)
} // else if (update)
} // if (itksys::SystemTools::FileExists(filename.c_str()))
else
{
if (! update)
// File does not exists
if (mode & Modes::read || mode & Modes::append)
{
itkGenericExceptionMacro(<< "No DataSource named <"<<filename<<"> exists,"
" and the file opening mode does not permit updates. DataSource creation is thus aborted.");
}
// Hand made factory based on file extension.
char const* driverName = DeduceDriverName(filename);
if (!driverName)
{
itkGenericExceptionMacro(<< "No OGR driver known to OTB to create and handle a DataSource named <"
<<filename<<">.");
}
OGRSFDriver * d = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName);
assert(d && "OGR driver not found");
OGRDataSource * source = d->CreateDataSource(filename.c_str());
if (!source) {
itkGenericExceptionMacro(<< "Failed to create OGRDataSource <"<<filename
<<"> (driver name: " << driverName<<">: " << CPLGetLastErrorMsg());
}
source->SetDriver(d);
Pointer res = new DataSource(source);
res->UnRegister();
return res;
}
return CreateDataSourceFromDriver(filename);
}
/*static*/
......@@ -391,6 +440,11 @@ OGREnvelope otb::ogr::DataSource::GetGlobalExtent(bool force/* = false */, std::
const OGRSpatialReference * ref_srs = lit->GetSpatialRef();
OGREnvelope sExtent = lit->GetExtent(force);
if (outwkt)
{
*outwkt = lit->GetProjectionRef();
}
++lit;
for(; lit!=this->end(); ++lit)
......@@ -399,7 +453,7 @@ OGREnvelope otb::ogr::DataSource::GetGlobalExtent(bool force/* = false */, std::
const OGRSpatialReference * current_srs = lit->GetSpatialRef();
// If both srs are valid and if they are different
// If both srs are valid and if they are different
if(ref_srs && current_srs && current_srs->IsSame(ref_srs) == 0)
{
// Reproject cExtent in ref_srs
......@@ -434,10 +488,6 @@ OGREnvelope otb::ogr::DataSource::GetGlobalExtent(bool force/* = false */, std::
sExtent.Merge(cExtent);
} // for each layer
if (outwkt)
{
*outwkt = lit->GetProjectionRef();
}
return sExtent;
}
......
......@@ -94,7 +94,7 @@ public:
* \note Read/Write mode should have been <tt>read | write</tt>, but actually
* OGR data source are always at least in read mode.
*/
struct Modes { enum type { invalid, read=1, write=2, MAX__ }; };
struct Modes { enum type { invalid, read=1, write=2, append=4, MAX__ }; };
/**
* Builder from an existing named data source.
......@@ -471,6 +471,8 @@ protected:
*/
virtual ~DataSource();
static Pointer CreateDataSourceFromDriver(std::string const& filename);
/** Prints self into stream. */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
......
......@@ -27,12 +27,20 @@ namespace otb
{
namespace ogr
{
/**\ingroup boost
* \brief propagation of const-qualifier.
* \note This type traits is likelly to appear in boost at some point in time.
* \note As a consequence, it follows C++ standard and boost naming policy.
* \since OTB v 3.14.0
* @{
*/
template <typename Tin, typename Tout>
struct propagate_const
{ typedef Tout type; };
template <typename Tin, typename Tout>
struct propagate_const<Tin const, Tout>
{ typedef typename boost::add_const<Tout>::type type; };
/** @} */
#define TRY_APPLY(TYPE, geometry, functor) \
if (typename propagate_const<TGeometry, TYPE>::type * dc \
......@@ -42,6 +50,22 @@ if (typename propagate_const<TGeometry, TYPE>::type * dc \
}
/**\ingroup gGeometry
* External polymorphic call of functions on \c OGRGeometry.
* This helper function tries to polymorphically dispatch the call of a function
* on the right \c OGRGeometry subtype.
* \internal
* In a perfect world, \c OGRGeometry would have provided a visitor to extend
* the number of functions to polymorphically %apply on them. As this isn't the
* case, \c apply executes many downcasts until it finds the right subtype.
*
* \tparam TResult type of the result
* \tparam TGeometry matched an \c OGRGeometry that may or may not be const
* qualified.
* \tparam TFunctor functor to apply on the geometry.
* \todo Support a list of types to check
* \since OTB v 3.14.0
*/
template <typename TResult, class TGeometry, typename TFunctor>
TResult apply(TGeometry * geometry, TFunctor functor)
{
......
......@@ -249,7 +249,7 @@ std::string otb::ogr::Layer::GetProjectionRef() const
if(res != OGRERR_NONE)
{
itkGenericExceptionMacro(<< "Cannot convert spatial reference to wkt string for layer <"
<<m_Layer->GetName()<<">: " << CPLGetLastErrorMsg());
<<GetName()<<">: " << CPLGetLastErrorMsg());
}
assert(wkt);
......
......@@ -58,6 +58,7 @@ namespace boost {
*
* \sa http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3350.html about
* \c contiguous_iterator_tag.
* \since OTB v 3.14.0
* @{
*/
template <typename Range> struct is_contiguous
......
......@@ -119,10 +119,10 @@ ENDIF(OTB_DATA_USE_LARGEINPUT)
IF(OTB_DATA_USE_LARGEINPUT)
ADD_TEST(prTeGeometriesProjectionTest ${EXE_TESTS}
--compare-ogr ${TOL}
${BASELINE}/vectorDataProjectionExample.shp
${BASELINE}/geometriesProjectionExample.shp
${TEMP}/geometriesProjectionExample.shp
GeometriesProjectionTest
${INPUTDATA}/Capitole-Shadows.kml
${INPUTDATA}/Capitole-Shadows.shp
${INPUTLARGEDATA}/QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF
${TEMP}/geometriesProjectionExample.shp
)
......
......@@ -35,8 +35,6 @@
#include "otbGeometriesProjectionFilter.h"
#include "otbGeometriesSet.h"
// #include "otbGeometriesFileReader.h"
// #include "otbGeometriesFileWriter.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
......@@ -130,8 +128,8 @@ int main(int argc, char* argv[])
// Software Guide : BeginCodeSnippet
filter->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist()); // nec qd capteur
filter->OutputImageReference.SetOrigin(imageReader->GetOutput()->GetOrigin()); // nec qd capteur
filter->OutputImageReference.SetSpacing(imageReader->GetOutput()->GetSpacing()); // nec qd capteur
filter->SetOutputOrigin(imageReader->GetOutput()->GetOrigin()); // nec qd capteur
filter->SetOutputSpacing(imageReader->GetOutput()->GetSpacing()); // nec qd capteur
filter->SetOutputProjectionRef( imageReader->GetOutput()->GetProjectionRef()); // ~ wkt
// Software Guide : EndCodeSnippet
......
......@@ -71,3 +71,29 @@ OTB_TEST_APPLICATION(NAME apTvRsRasterizationPolygons2LayersWith2SRS
VALID --compare-image ${NOTOL}
${BASELINE}/apTvRsRasterizationPolygons2LayersWith2SRS.tif
${TEMP}/apTvRsRasterizationPolygons2LayersWith2SRS.tif)
# Image in UTM, KML in WGS84
OTB_TEST_APPLICATION(NAME apTvRsRasterizationShadowsKML
APP Rasterization
OPTIONS -in ${INPUTDATA}/Capitole-Shadows.kml
-im ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
-out ${TEMP}/apTvRsRasterizationShadowsKML.tif
-background 255
-mode.binary.foreground 0
VALID --compare-image ${NOTOL}
${BASELINE}/apTvRsRasterizationShadowsKML.tif
${TEMP}/apTvRsRasterizationShadowsKML.tif)
# Image in UTM, SHP in UTM
OTB_TEST_APPLICATION(NAME apTvRsRasterizationShadowsSHP
APP Rasterization
OPTIONS -in ${INPUTDATA}/Capitole-Shadows.shp
-im ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
-out ${TEMP}/apTvRsRasterizationShadowsSHP.tif