otbVectorDataToLabelImageCustomFilter.hxx 10.74 KiB
/*=========================================================================
  Copyright (c) Remi Cresson (IRSTEA). All rights reserved.
     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 __gtbVectorDataToLabelImageCustomFilter_txx
#define __gtbVectorDataToLabelImageCustomFilter_txx
#include "otbVectorDataToLabelImageCustomFilter.h"
#include "otbOGRIOHelper.h"
#include "otbGdalDataTypeBridge.h"
#include "otbMacro.h"
#include "gdal_alg.h"
#include "ogr_srs_api.h"
#include "itkImageRegionIterator.h"
namespace otb
template<class TVectorData, class TOutputImage>
VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>
::VectorDataToLabelImageCustomFilter()
 : m_OGRDataSourcePointer(0),
   m_BurnAttribute("FID"),
   m_BurnMaxValueMode(false)
  this->SetNumberOfRequiredInputs(1);
  // Output parameters initialization
  m_OutputSpacing.Fill(1.0);
  m_OutputSize.Fill(0);
  m_OutputStartIndex.Fill(0);
  // This filter is intended to work with otb::Image
  m_BandsToBurn.push_back(1);
  // Default burn value if no burnAttribute available
  m_DefaultBurnValue = 1.;
template<class TVectorData, class TOutputImage>
void
VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>
::AddVectorData(const VectorDataType* vd)
  this->itk::ProcessObject::PushBackInput( vd );
template <class TVectorData, class TOutputImage>
const typename VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>::VectorDataType *
VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>
::GetInput(unsigned int idx)
  return static_cast<const TVectorData *>
  (this->itk::ProcessObject::GetInput(idx));
template <class TVectorData, class TOutputImage>
void
VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>
::SetOutputSpacing(const OutputSpacingType& spacing)
  if (this->m_OutputSpacing != spacing)
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
this->m_OutputSpacing = spacing; this->Modified(); } } template <class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> ::SetOutputSpacing(const double spacing[2]) { OutputSpacingType s(spacing); this->SetOutputSpacing(s); } template <class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> ::SetOutputSpacing(const float spacing[2]) { itk::Vector<float, 2> sf(spacing); OutputSpacingType s; s.CastFrom(sf); this->SetOutputSpacing(s); } template <class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> ::SetOutputOrigin(const double origin[2]) { OutputOriginType p(origin); this->SetOutputOrigin(p); } template <class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> ::SetOutputOrigin(const float origin[2]) { itk::Point<float, 2> of(origin); OutputOriginType p; p.CastFrom(of); this->SetOutputOrigin(p); } template <class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> ::SetOutputParametersFromImage(const ImageBaseType * src) { this->SetOutputOrigin ( src->GetOrigin() ); this->SetOutputSignedSpacing ( src->GetSignedSpacing() ); this->SetOutputSize ( src->GetLargestPossibleRegion().GetSize() ); otb::ImageMetadataInterfaceBase::Pointer imi = otb::ImageMetadataInterfaceFactory::CreateIMI(src->GetMetaDataDictionary()); this->SetOutputProjectionRef(imi->GetProjectionRef()); } template<class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> ::GenerateOutputInformation() { // get pointer to the output OutputImagePointer outputPtr = this->GetOutput(); if (!outputPtr) { return; } // Set the size of the output region
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
typename TOutputImage::RegionType outputLargestPossibleRegion; outputLargestPossibleRegion.SetSize(m_OutputSize); //outputLargestPossibleRegion.SetIndex(m_OutputStartIndex); outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion); // Set spacing and origin outputPtr->SetSignedSpacing(m_OutputSpacing); outputPtr->SetOrigin(m_OutputOrigin); itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary(); itk::EncapsulateMetaData<std::string> (dict, otb::MetaDataKey::ProjectionRefKey, static_cast<std::string>(this->GetOutputProjectionRef())); // Generate the OGRLayers from the input VectorDatas // iteration begin from 1 cause the 0th input is a image for (unsigned int inputIdx = 0; inputIdx < this->GetNumberOfInputs(); ++inputIdx) { const VectorDataType* vd = dynamic_cast< const VectorDataType*>(this->itk::ProcessObject::GetInput(inputIdx)); // Get the projection ref of the current VectorData std::string projectionRefWkt = vd->GetProjectionRef(); bool projectionInformationAvailable = !projectionRefWkt.empty(); OGRSpatialReference * oSRS = NULL; if (projectionInformationAvailable) { oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str())); } else { otbMsgDevMacro(<< "Projection information unavailable"); } // Retrieving root node DataTreeConstPointerType tree = vd->GetDataTree(); // Get the input tree root InternalTreeNodeType * inputRoot = const_cast<InternalTreeNodeType *>(tree->GetRoot()); // Iterative method to build the layers from a VectorData OGRLayer * ogrCurrentLayer = NULL; std::vector<OGRLayer *> ogrLayerVector; otb::OGRIOHelper::Pointer IOConversion = otb::OGRIOHelper::New(); // The method ConvertDataTreeNodeToOGRLayers create the // OGRDataSource but don t release it. Destruction is done in the // desctructor m_OGRDataSourcePointer = NULL; ogrLayerVector = IOConversion->ConvertDataTreeNodeToOGRLayers(inputRoot, m_OGRDataSourcePointer, ogrCurrentLayer, oSRS); // From OGRLayer* to OGRGeometryH vector for (unsigned int idx = 0; idx < ogrLayerVector.size(); ++idx) { // test if the layers contain a field m_BurnField; int burnField = -1; if( !m_BurnAttribute.empty() ) { burnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( (OGRLayerH)(ogrLayerVector[idx]) ), m_BurnAttribute.c_str() ); // Get the geometries of the layer OGRFeatureH hFeat; OGR_L_ResetReading( (OGRLayerH)(ogrLayerVector[idx]) ); while( ( hFeat = OGR_L_GetNextFeature( (OGRLayerH)(ogrLayerVector[idx]) )) != NULL ) { OGRGeometryH hGeom;
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
if( OGR_F_GetGeometryRef( hFeat ) == NULL ) { OGR_F_Destroy( hFeat ); continue; } hGeom = OGR_G_Clone( OGR_F_GetGeometryRef( hFeat ) ); m_SrcDataSetGeometries.push_back( hGeom ); if (m_BurnMaxValueMode) { m_FullBurnValues.push_back(static_cast<double>(itk::NumericTraits<OutputImageInternalPixelType>::max())); } else if (burnField == -1 ) { // TODO : if no burnAttribute available, warning or raise an exception?? m_FullBurnValues.push_back(m_DefaultBurnValue++); itkWarningMacro(<<"Failed to find attribute "<<m_BurnAttribute << " in layer " << OGR_FD_GetName( OGR_L_GetLayerDefn( (OGRLayerH)(ogrLayerVector[idx]) )) <<" .Setting burn value to default = " << m_DefaultBurnValue); } else { m_FullBurnValues.push_back( OGR_F_GetFieldAsDouble( hFeat, burnField ) ); } OGR_F_Destroy( hFeat ); } } // Destroy the oSRS if (oSRS != NULL) { OSRRelease(oSRS); } } } } template<class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage>::GenerateData() { // Call Superclass GenerateData this->AllocateOutputs(); itk::ImageRegionIterator<TOutputImage> it (this->GetOutput(), this->GetOutput()->GetBufferedRegion()); for (it.GoToBegin(); !it.IsAtEnd(); ++it) { it.Set(0); } // Get the buffered region OutputImageRegionType bufferedRegion = this->GetOutput()->GetBufferedRegion(); // nb bands 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(otb::GdalDataTypeBridge::GetGDALDataType<OutputImageInternalPixelType>()) << "," << "PIXELOFFSET=" << sizeof(OutputImageInternalPixelType) * nbBands << "," << "LINEOFFSET=" << sizeof(OutputImageInternalPixelType)*nbBands*bufferedRegion.GetSize()[0] << ","
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
<< "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()); // 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()->GetSignedSpacing()[0]; geoTransform[5] = this->GetOutput()->GetSignedSpacing()[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) { GDALRasterizeGeometries( dataset, m_BandsToBurn.size(), &(m_BandsToBurn[0]), m_SrcDataSetGeometries.size(), &(m_SrcDataSetGeometries[0]), NULL, NULL, &(m_FullBurnValues[0]), NULL, GDALDummyProgress, NULL ); // release the dataset GDALClose( dataset ); } } template<class TVectorData, class TOutputImage> void VectorDataToLabelImageCustomFilter<TVectorData, TOutputImage> ::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); } } // end namespace otb #endif