OTB  9.0.0
Orfeo Toolbox
otbVectorDataToRightAngleVectorDataFilter.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 otbVectorDataToRightAngleVectorDataFilter_hxx
22 #define otbVectorDataToRightAngleVectorDataFilter_hxx
23 
25 #include "otbVectorData.h"
26 
27 namespace otb
28 {
29 template <class TVectorData>
31 {
32  this->SetNumberOfRequiredInputs(1);
33  this->SetNumberOfRequiredOutputs(1);
34 
35  m_DistanceThreshold = 20.;
36  m_AngleThreshold = CONST_PI / 30.; // we want a threshold at 6 degrees
37 }
38 
39 template <class TVectorData>
41 {
42  // Get the input segments
43  typename VectorDataType::Pointer vData = const_cast<VectorDataType*>(this->GetInput());
44 
45  // Output
46  this->GetOutput(0)->SetMetaDataDictionary(vData->GetMetaDataDictionary());
47 
48  // Retrieving root node
49  typename DataNodeType::Pointer root = this->GetOutput(0)->GetDataTree()->GetRoot()->Get();
50  // Create the document node
51  typename DataNodeType::Pointer document = DataNodeType::New();
52  document->SetNodeType(otb::DOCUMENT);
53  // Adding the layer to the data tree
54  this->GetOutput(0)->GetDataTree()->Add(document, root);
55  // Create the folder node
56  typename DataNodeType::Pointer folder = DataNodeType::New();
57  folder->SetNodeType(otb::FOLDER);
58  this->GetOutput(0)->GetDataTree()->Add(folder, document);
59  this->GetOutput(0)->SetProjectionRef(vData->GetProjectionRef());
60 
61  // Itterate on the vector data
62  TreeIteratorType itVectorRef(vData->GetDataTree()); // Reference
63  itVectorRef.GoToBegin();
64 
65  while (!itVectorRef.IsAtEnd())
66  {
67  if (!itVectorRef.Get()->IsLineFeature())
68  {
69  ++itVectorRef;
70  continue; // do not process if it's not a line
71  }
72  TreeIteratorType itVectorCur = itVectorRef; // Current
73 
74  while (!itVectorCur.IsAtEnd())
75  {
76  if (!itVectorCur.Get()->IsLineFeature())
77  {
78  ++itVectorCur;
79  continue; // do not process if it's not a line
80  }
81  // Compute the angle formed by the two segments
82  double Angle = this->ComputeAngleFormedBySegments(itVectorRef.Get()->GetLine(), itVectorCur.Get()->GetLine());
83 
84  // Check if the angle is a right one
85  if (std::abs(Angle - CONST_PI_2) <= m_AngleThreshold)
86  {
87  // Right angle coordinate
88  PointType RightAngleCoordinate;
89  RightAngleCoordinate = this->ComputeRightAngleCoordinate(itVectorRef.Get()->GetLine(), itVectorCur.Get()->GetLine());
90 
91  // Compute the distance between the two segments and the right angle formed by this segments
92  double dist1_2 = this->ComputeDistanceFromPointToSegment(RightAngleCoordinate, itVectorRef.Get()->GetLine());
93  double dist2_2 = this->ComputeDistanceFromPointToSegment(RightAngleCoordinate, itVectorCur.Get()->GetLine());
94 
95  double threshold_2 = m_DistanceThreshold * m_DistanceThreshold;
96  if (dist1_2 < threshold_2 && dist2_2 < threshold_2)
97  {
98  // If Right Angle & not so far from segments: Add to the output
99  typename DataNodeType::Pointer CurrentGeometry = DataNodeType::New();
100  CurrentGeometry->SetNodeId("FEATURE_POINT");
101  CurrentGeometry->SetNodeType(otb::FEATURE_POINT);
102  CurrentGeometry->SetPoint(RightAngleCoordinate);
103  this->GetOutput(0)->GetDataTree()->Add(CurrentGeometry, folder);
104  }
105  }
106 
107  ++itVectorCur;
108  }
109  ++itVectorRef;
110  }
111 }
112 
113 template <class TVectorData>
115 {
116  VertexListType* vertexList = const_cast<VertexListType*>(line->GetVertexList());
117 
118  VertexType v0 = vertexList->GetElement(0);
119  VertexType v1 = vertexList->GetElement(1);
120 
121  // Case the extremities of the segment are the same
122  double l2 = v0.SquaredEuclideanDistanceTo(v1);
123 
124  // Is the projection of rAngle on the segment inside (0<u<1) or
125  // inside the segment bounds
126  double u = ((rAngle[0] - v0[0]) * (v1[0] - v0[0]) + (rAngle[1] - v0[1]) * (v1[1] - v0[1])) / l2;
127 
128  if (u < 1e-10)
129  u = 0.;
130  if (u - 1. > 1e-10)
131  u = 1.;
132 
133  double x = v0[0] + u * (v1[0] - v0[0]);
134  double y = v0[1] + u * (v1[1] - v0[1]);
135 
136  double dx = x - rAngle[0];
137  double dy = y - rAngle[1];
138 
139  return dx * dx + dy * dy;
140 }
141 
142 template <class TVectorData>
144 {
145  double oriDst = this->ComputeOrientation(lineDst);
146  double oriSrc = this->ComputeOrientation(lineSrc);
147 
148  return std::abs(oriDst - oriSrc);
149 }
150 
151 template <class TVectorData>
153 {
154  VertexListType* vertexList = const_cast<VertexListType*>(line->GetVertexList());
155 
156  double Xp1 = vertexList->GetElement(0)[0];
157  double Yp1 = vertexList->GetElement(0)[1];
158 
159  double Xp2 = vertexList->GetElement(1)[0];
160  double Yp2 = vertexList->GetElement(1)[1];
161 
162  // Compute the orientation
163  double dx = Xp1 - Xp2;
164  double dy = Yp1 - Yp2;
165  double orientation = std::atan2(dy, dx);
166  if (orientation < 0)
167  orientation += CONST_PI;
168 
169  return orientation;
170 }
171 
172 template <class TVectorData>
175 {
176  PointType P;
177 
178  VertexListType* vertexListSrc = const_cast<VertexListType*>(lineSrc->GetVertexList());
179  double Xp1 = vertexListSrc->GetElement(0)[0];
180  double Yp1 = vertexListSrc->GetElement(0)[1];
181  double Xp2 = vertexListSrc->GetElement(1)[0];
182  double Yp2 = vertexListSrc->GetElement(1)[1];
183 
184  VertexListType* vertexListDst = const_cast<VertexListType*>(lineDst->GetVertexList());
185  double Xq1 = vertexListDst->GetElement(0)[0];
186  double Yq1 = vertexListDst->GetElement(0)[1];
187  double Xq2 = vertexListDst->GetElement(1)[0];
188  double Yq2 = vertexListDst->GetElement(1)[1];
189 
190  double numU = (Xq2 - Xq1) * (Yp1 - Yq1) - (Yq2 - Yq1) * (Xp1 - Xq1);
191  double denumU = (Yq2 - Yq1) * (Xp2 - Xp1) - (Xq2 - Xq1) * (Yp2 - Yp1);
192 
193  double u = numU / denumU;
194 
195  P[0] = Xp1 + u * (Xp2 - Xp1);
196  P[1] = Yp1 + u * (Yp2 - Yp1);
197 
198  return P;
199 }
200 
201 template <class TVectorData>
202 void VectorDataToRightAngleVectorDataFilter<TVectorData>::PrintSelf(std::ostream& os, itk::Indent indent) const
203 {
204  Superclass::PrintSelf(os, indent);
205 }
206 
207 } // end namespace otb
208 
209 #endif
otb::FEATURE_POINT
@ FEATURE_POINT
Definition: otbDataNode.h:43
otb::VectorDataToRightAngleVectorDataFilter::VectorDataType
TVectorData VectorDataType
Definition: otbVectorDataToRightAngleVectorDataFilter.h:67
otb::VectorDataToRightAngleVectorDataFilter::ComputeDistanceFromPointToSegment
virtual double ComputeDistanceFromPointToSegment(PointType rAngle, LineType *line)
Definition: otbVectorDataToRightAngleVectorDataFilter.hxx:114
otb::CONST_PI
constexpr double CONST_PI
Definition: otbMath.h:49
otb::VectorDataToRightAngleVectorDataFilter::VertexType
LineType::VertexType VertexType
Definition: otbVectorDataToRightAngleVectorDataFilter.h:71
otb::VectorDataToRightAngleVectorDataFilter::LineType
VectorDataType::LineType LineType
Definition: otbVectorDataToRightAngleVectorDataFilter.h:69
otb::VectorDataToRightAngleVectorDataFilter::VectorDataToRightAngleVectorDataFilter
VectorDataToRightAngleVectorDataFilter()
Definition: otbVectorDataToRightAngleVectorDataFilter.hxx:30
otb::VectorDataToRightAngleVectorDataFilter::ComputeRightAngleCoordinate
virtual PointType ComputeRightAngleCoordinate(LineType *lineDst, LineType *lineSrc)
Definition: otbVectorDataToRightAngleVectorDataFilter.hxx:174
otb::VectorDataToRightAngleVectorDataFilter::ComputeAngleFormedBySegments
virtual double ComputeAngleFormedBySegments(LineType *lineDst, LineType *lineSrc)
Definition: otbVectorDataToRightAngleVectorDataFilter.hxx:143
otb::DOCUMENT
@ DOCUMENT
Definition: otbDataNode.h:41
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::VectorDataToRightAngleVectorDataFilter::PointType
VectorDataType::PointType PointType
Definition: otbVectorDataToRightAngleVectorDataFilter.h:70
otb::FOLDER
@ FOLDER
Definition: otbDataNode.h:42
otb::VectorDataToRightAngleVectorDataFilter::ComputeOrientation
virtual double ComputeOrientation(LineType *line)
Definition: otbVectorDataToRightAngleVectorDataFilter.hxx:152
otb::CONST_PI_2
constexpr double CONST_PI_2
Definition: otbMath.h:50
otb::VectorDataToRightAngleVectorDataFilter::VertexListType
LineType::VertexListType VertexListType
Definition: otbVectorDataToRightAngleVectorDataFilter.h:72
otb::VectorDataToRightAngleVectorDataFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbVectorDataToRightAngleVectorDataFilter.hxx:202
otb::VectorDataToRightAngleVectorDataFilter::GenerateData
void GenerateData() override
Definition: otbVectorDataToRightAngleVectorDataFilter.hxx:40
otbVectorData.h
otbVectorDataToRightAngleVectorDataFilter.h
otb::VectorDataToRightAngleVectorDataFilter::TreeIteratorType
itk::PreOrderTreeIterator< typename VectorDataType::DataTreeType > TreeIteratorType
Definition: otbVectorDataToRightAngleVectorDataFilter.h:74