Commit 24cde55a authored by Julien Michel's avatar Julien Michel
Browse files

ENH: Adding background and foreground value to rasterization filter, as well...

ENH: Adding background and foreground value to rasterization filter, as well as a flag to deactivate the buring of an attribute
parent edb9d609
/*=========================================================================
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 __otbOGRDataSourceToLabelImageFilter_h
#define __otbOGRDataSourceToLabelImageFilter_h
#include "itkImageToImageFilter.h"
#include "itkImageSource.h"
#include "otbMacro.h"
#include "gdal.h"
#include "gdal_alg.h"
#include "otbOGRDataSourceWrapper.h"
namespace otb {
/** \class OGRDataSourceToLabelImageFilter
* \brief Burn geometries from the specified VectorData into raster
*
* This class handles burning several input \c OGRDataSource into the
* output raster. It has two different modes:
* - either the burn values are extracted from a field set by
* the user (default field is DN). This is the default behaviour,
* - or the burn values are made of foreground (when inside
* geometries) and background (outside geometries) values, which can
* be set by the user. One can set this behaviour by disable the
* BurnAttributeMode using the BurnAttributeModeOff() method.
*
* Please note that the background value is also used in
* BurnAttributeModeOn() to fill areas where there are no geometries.
*
* Setting the output raster informations can be done in two ways by:
* - Setting the Origin/Size/Spacing of the output image
* - Using an existing image as support via SetOutputParametersFromImage(ImageBase)
*
*/
template < class TOutputImage >
class ITK_EXPORT OGRDataSourceToLabelImageFilter :
public itk::ImageSource<TOutputImage>
{
public:
/** Standard class typedefs */
typedef OGRDataSourceToLabelImageFilter Self;
typedef itk::ImageSource<TOutputImage> Superclass;
typedef itk::SmartPointer< Self > Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(OGRDataSourceToLabelImageFilter, itk::ImageSource);
/** Method for creation through the object factory. */
itkNewMacro(Self);
typedef TOutputImage OutputImageType;
typedef typename OutputImageType::Pointer OutputImagePointer;
typedef typename OutputImageType::SizeType OutputSizeType;
typedef typename OutputImageType::IndexType OutputIndexType;
typedef typename OutputImageType::SpacingType OutputSpacingType;
typedef typename OutputImageType::PointType OutputOriginType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
typedef typename OutputImageType::PixelType OutputImagePixelType;
typedef typename OutputImageType::InternalPixelType OutputImageInternalPixelType;
/** VectorData typedefs*/
typedef ogr::DataSource OGRDataSourceType;
typedef typename OGRDataSourceType::Pointer OGRDataSourcePointerType;
typedef ogr::Layer OGRLayerType;
typedef itk::ImageBase<OutputImageType::ImageDimension> ImageBaseType;
/** Get Nth input \c OGRDataSource */
const OGRDataSourceType* GetInput(unsigned int idx);
/** Method for adding a \c OGRDataSource to rasterize */
virtual void AddOGRDataSource(const OGRDataSourceType* ds);
/** Set the size of the output image. */
itkSetMacro(OutputSize, OutputSizeType);
/** Get the size of the output image. */
itkGetConstReferenceMacro(OutputSize, OutputSizeType);
/** Set the origin of the output image.
* \sa GetOrigin()
*/
itkSetMacro(OutputOrigin, OutputOriginType);
virtual void SetOutputOrigin(const double origin[2]);
virtual void SetOutputOrigin(const float origin[2]);
itkGetConstReferenceMacro(OutputOrigin, OutputOriginType);
/** Set the spacing (size of a pixel) of the output image.
* \sa GetSpacing()
*/
virtual void SetOutputSpacing(const OutputSpacingType& spacing);
virtual void SetOutputSpacing(const double spacing[2]);
virtual void SetOutputSpacing(const float spacing[2]);
/** Set/Get Output Projection Ref */
itkSetStringMacro(OutputProjectionRef);
itkGetStringMacro(OutputProjectionRef);
/** Set the attribute field on the \c OGRFeature to be used as burn value in the output image*/
itkSetStringMacro(BurnAttribute);
itkGetStringMacro(BurnAttribute);
/** Set/Get the background value */
itkSetMacro(BackgroundValue,OutputImageInternalPixelType);
itkGetConstReferenceMacro(BackgroundValue,OutputImageInternalPixelType);
/** Set/Get the foreground value */
itkSetMacro(ForegroundValue,OutputImageInternalPixelType);
itkGetConstReferenceMacro(ForegroundValue,OutputImageInternalPixelType);
/** Set/Get the BurnAttributeMode flag */
itkSetMacro(BurnAttributeMode,bool);
itkGetConstReferenceMacro(BurnAttributeMode,bool);
itkBooleanMacro(BurnAttributeMode);
/** Useful to set the output parameters from an existing image*/
void SetOutputParametersFromImage(const ImageBaseType * image);
protected:
virtual void GenerateData();
OGRDataSourceToLabelImageFilter();
virtual ~OGRDataSourceToLabelImageFilter() {}
virtual void GenerateOutputInformation();
void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
OGRDataSourceToLabelImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
std::vector< OGRLayerH > m_SrcDataSetLayers;
std::vector<int> m_BandsToBurn;
// Field used to extract the burn value
std::string m_BurnAttribute;
// Output params
std::string m_OutputProjectionRef;
OutputSpacingType m_OutputSpacing;
OutputOriginType m_OutputOrigin;
OutputSizeType m_OutputSize;
OutputIndexType m_OutputStartIndex;
OutputImageInternalPixelType m_BackgroundValue;
OutputImageInternalPixelType m_ForegroundValue;
bool m_BurnAttributeMode;
}; // end of class VectorDataToLabelImageFilter
} // end of namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbOGRDataSourceToLabelImageFilter.txx"
#endif
#endif
/*=========================================================================
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 "otbOGRDataSourceToLabelImageFilter.h"
#include "otbOGRIOHelper.h"
#include "otbGdalDataTypeBridge.h"
#include "otbMacro.h"
#include "gdal_alg.h"
namespace otb
{
template< class TOutputImage>
OGRDataSourceToLabelImageFilter<TOutputImage>
::OGRDataSourceToLabelImageFilter() : m_BurnAttribute("DN"),
m_BackgroundValue(0),
m_ForegroundValue(255),
m_BurnAttributeMode(true)
{
this->SetNumberOfRequiredInputs(1);
// Output parameters initialization
m_OutputSpacing.Fill(1.0);
m_OutputSize.Fill(0);
m_OutputStartIndex.Fill(0);
m_BandsToBurn.clear();
m_BandsToBurn.push_back(1);
}
template< class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::AddOGRDataSource(const OGRDataSourceType* ds)
{
this->itk::ProcessObject::PushBackInput( ds );
}
template < class TOutputImage>
const typename OGRDataSourceToLabelImageFilter<TOutputImage>::OGRDataSourceType *
OGRDataSourceToLabelImageFilter<TOutputImage>
::GetInput(unsigned int idx)
{
return static_cast<const OGRDataSourceType *>
(this->itk::ProcessObject::GetInput(idx));
}
template < class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::SetOutputSpacing(const OutputSpacingType& spacing)
{
if (this->m_OutputSpacing != spacing)
{
this->m_OutputSpacing = spacing;
this->Modified();
}
}
template < class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::SetOutputSpacing(const double spacing[2])
{
OutputSpacingType s(spacing);
this->SetOutputSpacing(s);
}
template < class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::SetOutputSpacing(const float spacing[2])
{
itk::Vector<float, 2> sf(spacing);
OutputSpacingType s;
s.CastFrom(sf);
this->SetOutputSpacing(s);
}
template < class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::SetOutputOrigin(const double origin[2])
{
OutputOriginType p(origin);
this->SetOutputOrigin(p);
}
template < class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::SetOutputOrigin(const float origin[2])
{
itk::Point<float, 2> of(origin);
OutputOriginType p;
p.CastFrom(of);
this->SetOutputOrigin(p);
}
template < class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::SetOutputParametersFromImage(const ImageBaseType * image)
{
const OutputImageType * src = dynamic_cast<const OutputImageType*>(image);
this->SetOutputOrigin ( src->GetOrigin() );
this->SetOutputSpacing ( src->GetSpacing() );
//this->SetOutputStartIndex ( src->GetLargestPossibleRegion().GetIndex() );
this->SetOutputSize ( src->GetLargestPossibleRegion().GetSize() );
this->SetOutputProjectionRef(src->GetProjectionRef());
//this->SetOutputKeywordList(src->GetImageKeywordlist());
}
template< class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::GenerateOutputInformation()
{
// get pointer to the output
OutputImagePointer outputPtr = this->GetOutput();
if (!outputPtr)
{
return;
}
// Set the size of the output region
typename TOutputImage::RegionType outputLargestPossibleRegion;
outputLargestPossibleRegion.SetSize(m_OutputSize);
//outputLargestPossibleRegion.SetIndex(m_OutputStartIndex);
outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
// Set spacing and origin
outputPtr->SetSpacing(m_OutputSpacing);
outputPtr->SetOrigin(m_OutputOrigin);
itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
itk::EncapsulateMetaData<std::string> (dict, MetaDataKey::ProjectionRefKey,
static_cast<std::string>(this->GetOutputProjectionRef()));
// Generate the OGRLayers from the input OGRDataSource
for (unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
{
OGRDataSourcePointerType ogrDS = dynamic_cast<OGRDataSourceType*>(this->itk::ProcessObject::GetInput(idx));
const unsigned int nbLayers = ogrDS->GetLayersCount();
for (unsigned int layer = 0; layer < nbLayers; ++layer)
{
m_SrcDataSetLayers.push_back( &(ogrDS->GetLayer(layer).ogr()) );
}
}
}
template< class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>::GenerateData()
{
// Call Superclass GenerateData
this->AllocateOutputs();
// Get the buffered region
OutputImageRegionType bufferedRegion = this->GetOutput()->GetBufferedRegion();
// nb bands
const unsigned int & nbBands = this->GetOutput()->GetNumberOfComponentsPerPixel();
// register drivers
GDALAllRegister();
std::ostringstream stream;
stream << "MEM:::"
<< "DATAPOINTER=" << (unsigned long)(this->GetOutput()->GetBufferPointer()) << ","
<< "PIXELS=" << bufferedRegion.GetSize()[0] << ","
<< "LINES=" << bufferedRegion.GetSize()[1]<< ","
<< "BANDS=" << nbBands << ","
<< "DATATYPE=" << GDALGetDataTypeName(GdalDataTypeBridge::GetGDALDataType<OutputImageInternalPixelType>()) << ","
<< "PIXELOFFSET=" << sizeof(OutputImageInternalPixelType) * nbBands << ","
<< "LINEOFFSET=" << sizeof(OutputImageInternalPixelType)*nbBands*bufferedRegion.GetSize()[0] << ","
<< "BANDOFFSET=" << sizeof(OutputImageInternalPixelType);
GDALDatasetH dataset = GDALOpen(stream.str().c_str(), GA_Update);
// Add the projection ref to the dataset
GDALSetProjection (dataset, this->GetOutput()->GetProjectionRef().c_str());
// Set the nodata value
for(unsigned int band = 0; band < nbBands;++band)
{
GDALRasterBandH hBand = GDALGetRasterBand(dataset, band + 1);
GDALSetRasterNoDataValue(hBand, m_BackgroundValue);
}
// add the geoTransform to the dataset
itk::VariableLengthVector<double> geoTransform(6);
// Reporting origin and spacing of the buffered region
// the spacing is unchanged, the origin is relative to the buffered region
OutputIndexType bufferIndexOrigin = bufferedRegion.GetIndex();
OutputOriginType bufferOrigin;
this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
geoTransform[0] = bufferOrigin[0];
geoTransform[3] = bufferOrigin[1];
geoTransform[1] = this->GetOutput()->GetSpacing()[0];
geoTransform[5] = this->GetOutput()->GetSpacing()[1];
// FIXME: Here component 1 and 4 should be replaced by the orientation parameters
geoTransform[2] = 0.;
geoTransform[4] = 0.;
GDALSetGeoTransform(dataset,const_cast<double*>(geoTransform.GetDataPointer()));
// Burn the geometries into the dataset
if (dataset != NULL)
{
std::vector<std::string> options;
std::vector<double> foreground(nbBands,m_ForegroundValue);
if(m_BurnAttributeMode)
{
options.push_back("ATTRIBUTE="+m_BurnAttribute);
}
GDALRasterizeLayers( dataset, nbBands,
&m_BandsToBurn[0],
m_SrcDataSetLayers.size(),
&(m_SrcDataSetLayers[0]),
NULL, NULL, &foreground[0],
ogr::StringListConverter(options).to_ogr(),
NULL, NULL );
// release the dataset
GDALClose( dataset );
}
}
template< class TOutputImage>
void
OGRDataSourceToLabelImageFilter<TOutputImage>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // end namespace otb
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