OTB  9.0.0
Orfeo Toolbox
otbLabelObjectToPolygonFunctor.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 otbLabelObjectToPolygonFunctor_hxx
22 #define otbLabelObjectToPolygonFunctor_hxx
23 
24 
26 
27 namespace otb
28 {
29 namespace Functor
30 {
31 
32 template <class TLabelObject, class TPolygon>
34 {
35  bool resp = l2.GetIndex()[1] > l1.GetIndex()[1];
36  resp = resp || (l2.GetIndex()[1] == l1.GetIndex()[1] && (l1.GetIndex()[0] + static_cast<long>(l1.GetLength())) < l2.GetIndex()[0]);
37  return resp;
38 }
39 
40 template <class TLabelObject, class TPolygon>
43 {
44  // Clear any previous context
45  m_CurrentState = DOWN_LEFT;
46  m_PositionFlag = LEFT_END;
47  m_InternalDataSet.clear();
48 
49  m_Polygon = PolygonType::New();
50 
51  // Get the internal container
52  // LineContainerType lcontainer = labelObject->GetLineContainer();
53 
54  // Sort it
55  // sort(lcontainer.begin(), lcontainer.end(), &LexicographicalLineCompare);
56  // Use the Optimize method
57  labelObject->Optimize();
58  // Step 1: Fill the internal data set
59 
60  // Iterates on the line container
61  // typename LineContainerType::const_iterator lIt = lcontainer.begin();
63  lIt.GoToBegin();
64  // Stores the current line
65  long currentLine = lIt.GetLine().GetIndex()[1];
66  long lineIndex = 0;
67 
68  // Push back the first line of runs
69  RunsPerLineType firstRunsPerLine;
70  m_InternalDataSet.push_back(firstRunsPerLine);
71 
72  while (!lIt.IsAtEnd())
73  {
74  // if we are still in the same image line
75  if (currentLine == lIt.GetLine().GetIndex()[1])
76  {
77  m_InternalDataSet.back().push_back(lIt.GetLine());
78  }
79  else
80  {
81  ++lineIndex;
82  currentLine = lIt.GetLine().GetIndex()[1];
83  RunsPerLineType newRunsPerLine;
84  newRunsPerLine.push_back(lIt.GetLine());
85  m_InternalDataSet.push_back(newRunsPerLine);
86  }
87  ++lIt;
88  }
89 
90  // Begin the boundaries tracking procedure
91  m_StartingPoint = m_InternalDataSet.at(0).at(0).GetIndex();
92  m_LineOffset = m_StartingPoint[1];
93  m_CurrentPoint = m_StartingPoint;
94  m_CurrentRun.Fill(0);
95  m_CurrentLine = 0;
96 
97  bool goesOn = true;
98 
99  while (goesOn)
100  {
101  switch (m_CurrentState)
102  {
103  case UP_RIGHT:
104  {
105  // First candidate run
106  IndexType firstCandidateRun = Within(m_CurrentPoint, m_CurrentLine - 1);
107  if (IsRunIndexValid(firstCandidateRun))
108  {
109  // Second candidate run
110  IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine, RightEnd(m_CurrentRun), firstCandidateRun);
111  if (IsRunIndexValid(secondCandidateRun))
112  {
113  // Down-Right case
114  m_CurrentRun = secondCandidateRun;
115  m_CurrentState = DOWN_RIGHT;
116  m_PositionFlag = LEFT_END;
117  WalkRight(m_CurrentLine - 1, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
118  }
119  else
120  {
121  // Up-Right case
122  m_CurrentLine--;
123  m_CurrentRun = firstCandidateRun;
124  m_CurrentState = UP_RIGHT;
125  m_PositionFlag = RIGHT_END;
126  WalkRight(m_CurrentLine, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
127  }
128  }
129  else
130  {
131  IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine - 1, RightEnd(m_CurrentRun), m_CurrentRun);
132 
133  if (IsRunIndexValid(secondCandidateRun))
134  {
135  // Up-Left Case
136  m_CurrentState = UP_LEFT;
137  m_PositionFlag = RIGHT_END;
138  WalkLeft(m_CurrentLine, m_CurrentPoint, RightEnd(secondCandidateRun), m_Polygon, m_CurrentState);
139  m_CurrentLine--;
140  m_CurrentRun = secondCandidateRun;
141  }
142  else
143  {
144  // Down-Left case
145  m_CurrentState = DOWN_LEFT;
146  m_PositionFlag = LEFT_END;
147  WalkLeft(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
148  }
149  }
150  break;
151  }
152  case DOWN_LEFT:
153  {
154  // First candidate run
155  IndexType firstCandidateRun = Within(m_CurrentPoint, m_CurrentLine + 1);
156 
157  if (IsRunIndexValid(firstCandidateRun))
158  {
159  // Second candidate run
160  IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine, LeftEnd(m_CurrentRun), firstCandidateRun);
161 
162  if (IsRunIndexValid(secondCandidateRun))
163  {
164  // Up-Left case
165  m_CurrentRun = secondCandidateRun;
166  m_CurrentState = UP_LEFT;
167  m_PositionFlag = RIGHT_END;
168  WalkLeft(m_CurrentLine + 1, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
169  }
170  else
171  {
172  // Down-Left case
173  m_CurrentLine++;
174  m_CurrentRun = firstCandidateRun;
175  m_CurrentState = DOWN_LEFT;
176  m_PositionFlag = LEFT_END;
177  WalkLeft(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
178  }
179  }
180  else
181  {
182  IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine + 1, LeftEnd(m_CurrentRun), m_CurrentRun);
183 
184  if (IsRunIndexValid(secondCandidateRun))
185  {
186  // Down-Right case
187  m_CurrentRun = secondCandidateRun;
188  m_CurrentLine++;
189  m_CurrentState = DOWN_RIGHT;
190  m_PositionFlag = LEFT_END;
191  WalkRight(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
192  }
193  else
194  {
195  // Up-Right case
196  m_CurrentState = UP_RIGHT;
197  m_PositionFlag = RIGHT_END;
198  WalkRight(m_CurrentLine, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
199  }
200  }
201  break;
202  }
203  case DOWN_RIGHT:
204  {
205  IndexType firstCandidateRun = Within(m_CurrentPoint, m_CurrentLine + 1);
206 
207  if (IsRunIndexValid(firstCandidateRun))
208  {
209  IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine, RightEnd(m_CurrentRun), firstCandidateRun);
210 
211  if (IsRunIndexValid(secondCandidateRun))
212  {
213  // Up-Left case
214  m_CurrentState = UP_LEFT;
215  m_PositionFlag = RIGHT_END;
216  m_CurrentRun = secondCandidateRun;
217  WalkLeft(m_CurrentLine + 1, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
218  }
219  else
220  {
221  // Down-Left case
222  m_CurrentLine++;
223  m_CurrentRun = firstCandidateRun;
224  m_CurrentState = DOWN_LEFT;
225  m_PositionFlag = LEFT_END;
226  WalkLeft(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
227  }
228  }
229  else
230  {
231  IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine + 1, LeftEnd(m_CurrentRun), m_CurrentRun);
232 
233  if (IsRunIndexValid(secondCandidateRun))
234  {
235  // Down-Right case
236  m_CurrentLine++;
237  m_CurrentRun = secondCandidateRun;
238  m_CurrentState = DOWN_RIGHT;
239  m_PositionFlag = LEFT_END;
240  WalkRight(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
241  }
242  else
243  {
244  // Up-Right case
245  m_CurrentState = UP_RIGHT;
246  m_PositionFlag = RIGHT_END;
247  WalkRight(m_CurrentLine, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
248  }
249  }
250  break;
251  }
252  case UP_LEFT:
253  {
254  IndexType firstCandidateRun = Within(m_CurrentPoint, m_CurrentLine - 1);
255 
256  if (IsRunIndexValid(firstCandidateRun))
257  {
258  IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine, LeftEnd(m_CurrentRun), firstCandidateRun);
259 
260  if (IsRunIndexValid(secondCandidateRun))
261  {
262  // Down-Right case
263  m_CurrentRun = secondCandidateRun;
264  m_CurrentState = DOWN_RIGHT;
265  m_PositionFlag = LEFT_END;
266  WalkRight(m_CurrentLine - 1, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
267  }
268  else
269  {
270  // Up-Right case
271  m_CurrentLine--;
272  m_CurrentRun = firstCandidateRun;
273  m_CurrentState = UP_RIGHT;
274  m_PositionFlag = RIGHT_END;
275  WalkRight(m_CurrentLine, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
276  }
277  }
278  else
279  {
280  IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine - 1, RightEnd(m_CurrentRun), m_CurrentRun);
281 
282  if (IsRunIndexValid(secondCandidateRun))
283  {
284  // Up-Left case
285  m_CurrentState = UP_LEFT;
286  m_PositionFlag = RIGHT_END;
287  WalkLeft(m_CurrentLine, m_CurrentPoint, RightEnd(secondCandidateRun), m_Polygon, m_CurrentState);
288  m_CurrentLine--;
289  m_CurrentRun = secondCandidateRun;
290  }
291  else
292  {
293  // Down-Left case
294  m_CurrentState = DOWN_LEFT;
295  m_PositionFlag = LEFT_END;
296  WalkLeft(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
297  }
298  }
299  break;
300  }
301  }
302  goesOn = m_CurrentPoint != m_StartingPoint;
303  }
304 
305  return m_Polygon;
306 }
307 
308 template <class TLabelObject, class TPolygon>
310 {
311  return (index[0] >= 0 && index[1] >= 0);
312 }
313 
314 template <class TLabelObject, class TPolygon>
317 {
318  unsigned int idx = 0;
319  IndexType resp;
320  resp[0] = -1;
321 
322  if (line >= m_InternalDataSet.size())
323  {
324  resp[1] = -1;
325  return resp;
326  }
327 
328  long leftoffset = 0;
329  long rightoffset = 0;
330 
331  switch (m_PositionFlag)
332  {
333  case LEFT_END:
334  rightoffset = 1;
335  break;
336 
337  case RIGHT_END:
338  leftoffset = -1;
339  break;
340  }
341 
342  typename RunsPerLineType::const_iterator it = m_InternalDataSet.at(line).begin();
343  resp[1] = line;
344 
345  while (resp[0] < 0 && it != m_InternalDataSet.at(line).end())
346  {
347  if (point[0] >= (it->GetIndex()[0]) + leftoffset && point[0] < (it->GetIndex()[0] + static_cast<long>(it->GetLength())) + rightoffset)
348  {
349  resp[0] = idx;
350  }
351  ++idx;
352  ++it;
353  }
354  return resp;
355 }
356 
357 template <class TLabelObject, class TPolygon>
360 {
361  return m_InternalDataSet.at(runIndex[1]).at(runIndex[0]).GetIndex();
362 }
363 
364 template <class TLabelObject, class TPolygon>
367 {
368  IndexType point = m_InternalDataSet.at(runIndex[1]).at(runIndex[0]).GetIndex();
369  point[0] += static_cast<long>(m_InternalDataSet.at(runIndex[1]).at(runIndex[0]).GetLength() - 1);
370  return point;
371 }
372 
373 template <class TLabelObject, class TPolygon>
376 {
377  unsigned int idx = 0;
378  IndexType resp;
379  resp[0] = -1;
380 
381  if (line >= m_InternalDataSet.size())
382  {
383  resp[1] = -1;
384  return resp;
385  }
386 
387  typename RunsPerLineType::const_iterator it = m_InternalDataSet.at(line).begin();
388  resp[1] = line;
389 
390  LineType lrun = m_InternalDataSet.at(run[1]).at(run[0]);
391 
392  while (resp[0] < 0 && it != m_InternalDataSet.at(line).end())
393  {
395  if (it->GetIndex()[0] > point[0]
397  && it->GetIndex()[0] - 1 >= lrun.GetIndex()[0] && it->GetIndex()[0] - 1 < lrun.GetIndex()[0] + static_cast<long>(lrun.GetLength()))
398  {
399  resp[0] = idx;
400  }
401  ++idx;
402  ++it;
403  }
404  return resp;
405 }
406 
407 template <class TLabelObject, class TPolygon>
410 {
411  IndexType resp;
412  resp[0] = -1;
413 
414  if (line >= m_InternalDataSet.size())
415  {
416  resp[1] = -1;
417  return resp;
418  }
419  unsigned int idx = m_InternalDataSet.at(line).size() - 1;
420 
421  typename RunsPerLineType::const_reverse_iterator it = m_InternalDataSet.at(line).rbegin();
422  resp[1] = line;
423 
424  LineType lrun = m_InternalDataSet.at(run[1]).at(run[0]);
425 
426  while (resp[0] < 0 && it != m_InternalDataSet.at(line).rend())
427  {
429  if (it->GetIndex()[0] + static_cast<long>(it->GetLength()) <= point[0]
431  && it->GetIndex()[0] + static_cast<long>(it->GetLength()) >= lrun.GetIndex()[0] &&
432  it->GetIndex()[0] + static_cast<long>(it->GetLength()) < lrun.GetIndex()[0] + static_cast<long>(lrun.GetLength()))
433  {
434  resp[0] = idx;
435  }
436  --idx;
437  ++it;
438  }
439  return resp;
440 }
441 
442 template <class TLabelObject, class TPolygon>
443 void LabelObjectToPolygonFunctor<TLabelObject, TPolygon>::WalkLeft(unsigned int line, const IndexType& startPoint, const IndexType& endPoint,
444  PolygonType* polygon, const StateType state)
445 {
446  if (std::abs(static_cast<long int>(line + m_LineOffset - endPoint[1])) > 1)
447  {
448  itkExceptionMacro("End point not with +/-1 line from line")
449  }
450 
451  typename PolygonType::VertexType::VectorType offset;
452  typedef typename PolygonType::VertexType::VectorType::ValueType VectorValueType;
453  offset.Fill(itk::NumericTraits<VectorValueType>::Zero);
454 
455  switch (state)
456  {
457  case UP_RIGHT:
458  offset[1] = 0.5;
459  break;
460  case UP_LEFT:
461  offset[1] = 0.5;
462  break;
463  case DOWN_RIGHT:
464  offset[1] = -0.5;
465  break;
466  case DOWN_LEFT:
467  offset[1] = -0.5;
468  break;
469  }
470 
471  switch (m_PositionFlag)
472  {
473  case LEFT_END:
474  offset[0] = -0.5;
475  break;
476  case RIGHT_END:
477  offset[0] = 0.5;
478  break;
479  }
480  typename PolygonType::VertexType newPoint;
481 
482  m_CurrentPoint = startPoint;
483  m_CurrentPoint[0] -= 1;
484 
485  if (m_CurrentPoint[0] > endPoint[0] + 1)
486  {
487  m_CurrentPoint[1] = line + m_LineOffset;
488  newPoint = m_CurrentPoint;
489  newPoint += offset;
490  polygon->AddVertex(IndexToPoint(newPoint));
491  }
492 
493  // if the end point is not on line n, add an intermediate point
494  if (static_cast<int>(line + m_LineOffset) != endPoint[1] && m_CurrentPoint[0] > endPoint[0] + 1)
495  {
496  m_CurrentPoint[0] = endPoint[0] + 1;
497  newPoint = m_CurrentPoint;
498  newPoint += offset;
499  polygon->AddVertex(IndexToPoint(newPoint));
500  }
501 
502  if (m_CurrentPoint != endPoint)
503  {
504  m_CurrentPoint = endPoint;
505  newPoint = m_CurrentPoint;
506  newPoint += offset;
507  polygon->AddVertex(IndexToPoint(newPoint));
508  }
509 }
510 
511 template <class TLabelObject, class TPolygon>
512 void LabelObjectToPolygonFunctor<TLabelObject, TPolygon>::WalkRight(unsigned int line, const IndexType& startPoint, const IndexType& endPoint,
513  PolygonType* polygon, const StateType state)
514 {
515 
516  if (std::abs(static_cast<long int>(line + m_LineOffset - endPoint[1])) > 1)
517  {
518  itkExceptionMacro("End point not with +/-1 line from line")
519  }
520 
521  typename PolygonType::VertexType::VectorType offset;
522  typedef typename PolygonType::VertexType::VectorType::ValueType VectorValueType;
523  offset.Fill(itk::NumericTraits<VectorValueType>::Zero);
524 
525  switch (state)
526  {
527  case UP_RIGHT:
528  offset[0] = 0.5;
529  offset[1] = 0.5;
530  break;
531  case UP_LEFT:
532  offset[0] = -0.5;
533  offset[1] = 0.5;
534  break;
535  case DOWN_RIGHT:
536  offset[0] = 0.5;
537  offset[1] = -0.5;
538  break;
539  case DOWN_LEFT:
540  offset[0] = -0.5;
541  offset[1] = -0.5;
542  break;
543  }
544 
545  typename PolygonType::VertexType newPoint;
546 
547  m_CurrentPoint = startPoint;
548  m_CurrentPoint[0] += 1;
549 
550  if (m_CurrentPoint[0] < endPoint[0] - 1)
551  {
552  m_CurrentPoint[1] = line + m_LineOffset;
553  newPoint = m_CurrentPoint;
554  newPoint += offset;
555  polygon->AddVertex(IndexToPoint(newPoint));
556  }
557 
558  // if the end point is not on line n, add an intermediate point
559  if (static_cast<int>(line + m_LineOffset) != endPoint[1] && m_CurrentPoint[0] < endPoint[0] - 1)
560  {
561  m_CurrentPoint[0] = endPoint[0] - 1;
562  newPoint = m_CurrentPoint;
563  newPoint += offset;
564  polygon->AddVertex(IndexToPoint(newPoint));
565  }
566 
567  if (m_CurrentPoint != endPoint)
568  {
569  m_CurrentPoint = endPoint;
570  newPoint = m_CurrentPoint;
571  newPoint += offset;
572  polygon->AddVertex(IndexToPoint(newPoint));
573  }
574 }
575 
576 // Apply origin and spacing
577 template <class TLabelObject, class TPolygon>
580 {
581  VertexType resp;
582 
583  // Apply origin and spacing
584  // resp[0] = (index[0] - m_StartIndex[0]) * m_Spacing[0] + m_Origin[0];
585  // resp[1] = (index[1] - m_StartIndex[1]) * m_Spacing[1] + m_Origin[1];
586  resp[0] = index[0] * m_Spacing[0] + m_Origin[0];
587  resp[1] = index[1] * m_Spacing[1] + m_Origin[1];
588 
589  return resp;
590 }
591 
592 } // end namespace Functor
593 
594 } // end namespace otb
595 
596 #endif
otb::Functor::LabelObjectToPolygonFunctor::LeftMostRightEndInside
IndexType LeftMostRightEndInside(unsigned int line, const IndexType &point, const IndexType &run) const
Definition: otbLabelObjectToPolygonFunctor.hxx:409
otb::Functor::LabelObjectToPolygonFunctor::VertexType
PolygonType::VertexType VertexType
Definition: otbLabelObjectToPolygonFunctor.h:75
otb::Functor::LabelObjectToPolygonFunctor::WalkLeft
void WalkLeft(unsigned int line, const IndexType &startPoint, const IndexType &endPoint, PolygonType *polygon, const StateType state)
Walk left to update the finite states machine.
Definition: otbLabelObjectToPolygonFunctor.hxx:443
otb::Functor::LabelObjectToPolygonFunctor::ConstLineIteratorType
LabelObjectType::ConstLineIterator ConstLineIteratorType
Definition: otbLabelObjectToPolygonFunctor.h:69
otb::Functor::LabelObjectToPolygonFunctor::IsRunIndexValid
bool IsRunIndexValid(const IndexType &index) const
Check if the given run index (index in line, line) is valid.
Definition: otbLabelObjectToPolygonFunctor.hxx:309
otb::ogr::Within
OTBGdalAdapters_EXPORT bool Within(OGRGeometry const &lhs, OGRGeometry const &rhs)
Tests for containment.
otb::Functor::LabelObjectToPolygonFunctor::IndexToPoint
VertexType IndexToPoint(const VertexType &index) const
Internal enums.
Definition: otbLabelObjectToPolygonFunctor.hxx:579
otb::Functor::LabelObjectToPolygonFunctor::LexicographicalLineCompare
static bool LexicographicalLineCompare(const LineType &l1, const LineType &l2)
Compare two line in the lexicographical order.
Definition: otbLabelObjectToPolygonFunctor.hxx:33
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::MetaDataKey::VectorType
std::vector< double > VectorType
Definition: otbMetaDataKey.h:119
otb::Functor::LabelObjectToPolygonFunctor::WalkRight
void WalkRight(unsigned int line, const IndexType &startPoint, const IndexType &endPoint, PolygonType *polygon, const StateType state)
Walk right to update the finite states machine.
Definition: otbLabelObjectToPolygonFunctor.hxx:512
otb::Functor::LabelObjectToPolygonFunctor::PolygonType
TPolygon PolygonType
Definition: otbLabelObjectToPolygonFunctor.h:73
otb::Functor::LabelObjectToPolygonFunctor::operator()
PolygonType * operator()(LabelObjectType *labelObject)
Definition: otbLabelObjectToPolygonFunctor.hxx:42
otb::Functor::LabelObjectToPolygonFunctor::IndexType
LineType::IndexType IndexType
Definition: otbLabelObjectToPolygonFunctor.h:72
otb::Functor::LabelObjectToPolygonFunctor::LineType
LabelObjectType::LineType LineType
Definition: otbLabelObjectToPolygonFunctor.h:71
otb::Functor::LabelObjectToPolygonFunctor::RightMostLeftEndInside
IndexType RightMostLeftEndInside(unsigned int line, const IndexType &point, const IndexType &run) const
Definition: otbLabelObjectToPolygonFunctor.hxx:375
otb::Functor::LabelObjectToPolygonFunctor::LabelObjectType
TLabelObject LabelObjectType
Definition: otbLabelObjectToPolygonFunctor.h:66
otb::Functor::LabelObjectToPolygonFunctor::Within
IndexType Within(const IndexType &point, unsigned int line) const
Check if the point lies within the range of the line.
Definition: otbLabelObjectToPolygonFunctor.hxx:316
otbLabelObjectToPolygonFunctor.h
otb::Functor::LabelObjectToPolygonFunctor::RightEnd
IndexType RightEnd(const IndexType &runIndex) const
Return the right-end of the run.
Definition: otbLabelObjectToPolygonFunctor.hxx:366
otb::Functor::LabelObjectToPolygonFunctor::LeftEnd
IndexType LeftEnd(const IndexType &runIndex) const
Return the left-end of the run.
Definition: otbLabelObjectToPolygonFunctor.hxx:359
otb::Functor::LabelObjectToPolygonFunctor::StateType
StateType
Internal enums.
Definition: otbLabelObjectToPolygonFunctor.h:163
otb::Functor::LabelObjectToPolygonFunctor::RunsPerLineType
std::vector< LineType > RunsPerLineType
Internal structures.
Definition: otbLabelObjectToPolygonFunctor.h:158