OTB  9.0.0
Orfeo Toolbox
otbVectorDataToLabelImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbVectorDataToLabelImageFilter_hxx
22 #define otbVectorDataToLabelImageFilter_hxx
23 
24 #include "gdal_alg.h"
25 #include "ogr_srs_api.h"
26 
28 #include "otbOGRIOHelper.h"
29 #include "otbGdalDataTypeBridge.h"
30 #include "otbImage.h"
31 
32 namespace otb
33 {
34 template <class TVectorData, class TOutputImage>
36  : m_OGRDataSourcePointer(nullptr), m_BandsToBurn(1, 1), m_BurnAttribute("FID"), m_DefaultBurnValue(1.), m_BackgroundValue(0.), m_AllTouchedMode(false)
37 {
38  this->SetNumberOfRequiredInputs(1);
39 
40  // Output parameters initialization
41  m_OutputSpacing.Fill(1.0);
42  m_OutputSize.Fill(0);
43  m_OutputStartIndex.Fill(0);
44 }
45 
46 template <class TVectorData, class TOutputImage>
48 {
49  this->itk::ProcessObject::PushBackInput(vd);
50 }
51 
52 template <class TVectorData, class TOutputImage>
55 {
56  return static_cast<const TVectorData*>(this->itk::ProcessObject::GetInput(idx));
57 }
58 
59 template <class TVectorData, class TOutputImage>
61 {
62  if (this->m_OutputSpacing != spacing)
63  {
64  this->m_OutputSpacing = spacing;
65  this->Modified();
66  }
67 }
68 
69 template <class TVectorData, class TOutputImage>
71 {
72  OutputSpacingType s(spacing);
73  this->SetOutputSpacing(s);
74 }
75 
76 template <class TVectorData, class TOutputImage>
78 {
79  itk::Vector<float, 2> sf(spacing);
81  s.CastFrom(sf);
82  this->SetOutputSpacing(s);
83 }
84 
85 template <class TVectorData, class TOutputImage>
87 {
88  OutputOriginType p(origin);
89  this->SetOutputOrigin(p);
90 }
91 
92 template <class TVectorData, class TOutputImage>
94 {
95  itk::Point<float, 2> of(origin);
97  p.CastFrom(of);
98  this->SetOutputOrigin(p);
99 }
100 
101 template <class TVectorData, class TOutputImage>
102 template <class ImagePointerType>
104 {
105  this->SetOutputOrigin(src->GetOrigin());
106  this->SetOutputSpacing(src->GetSignedSpacing());
107  this->SetOutputSize(src->GetLargestPossibleRegion().GetSize());
108  this->SetOutputProjectionRef(src->GetProjectionRef());
109 }
110 
111 template <class TVectorData, class TOutputImage>
113 {
114  // get pointer to the output
115  OutputImagePointer outputPtr = this->GetOutput();
116  if (!outputPtr)
117  {
118  return;
119  }
120 
121  // Set the size of the output region
122  typename TOutputImage::RegionType outputLargestPossibleRegion;
123  outputLargestPossibleRegion.SetSize(m_OutputSize);
124  // outputLargestPossibleRegion.SetIndex(m_OutputStartIndex);
125  outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
126 
127  // Set spacing and origin
128  outputPtr->SetSignedSpacing(m_OutputSpacing);
129  outputPtr->SetOrigin(m_OutputOrigin);
130 
131  itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
132  itk::EncapsulateMetaData<std::string>(dict, MetaDataKey::ProjectionRefKey, static_cast<std::string>(this->GetOutputProjectionRef()));
133 
134  // Generate the OGRLayers from the input VectorDatas
135  // iteration begin from 1 cause the 0th input is a image
136  for (unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
137  {
138  const VectorDataType* vd = dynamic_cast<const VectorDataType*>(this->itk::ProcessObject::GetInput(idx));
139 
140  // Get the projection ref of the current VectorData
141  std::string projectionRefWkt = vd->GetProjectionRef();
142  bool projectionInformationAvailable = !projectionRefWkt.empty();
143  OGRSpatialReference* oSRS = nullptr;
144 
145  if (projectionInformationAvailable)
146  {
147  oSRS = static_cast<OGRSpatialReference*>(OSRNewSpatialReference(projectionRefWkt.c_str()));
148  }
149  else
150  {
151  otbMsgDevMacro(<< "Projection information unavailable");
152  }
153 
154  // Retrieving root node
155  DataTreeConstPointerType tree = vd->GetDataTree();
156 
157  // Get the input tree root
158  InternalTreeNodeType* inputRoot = const_cast<InternalTreeNodeType*>(tree->GetRoot());
159 
160  // Iterative method to build the layers from a VectorData
161  OGRLayer* ogrCurrentLayer = nullptr;
162  std::vector<OGRLayer*> ogrLayerVector;
164 
165  // The method ConvertDataTreeNodeToOGRLayers create the
166  // OGRDataSource but don t release it. Destruction is done in the
167  // destructor
168  m_OGRDataSourcePointer = nullptr;
169  ogrLayerVector = IOConversion->ConvertDataTreeNodeToOGRLayers(inputRoot, m_OGRDataSourcePointer, ogrCurrentLayer, oSRS);
170 
171  // From OGRLayer* to OGRGeometryH vector
172  for (unsigned int idx2 = 0; idx2 < ogrLayerVector.size(); ++idx2)
173  {
174  // test if the layers contain a field m_BurnField;
175  int burnField = -1;
176 
177  if (!m_BurnAttribute.empty())
178  {
179  burnField = OGR_FD_GetFieldIndex(OGR_L_GetLayerDefn((OGRLayerH)(ogrLayerVector[idx2])), m_BurnAttribute.c_str());
180 
181  // Get the geometries of the layer
182  OGRFeatureH hFeat;
183  OGR_L_ResetReading((OGRLayerH)(ogrLayerVector[idx2]));
184  while ((hFeat = OGR_L_GetNextFeature((OGRLayerH)(ogrLayerVector[idx2]))) != nullptr)
185  {
186  OGRGeometryH hGeom;
187  if (OGR_F_GetGeometryRef(hFeat) == nullptr)
188  {
189  OGR_F_Destroy(hFeat);
190  continue;
191  }
192 
193  hGeom = OGR_G_Clone(OGR_F_GetGeometryRef(hFeat));
194  m_SrcDataSetGeometries.push_back(hGeom);
195 
196  if (burnField == -1)
197  {
198  // TODO : if no burnAttribute available, warning or raise an exception??
199  m_FullBurnValues.push_back(m_DefaultBurnValue++);
200  itkWarningMacro(<< "Failed to find attribute " << m_BurnAttribute << " in layer "
201  << OGR_FD_GetName(OGR_L_GetLayerDefn((OGRLayerH)(ogrLayerVector[idx2])))
202  << " .Setting burn value to default = " << m_DefaultBurnValue);
203  }
204  else
205  {
206  m_FullBurnValues.push_back(OGR_F_GetFieldAsDouble(hFeat, burnField));
207  }
208 
209  OGR_F_Destroy(hFeat);
210  }
211  }
212 
213  // Destroy the oSRS
214  if (oSRS != nullptr)
215  {
216  OSRRelease(oSRS);
217  }
218  }
219  }
220 }
221 
222 template <class TVectorData, class TOutputImage>
224 {
225  // Call Superclass GenerateData
226  this->AllocateOutputs();
227 
228  // Get the buffered region
229  OutputImageRegionType bufferedRegion = this->GetOutput()->GetBufferedRegion();
230 
231  // Fill the buffer with the background value
232  this->GetOutput()->FillBuffer(m_BackgroundValue);
233 
234  // nb bands
235  unsigned int nbBands = this->GetOutput()->GetNumberOfComponentsPerPixel();
236 
237  // register drivers
238  GDALAllRegister();
239 
240  std::ostringstream stream;
241  stream << "MEM:::"
242  << "DATAPOINTER=" << (uintptr_t)(this->GetOutput()->GetBufferPointer()) << ","
243  << "PIXELS=" << bufferedRegion.GetSize()[0] << ","
244  << "LINES=" << bufferedRegion.GetSize()[1] << ","
245  << "BANDS=" << nbBands << ","
246  << "DATATYPE=" << GDALGetDataTypeName(GdalDataTypeBridge::GetGDALDataType<OutputImageInternalPixelType>()) << ","
247  << "PIXELOFFSET=" << sizeof(OutputImageInternalPixelType) * nbBands << ","
248  << "LINEOFFSET=" << sizeof(OutputImageInternalPixelType) * nbBands * bufferedRegion.GetSize()[0] << ","
249  << "BANDOFFSET=" << sizeof(OutputImageInternalPixelType);
250 
251  GDALDatasetH dataset = GDALOpen(stream.str().c_str(), GA_Update);
252 
253  // Add the projection ref to the dataset
254  GDALSetProjection(dataset, this->GetOutput()->GetProjectionRef().c_str());
255 
256  // add the geoTransform to the dataset
257  itk::VariableLengthVector<double> geoTransform(6);
258 
259  // Reporting origin and spacing of the buffered region
260  // the spacing is unchanged, the origin is relative to the buffered region
261  OutputIndexType bufferIndexOrigin = bufferedRegion.GetIndex();
262  OutputOriginType bufferOrigin;
263  this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
264  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSignedSpacing()[0];
265  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSignedSpacing()[1];
266  geoTransform[1] = this->GetOutput()->GetSignedSpacing()[0];
267  geoTransform[5] = this->GetOutput()->GetSignedSpacing()[1];
268 
269  // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
270  geoTransform[2] = 0.;
271  geoTransform[4] = 0.;
272  GDALSetGeoTransform(dataset, const_cast<double*>(geoTransform.GetDataPointer()));
273 
274  char** options = nullptr;
275  if (m_AllTouchedMode)
276  {
277  options = CSLSetNameValue(options, "ALL_TOUCHED", "TRUE");
278  }
279 
280  // Burn the geometries into the dataset
281  if (dataset != nullptr)
282  {
283  GDALRasterizeGeometries(dataset, m_BandsToBurn.size(), &(m_BandsToBurn[0]), m_SrcDataSetGeometries.size(), &(m_SrcDataSetGeometries[0]), nullptr, nullptr,
284  &(m_FullBurnValues[0]), options, GDALDummyProgress, nullptr);
285 
286  CSLDestroy(options);
287 
288  // release the dataset
289  GDALClose(dataset);
290  }
291 }
292 
293 template <class TVectorData, class TOutputImage>
294 void VectorDataToLabelImageFilter<TVectorData, TOutputImage>::PrintSelf(std::ostream& os, itk::Indent indent) const
295 {
296  Superclass::PrintSelf(os, indent);
297 }
298 
299 } // end namespace otb
300 
301 #endif
otb::VectorDataToLabelImageFilter::OutputSpacingType
OutputImageType::SpacingType OutputSpacingType
Definition: otbVectorDataToLabelImageFilter.h:73
otb::VectorDataToLabelImageFilter::OutputImageRegionType
OutputImageType::RegionType OutputImageRegionType
Definition: otbVectorDataToLabelImageFilter.h:75
otb::VectorDataToLabelImageFilter::OutputImagePointer
OutputImageType::Pointer OutputImagePointer
Definition: otbVectorDataToLabelImageFilter.h:70
otbVectorDataToLabelImageFilter.h
otbImage.h
otbOGRIOHelper.h
otb::VectorDataToLabelImageFilter::m_OutputSpacing
OutputSpacingType m_OutputSpacing
Definition: otbVectorDataToLabelImageFilter.h:195
otb::VectorDataToLabelImageFilter::VectorDataType
TVectorData VectorDataType
Definition: otbVectorDataToLabelImageFilter.h:80
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::VectorDataToLabelImageFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbVectorDataToLabelImageFilter.hxx:112
otb::OGRIOHelper::Pointer
itk::SmartPointer< Self > Pointer
Definition: otbOGRIOHelper.h:53
otb::OGRIOHelper::New
static Pointer New()
otb::VectorDataToLabelImageFilter::DataTreeConstPointerType
DataTreeType::ConstPointer DataTreeConstPointerType
Definition: otbVectorDataToLabelImageFilter.h:84
otb::VectorDataToLabelImageFilter::VectorDataToLabelImageFilter
VectorDataToLabelImageFilter()
Definition: otbVectorDataToLabelImageFilter.hxx:35
otb::VectorDataToLabelImageFilter::AddVectorData
virtual void AddVectorData(const VectorDataType *vd)
Definition: otbVectorDataToLabelImageFilter.hxx:47
otb::VectorDataToLabelImageFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbVectorDataToLabelImageFilter.hxx:294
otb::VectorDataToLabelImageFilter::InternalTreeNodeType
DataTreeType::TreeNodeType InternalTreeNodeType
Definition: otbVectorDataToLabelImageFilter.h:82
otb::VectorDataToLabelImageFilter::GetInput
const VectorDataType * GetInput(unsigned int idx)
Definition: otbVectorDataToLabelImageFilter.hxx:54
otb::VectorDataToLabelImageFilter::m_OutputStartIndex
OutputIndexType m_OutputStartIndex
Definition: otbVectorDataToLabelImageFilter.h:198
otbGdalDataTypeBridge.h
otb::VectorDataToLabelImageFilter::OutputIndexType
OutputImageType::IndexType OutputIndexType
Definition: otbVectorDataToLabelImageFilter.h:72
otbMsgDevMacro
#define otbMsgDevMacro(x)
Definition: otbMacro.h:64
otb::VectorDataToLabelImageFilter::GenerateData
void GenerateData() override
Definition: otbVectorDataToLabelImageFilter.hxx:223
otb::VectorDataToLabelImageFilter::m_OutputSize
OutputSizeType m_OutputSize
Definition: otbVectorDataToLabelImageFilter.h:197
otb::VectorDataToLabelImageFilter::SetOutputOrigin
virtual void SetOutputOrigin(OutputOriginType _arg)
otb::MetaDataKey::ProjectionRefKey
OTBMetadata_EXPORT char const * ProjectionRefKey
otb::VectorDataToLabelImageFilter::SetOutputSpacing
virtual void SetOutputSpacing(const OutputSpacingType &spacing)
Definition: otbVectorDataToLabelImageFilter.hxx:60
otb::VectorDataToLabelImageFilter::OutputImageInternalPixelType
OutputImageType::InternalPixelType OutputImageInternalPixelType
Definition: otbVectorDataToLabelImageFilter.h:77
otb::VectorDataToLabelImageFilter::OutputOriginType
OutputImageType::PointType OutputOriginType
Definition: otbVectorDataToLabelImageFilter.h:74
otb::VectorDataToLabelImageFilter::SetOutputParametersFromImage
void SetOutputParametersFromImage(const ImagePointerType image)
Definition: otbVectorDataToLabelImageFilter.hxx:103