OTB  9.0.0
Orfeo Toolbox
otbVectorDataToLabelMapWithAttributesFilter.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 otbVectorDataToLabelMapWithAttributesFilter_hxx
22 #define otbVectorDataToLabelMapWithAttributesFilter_hxx
23 
25 #include "itkBinaryImageToLabelMapFilter.h"
26 #include "itkNumericTraits.h"
27 
29 
30 namespace otb
31 {
32 
33 template <class TVectorData, class TLabelMap>
35 {
36  m_BackgroundValue = itk::NumericTraits<OutputLabelMapPixelType>::max();
37  this->SetNumberOfRequiredInputs(1);
38  m_Spacing.Fill(1.0);
39  m_Origin.Fill(0.0);
40  m_Direction.SetIdentity();
41  m_Size.Fill(0);
42  m_StartIndex.Fill(0);
43  m_InitialLabel = itk::NumericTraits<LabelType>::Zero;
44 
45  m_AutomaticSizeComputation = true;
46  m_VectorDataProperties = VectorDataPropertiesType::New();
47 }
48 
49 //----------------------------------------------------------------------------
50 template <class TVectorData, class TLabelMap>
52 {
53  if (this->m_Spacing != spacing)
54  {
55  this->m_Spacing = spacing;
56  this->Modified();
57  }
58 }
59 
60 //----------------------------------------------------------------------------
61 template <class TVectorData, class TLabelMap>
63 {
64  SpacingType s(spacing);
65  this->SetSpacing(s);
66 }
67 
68 //----------------------------------------------------------------------------
69 template <class TVectorData, class TLabelMap>
71 {
72  itk::Vector<float, 2> sf(spacing);
73  SpacingType s;
74  s.CastFrom(sf);
75  this->SetSpacing(s);
76 }
77 
78 //----------------------------------------------------------------------------
79 template <class TVectorData, class TLabelMap>
81 {
82  OriginType p(origin);
83  this->SetOrigin(p);
84 }
85 
86 //----------------------------------------------------------------------------
87 template <class TVectorData, class TLabelMap>
89 {
90  itk::Point<float, 2> of(origin);
91  OriginType p;
92  p.CastFrom(of);
93  this->SetOrigin(p);
94 }
95 
96 
101 template <class TVectorData, class TLabelMap>
103 {
104  // we can't call the superclass method here.
105 
106  // get pointers to the input and output
107  OutputLabelMapType* outputPtr = this->GetOutput();
108 
109  if (!outputPtr)
110  {
111  return;
112  }
113 
114  RegionType outputLargestPossibleRegion;
115  if (m_AutomaticSizeComputation == false)
116  {
117  // Set the size of the output region
118  outputLargestPossibleRegion.SetSize(m_Size);
119  outputLargestPossibleRegion.SetIndex(m_StartIndex);
120  outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
121 
122  otbGenericMsgDebugMacro(<< "LargestPossibleRegion " << outputPtr->GetLargestPossibleRegion());
123 
124  // Set spacing and origin
125  outputPtr->SetSpacing(m_Spacing);
126  outputPtr->SetOrigin(m_Origin);
127  outputPtr->SetDirection(m_Direction);
128  }
129  else
130  {
131  // typename PolygonType::RegionType region;
132  m_VectorDataProperties->SetVectorDataObject(this->GetInput());
133  // m_VectorDataProperties->SetBoundingRegion(region);
134  // Compute the global bounding box of the vectordata
135  m_VectorDataProperties->ComputeBoundingRegion();
136 
137  // Compute origin and size
138  SizeType size;
139  SpacingType spacing = this->GetInput()->GetSpacing();
140  OriginType origin = m_VectorDataProperties->GetBoundingRegion().GetOrigin();
141  for (unsigned int i = 0; i < 2; ++i)
142  {
143  if (spacing[i] < 0.0)
144  {
145  origin[i] += m_VectorDataProperties->GetBoundingRegion().GetSize(i);
146  }
147  origin[i] += (0.5 - m_StartIndex[i]) * spacing[i];
148  size[i] = static_cast<unsigned long>(std::ceil(std::abs(m_VectorDataProperties->GetBoundingRegion().GetSize(i) / spacing[i])));
149  }
150 
151  outputLargestPossibleRegion.SetSize(size);
152  outputLargestPossibleRegion.SetIndex(m_StartIndex);
153 
154  outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
155  outputPtr->SetSpacing(spacing);
156  outputPtr->SetOrigin(origin);
157  outputPtr->SetDirection(m_Direction);
158  }
159  return;
160 }
161 /*
162 template <class TVectorData, class TLabelMap >
163 void
164  VectorDataToLabelMapWithAttributesFilter<TVectorData, TLabelMap >
165 ::GenerateInputRequestedRegion()
166 {
167 
168  //call the superclass' implementation of this method
169  Superclass::GenerateInputRequestedRegion();
170 
171  // We need all the input.
172  InputVectorDataPointer input = const_cast<InputVectorDataType *>(this->GetInput());
173  if( !input )
174  {
175  return;
176  }
177  input->SetRequestedRegionToLargestPossibleRegion ();
178 }
179 
180 
181 template <class TVectorData, class TLabelMap >
182 void
183 VectorDataToLabelMapWithAttributesFilter<TVectorData, TLabelMap >
184 ::EnlargeOutputRequestedRegion(itk::DataObject *)
185 {
186  this->GetOutput()
187  ->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() );
188 }
189 */
190 
191 template <class TVectorData, class TLabelMap>
193 {
194  // Process object is not const-correct so the const_cast is required here
195  this->itk::ProcessObject::SetNthInput(0, const_cast<InputVectorDataType*>(input));
196 }
197 
198 template <class TVectorData, class TLabelMap>
200 {
201  // Process object is not const-correct so the const_cast is required here
202  this->itk::ProcessObject::SetNthInput(idx, const_cast<InputVectorDataType*>(input));
203 }
204 
205 template <class TVectorData, class TLabelMap>
208 {
209  if (this->GetNumberOfInputs() < 1)
210  {
211  return nullptr;
212  }
213 
214  return static_cast<const TVectorData*>(this->itk::ProcessObject::GetInput(0));
215 }
216 
217 template <class TVectorData, class TLabelMap>
220 {
221  return static_cast<const TVectorData*>(this->itk::ProcessObject::GetInput(idx));
222 }
223 
224 template <class TVectorData, class TLabelMap>
226 {
227  // Allocate the output
228  this->AllocateOutputs();
229 
230  OutputLabelMapType* output = this->GetOutput();
231 
232  // For each input
233  for (unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
234  {
235  if (this->GetInput(idx))
236  {
237 
238  InputVectorDataConstPointer input = this->GetInput(idx);
239  InternalTreeNodeType* inputRoot = const_cast<InternalTreeNodeType*>(input->GetDataTree()->GetRoot());
240  // Use our own value for the background
241  output->SetBackgroundValue(m_BackgroundValue);
242  // Set the value of the first label
243  m_lab = m_InitialLabel;
244  // otbGenericMsgDebugMacro(<<"input " << idx);
245 
246  // The projection information
247  output->SetMetaDataDictionary(input->GetMetaDataDictionary());
248  ProcessNode(inputRoot);
249  }
250  }
251 }
252 
253 template <class TVectorData, class TLabelMap>
255 {
256 
257  // Get the children list from the input node
258  ChildrenListType children = source->GetChildrenList();
259 
260  // For each child
261  for (typename ChildrenListType::iterator it = children.begin(); it != children.end(); ++it)
262  {
263  // Copy input DataNode info
264  DataNodePointerType dataNode = (*it)->Get();
265  otbGenericMsgDebugMacro(<< "Type of node " << dataNode->GetNodeType() << " id" << dataNode->GetNodeId());
266  switch (dataNode->GetNodeType())
267  {
268  case otb::ROOT:
269  {
270  ProcessNode((*it));
271  break;
272  }
273  case otb::DOCUMENT:
274  {
275  ProcessNode((*it));
276  break;
277  }
278  case otb::FOLDER:
279  {
280  ProcessNode((*it));
281  break;
282  }
283  case FEATURE_POINT:
284  {
285  otbGenericMsgDebugMacro(<< "Insert Point from vectorData");
286  IndexType index;
287  this->GetOutput()->TransformPhysicalPointToIndex(dataNode->GetPoint(), index);
288  if (this->GetOutput()->GetLargestPossibleRegion().IsInside(index))
289  {
290  this->GetOutput()->SetPixel(index, m_lab);
291  m_lab += 1;
292  }
293  break;
294  }
295  case otb::FEATURE_LINE:
296  {
297  // TODO Bresenham
298  itkExceptionMacro(<< "This type (FEATURE_LINE) is not handle (yet) by VectorDataToLabelMapWithAttributesFilter(), please request for it");
299  break;
300  }
301  case FEATURE_POLYGON:
302  {
303 
305  CorrectFunctorType correct;
306  PolygonPointerType correctPolygonExtRing = correct(dataNode->GetPolygonExteriorRing());
308 
309  // typedef typename DataNodeType::PolygonType PolygonType;
310  typedef typename PolygonType::RegionType RSRegionType;
311  typedef typename PolygonType::VertexType VertexType;
312  typedef typename IndexType::IndexValueType IndexValueType;
313  RSRegionType polygonExtRingBoundReg = correctPolygonExtRing->GetBoundingRegion();
314 
315 
316  OriginType physCorners[4];
317  physCorners[0][0] = polygonExtRingBoundReg.GetOrigin(0);
318  physCorners[0][1] = polygonExtRingBoundReg.GetOrigin(1);
319  physCorners[1] = physCorners[0];
320  physCorners[2] = physCorners[0];
321  physCorners[3] = physCorners[0];
322 
323  physCorners[1][1] += polygonExtRingBoundReg.GetSize(1);
324  physCorners[2][1] += polygonExtRingBoundReg.GetSize(1);
325  physCorners[2][0] += polygonExtRingBoundReg.GetSize(0);
326  physCorners[3][0] += polygonExtRingBoundReg.GetSize(0);
327 
328  IndexType startIdx, endIdx, tmpIdx;
329 
330  startIdx.Fill(itk::NumericTraits<IndexValueType>::max());
331  endIdx.Fill(itk::NumericTraits<IndexValueType>::NonpositiveMin());
332 
333  for (unsigned int k = 0; k < 4; ++k)
334  {
335  this->GetOutput()->TransformPhysicalPointToIndex(physCorners[k], tmpIdx);
336 
337  startIdx[0] = std::min(startIdx[0], tmpIdx[0]);
338  startIdx[1] = std::min(startIdx[1], tmpIdx[1]);
339  endIdx[0] = std::max(endIdx[0], tmpIdx[0]);
340  endIdx[1] = std::max(endIdx[1], tmpIdx[1]);
341  }
342  // Check that the polygon intersects the largest possible region
343  RegionType polyRegion;
344  polyRegion.SetIndex(startIdx);
345  polyRegion.SetSize(0, endIdx[0] - startIdx[0] + 1);
346  polyRegion.SetSize(1, endIdx[1] - startIdx[1] + 1);
347  if (polyRegion.Crop(this->GetOutput()->GetLargestPossibleRegion()))
348  {
349  startIdx = polyRegion.GetIndex();
350  endIdx[0] = startIdx[0] - 1 + polyRegion.GetSize(0);
351  endIdx[1] = startIdx[1] - 1 + polyRegion.GetSize(1);
352  }
353  else
354  {
355  // No intersection
356  break;
357  }
358 
359  OriginType tmpPoint;
360  VertexType vertex;
361  for (IndexValueType j = startIdx[1]; j <= endIdx[1]; ++j)
362  {
363  for (IndexValueType i = startIdx[0]; i <= endIdx[0]; ++i)
364  {
365  tmpIdx[0] = i;
366  tmpIdx[1] = j;
367  this->GetOutput()->TransformIndexToPhysicalPoint(tmpIdx, tmpPoint);
368  vertex[0] = tmpPoint[0];
369  vertex[1] = tmpPoint[1];
370  if (correctPolygonExtRing->IsInside(vertex) || correctPolygonExtRing->IsOnEdge(vertex))
371  {
372  // TODO : should also test interior rings
373  if (this->GetOutput()->HasLabel(m_lab))
374  {
375  if (!this->GetOutput()->GetLabelObject(m_lab)->HasIndex(tmpIdx))
376  { // Add a pixel to the current labelObject
377  this->GetOutput()->SetPixel(tmpIdx, m_lab);
378  }
379  }
380  else
381  {
382  // Add a pixel to the current labelObject
383  this->GetOutput()->SetPixel(tmpIdx, m_lab);
384  // add attributes
385  AttributesValueType fieldValue;
386  for (unsigned int ii = 0; ii < dataNode->GetFieldList().size(); ii++)
387  {
388  fieldValue = static_cast<AttributesValueType>(dataNode->GetFieldAsString(dataNode->GetFieldList()[ii]));
389  this->GetOutput()->GetLabelObject(m_lab)->SetAttribute(dataNode->GetFieldList()[ii].c_str(), fieldValue);
390  }
391  }
392  }
393  }
394  }
395  // Modify the label for the next layer
396  m_lab += 1;
397  break;
398  }
399  case FEATURE_MULTIPOINT:
400  {
401  itkExceptionMacro(<< "This type (FEATURE_MULTIPOINT) is not handle (yet) by VectorDataToLabelMapWithAttributesFilter(), please request for it");
402  break;
403  }
404  case FEATURE_MULTILINE:
405  {
406  itkExceptionMacro(<< "This type (FEATURE_MULTILINE) is not handle (yet) by VectorDataToLabelMapWithAttributesFilter(), please request for it");
407  break;
408  }
410  {
411  itkExceptionMacro(<< "This type (FEATURE_MULTIPOLYGON) is not handle (yet) by VectorDataToLabelMapWithAttributesFilter(), please request for it");
412  break;
413  }
414  case FEATURE_COLLECTION:
415  {
416  itkExceptionMacro(<< "This type (FEATURE_COLLECTION) is not handle (yet) by VectorDataToLabelMapWithAttributesFilter(), please request for it");
417  break;
418  }
419  }
420  }
421 }
422 
423 template <class TVectorData, class TLabelMap>
425 {
426  Superclass::PrintSelf(os, indent);
427  os << indent << "BackgroundValue: " << static_cast<typename itk::NumericTraits<OutputLabelMapPixelType>::PrintType>(m_BackgroundValue) << std::endl;
428 }
429 
430 } // end namespace otb
431 
432 #endif
otb::VectorDataToLabelMapWithAttributesFilter::RegionType
OutputLabelMapType::RegionType RegionType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:97
otb::FEATURE_POINT
@ FEATURE_POINT
Definition: otbDataNode.h:43
otb::VectorDataToLabelMapWithAttributesFilter::InputVectorDataConstPointer
InputVectorDataType::ConstPointer InputVectorDataConstPointer
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:79
otb::VectorDataToLabelMapWithAttributesFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:102
otb::VectorDataToLabelMapWithAttributesFilter::VectorDataToLabelMapWithAttributesFilter
VectorDataToLabelMapWithAttributesFilter()
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:34
otb::VectorDataToLabelMapWithAttributesFilter::PolygonPointerType
PolygonType::Pointer PolygonPointerType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:89
otb::VectorDataToLabelMapWithAttributesFilter::InternalTreeNodeType
InputVectorDataType::DataTreeType::TreeNodeType InternalTreeNodeType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:84
otb::FEATURE_MULTIPOLYGON
@ FEATURE_MULTIPOLYGON
Definition: otbDataNode.h:48
otb::DOCUMENT
@ DOCUMENT
Definition: otbDataNode.h:41
otbVectorDataProperties.h
otb::VectorDataToLabelMapWithAttributesFilter::OutputLabelMapType
TLabelMap OutputLabelMapType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:77
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::FEATURE_LINE
@ FEATURE_LINE
Definition: otbDataNode.h:44
otbVectorDataToLabelMapWithAttributesFilter.h
otbGenericMsgDebugMacro
#define otbGenericMsgDebugMacro(x)
Definition: otbMacro.h:63
otb::VectorDataToLabelMapWithAttributesFilter::ProcessNode
void ProcessNode(InternalTreeNodeType *source)
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:254
otb::VectorDataToLabelMapWithAttributesFilter::OriginType
OutputLabelMapType::PointType OriginType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:94
otb::VectorDataToLabelMapWithAttributesFilter::IndexType
OutputLabelMapType::IndexType IndexType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:92
otb::FOLDER
@ FOLDER
Definition: otbDataNode.h:42
otb::VectorDataToLabelMapWithAttributesFilter::AttributesValueType
LabelObjectType::AttributesValueType AttributesValueType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:99
otb::CorrectPolygonFunctor
This filter simplify and close the input polygon, making the last point equal to the first one.
Definition: otbCorrectPolygonFunctor.h:42
otb::VectorDataToLabelMapWithAttributesFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:424
otb::FEATURE_POLYGON
@ FEATURE_POLYGON
Definition: otbDataNode.h:45
otb::VectorDataToLabelMapWithAttributesFilter::SetSpacing
virtual void SetSpacing(const SpacingType &spacing)
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:51
otb::VectorDataToLabelMapWithAttributesFilter::InputVectorDataType
TVectorData InputVectorDataType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:76
otb::VectorDataToLabelMapWithAttributesFilter::SpacingType
OutputLabelMapType::SpacingType SpacingType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:95
otb::VectorDataToLabelMapWithAttributesFilter::GetInput
const InputVectorDataType * GetInput(void)
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:207
otb::FEATURE_MULTIPOINT
@ FEATURE_MULTIPOINT
Definition: otbDataNode.h:46
otb::VectorDataToLabelMapWithAttributesFilter::SetOrigin
virtual void SetOrigin(OriginType _arg)
otb::VectorDataToLabelMapWithAttributesFilter::DataNodePointerType
DataNodeType::Pointer DataNodePointerType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:87
otb::VectorDataToLabelMapWithAttributesFilter::SizeType
itk::Size< itkGetStaticConstMacro(VectorDataDimension)> SizeType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:110
otb::VectorDataToLabelMapWithAttributesFilter::GenerateData
void GenerateData() override
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:225
otb::VectorDataToLabelMapWithAttributesFilter::ChildrenListType
InternalTreeNodeType::ChildrenListType ChildrenListType
Definition: otbVectorDataToLabelMapWithAttributesFilter.h:85
otb::VectorDataToLabelMapWithAttributesFilter::SetInput
virtual void SetInput(const InputVectorDataType *input)
Definition: otbVectorDataToLabelMapWithAttributesFilter.hxx:192
otb::FEATURE_COLLECTION
@ FEATURE_COLLECTION
Definition: otbDataNode.h:49
otb::FEATURE_MULTILINE
@ FEATURE_MULTILINE
Definition: otbDataNode.h:47
otb::ROOT
@ ROOT
Definition: otbDataNode.h:40