21 #ifndef otbLabelObjectToPolygonFunctor_hxx
22 #define otbLabelObjectToPolygonFunctor_hxx
32 template <
class TLabelObject,
class TPolygon>
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]);
40 template <
class TLabelObject,
class TPolygon>
45 m_CurrentState = DOWN_LEFT;
46 m_PositionFlag = LEFT_END;
47 m_InternalDataSet.clear();
49 m_Polygon = PolygonType::New();
57 labelObject->Optimize();
65 long currentLine = lIt.GetLine().GetIndex()[1];
70 m_InternalDataSet.push_back(firstRunsPerLine);
72 while (!lIt.IsAtEnd())
75 if (currentLine == lIt.GetLine().GetIndex()[1])
77 m_InternalDataSet.back().push_back(lIt.GetLine());
82 currentLine = lIt.GetLine().GetIndex()[1];
84 newRunsPerLine.push_back(lIt.GetLine());
85 m_InternalDataSet.push_back(newRunsPerLine);
91 m_StartingPoint = m_InternalDataSet.at(0).at(0).GetIndex();
92 m_LineOffset = m_StartingPoint[1];
93 m_CurrentPoint = m_StartingPoint;
101 switch (m_CurrentState)
106 IndexType firstCandidateRun =
Within(m_CurrentPoint, m_CurrentLine - 1);
107 if (IsRunIndexValid(firstCandidateRun))
110 IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine, RightEnd(m_CurrentRun), firstCandidateRun);
111 if (IsRunIndexValid(secondCandidateRun))
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);
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);
131 IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine - 1, RightEnd(m_CurrentRun), m_CurrentRun);
133 if (IsRunIndexValid(secondCandidateRun))
136 m_CurrentState = UP_LEFT;
137 m_PositionFlag = RIGHT_END;
138 WalkLeft(m_CurrentLine, m_CurrentPoint, RightEnd(secondCandidateRun), m_Polygon, m_CurrentState);
140 m_CurrentRun = secondCandidateRun;
145 m_CurrentState = DOWN_LEFT;
146 m_PositionFlag = LEFT_END;
147 WalkLeft(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
155 IndexType firstCandidateRun =
Within(m_CurrentPoint, m_CurrentLine + 1);
157 if (IsRunIndexValid(firstCandidateRun))
160 IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine, LeftEnd(m_CurrentRun), firstCandidateRun);
162 if (IsRunIndexValid(secondCandidateRun))
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);
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);
182 IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine + 1, LeftEnd(m_CurrentRun), m_CurrentRun);
184 if (IsRunIndexValid(secondCandidateRun))
187 m_CurrentRun = secondCandidateRun;
189 m_CurrentState = DOWN_RIGHT;
190 m_PositionFlag = LEFT_END;
191 WalkRight(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
196 m_CurrentState = UP_RIGHT;
197 m_PositionFlag = RIGHT_END;
198 WalkRight(m_CurrentLine, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
205 IndexType firstCandidateRun =
Within(m_CurrentPoint, m_CurrentLine + 1);
207 if (IsRunIndexValid(firstCandidateRun))
209 IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine, RightEnd(m_CurrentRun), firstCandidateRun);
211 if (IsRunIndexValid(secondCandidateRun))
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);
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);
231 IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine + 1, LeftEnd(m_CurrentRun), m_CurrentRun);
233 if (IsRunIndexValid(secondCandidateRun))
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);
245 m_CurrentState = UP_RIGHT;
246 m_PositionFlag = RIGHT_END;
247 WalkRight(m_CurrentLine, m_CurrentPoint, RightEnd(m_CurrentRun), m_Polygon, m_CurrentState);
254 IndexType firstCandidateRun =
Within(m_CurrentPoint, m_CurrentLine - 1);
256 if (IsRunIndexValid(firstCandidateRun))
258 IndexType secondCandidateRun = RightMostLeftEndInside(m_CurrentLine, LeftEnd(m_CurrentRun), firstCandidateRun);
260 if (IsRunIndexValid(secondCandidateRun))
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);
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);
280 IndexType secondCandidateRun = LeftMostRightEndInside(m_CurrentLine - 1, RightEnd(m_CurrentRun), m_CurrentRun);
282 if (IsRunIndexValid(secondCandidateRun))
285 m_CurrentState = UP_LEFT;
286 m_PositionFlag = RIGHT_END;
287 WalkLeft(m_CurrentLine, m_CurrentPoint, RightEnd(secondCandidateRun), m_Polygon, m_CurrentState);
289 m_CurrentRun = secondCandidateRun;
294 m_CurrentState = DOWN_LEFT;
295 m_PositionFlag = LEFT_END;
296 WalkLeft(m_CurrentLine, m_CurrentPoint, LeftEnd(m_CurrentRun), m_Polygon, m_CurrentState);
302 goesOn = m_CurrentPoint != m_StartingPoint;
308 template <
class TLabelObject,
class TPolygon>
311 return (index[0] >= 0 && index[1] >= 0);
314 template <
class TLabelObject,
class TPolygon>
318 unsigned int idx = 0;
322 if (line >= m_InternalDataSet.size())
329 long rightoffset = 0;
331 switch (m_PositionFlag)
342 typename RunsPerLineType::const_iterator it = m_InternalDataSet.at(line).begin();
345 while (resp[0] < 0 && it != m_InternalDataSet.at(line).end())
347 if (point[0] >= (it->GetIndex()[0]) + leftoffset && point[0] < (it->GetIndex()[0] +
static_cast<long>(it->GetLength())) + rightoffset)
357 template <
class TLabelObject,
class TPolygon>
361 return m_InternalDataSet.at(runIndex[1]).at(runIndex[0]).GetIndex();
364 template <
class TLabelObject,
class TPolygon>
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);
373 template <
class TLabelObject,
class TPolygon>
377 unsigned int idx = 0;
381 if (line >= m_InternalDataSet.size())
387 typename RunsPerLineType::const_iterator it = m_InternalDataSet.at(line).begin();
390 LineType lrun = m_InternalDataSet.at(run[1]).at(run[0]);
392 while (resp[0] < 0 && it != m_InternalDataSet.at(line).end())
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()))
407 template <
class TLabelObject,
class TPolygon>
414 if (line >= m_InternalDataSet.size())
419 unsigned int idx = m_InternalDataSet.at(line).size() - 1;
421 typename RunsPerLineType::const_reverse_iterator it = m_InternalDataSet.at(line).rbegin();
424 LineType lrun = m_InternalDataSet.at(run[1]).at(run[0]);
426 while (resp[0] < 0 && it != m_InternalDataSet.at(line).rend())
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()))
442 template <
class TLabelObject,
class TPolygon>
446 if (std::abs(
static_cast<long int>(line + m_LineOffset - endPoint[1])) > 1)
448 itkExceptionMacro(
"End point not with +/-1 line from line")
452 typedef typename PolygonType::VertexType::VectorType::ValueType VectorValueType;
453 offset.Fill(itk::NumericTraits<VectorValueType>::Zero);
471 switch (m_PositionFlag)
480 typename PolygonType::VertexType newPoint;
482 m_CurrentPoint = startPoint;
483 m_CurrentPoint[0] -= 1;
485 if (m_CurrentPoint[0] > endPoint[0] + 1)
487 m_CurrentPoint[1] = line + m_LineOffset;
488 newPoint = m_CurrentPoint;
490 polygon->AddVertex(IndexToPoint(newPoint));
494 if (
static_cast<int>(line + m_LineOffset) != endPoint[1] && m_CurrentPoint[0] > endPoint[0] + 1)
496 m_CurrentPoint[0] = endPoint[0] + 1;
497 newPoint = m_CurrentPoint;
499 polygon->AddVertex(IndexToPoint(newPoint));
502 if (m_CurrentPoint != endPoint)
504 m_CurrentPoint = endPoint;
505 newPoint = m_CurrentPoint;
507 polygon->AddVertex(IndexToPoint(newPoint));
511 template <
class TLabelObject,
class TPolygon>
516 if (std::abs(
static_cast<long int>(line + m_LineOffset - endPoint[1])) > 1)
518 itkExceptionMacro(
"End point not with +/-1 line from line")
522 typedef typename PolygonType::VertexType::VectorType::ValueType VectorValueType;
523 offset.Fill(itk::NumericTraits<VectorValueType>::Zero);
545 typename PolygonType::VertexType newPoint;
547 m_CurrentPoint = startPoint;
548 m_CurrentPoint[0] += 1;
550 if (m_CurrentPoint[0] < endPoint[0] - 1)
552 m_CurrentPoint[1] = line + m_LineOffset;
553 newPoint = m_CurrentPoint;
555 polygon->AddVertex(IndexToPoint(newPoint));
559 if (
static_cast<int>(line + m_LineOffset) != endPoint[1] && m_CurrentPoint[0] < endPoint[0] - 1)
561 m_CurrentPoint[0] = endPoint[0] - 1;
562 newPoint = m_CurrentPoint;
564 polygon->AddVertex(IndexToPoint(newPoint));
567 if (m_CurrentPoint != endPoint)
569 m_CurrentPoint = endPoint;
570 newPoint = m_CurrentPoint;
572 polygon->AddVertex(IndexToPoint(newPoint));
577 template <
class TLabelObject,
class TPolygon>
586 resp[0] = index[0] * m_Spacing[0] + m_Origin[0];
587 resp[1] = index[1] * m_Spacing[1] + m_Origin[1];