1 ///////////////////////////////////////////////////////////
2 // //
3 // SAGA //
4 // //
5 // System for Automated Geoscientific Analyses //
6 // //
7 // Tool Library //
8 // shapes_lines //
9 // //
10 //-------------------------------------------------------//
11 // //
12 // extract_closed_lines.cpp //
13 // //
14 // Copyright (C) 2021 by //
15 // Volker Wichmann //
16 // //
17 //-------------------------------------------------------//
18 // //
19 // This file is part of 'SAGA - System for Automated //
20 // Geoscientific Analyses'. SAGA is free software; you //
21 // can redistribute it and/or modify it under the terms //
22 // of the GNU General Public License as published by the //
23 // Free Software Foundation, either version 2 of the //
24 // License, or (at your option) any later version. //
25 // //
26 // SAGA is distributed in the hope that it will be //
27 // useful, but WITHOUT ANY WARRANTY; without even the //
28 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
29 // PARTICULAR PURPOSE. See the GNU General Public //
30 // License for more details. //
31 // //
32 // You should have received a copy of the GNU General //
33 // Public License along with this program; if not, see //
34 // <http://www.gnu.org/licenses/>. //
35 // //
36 //-------------------------------------------------------//
37 // //
38 // e-mail: wichmann@laserdata.at //
39 // //
40 // contact: Volker Wichmann //
41 // LASERDATA GmbH //
42 // Management and analysis of //
43 // laserscanning data //
44 // Innsbruck, Austria //
45 // //
46 ///////////////////////////////////////////////////////////
47
48 //---------------------------------------------------------
49
50
51 ///////////////////////////////////////////////////////////
52 // //
53 // //
54 // //
55 ///////////////////////////////////////////////////////////
56
57 //---------------------------------------------------------
58 #include "extract_closed_lines.h"
59
60
61 ///////////////////////////////////////////////////////////
62 // //
63 // //
64 // //
65 ///////////////////////////////////////////////////////////
66
67 //---------------------------------------------------------
CExtract_Closed_Lines(void)68 CExtract_Closed_Lines::CExtract_Closed_Lines(void)
69 {
70 //-----------------------------------------------------
71 Set_Name (_TL("Extract Closed Lines"));
72
73 Set_Author (SG_T("V. Wichmann (c) 2021"));
74
75 Set_Description (_TW(
76 "The tool allows one to extract closed lines from the input "
77 "shapefile. Closed lines are detected by examining the distance "
78 "between the first and last line vertex.\n"
79 "The 'tolerance' parameter describes the maximum distance allowed "
80 "between the first and last line vertex. The 'maximum length' "
81 "parameter can be used to exclude long lines.\n\n"
82 ));
83
84 //-----------------------------------------------------
85 Parameters.Add_Shapes("",
86 "LINES_IN" , _TL("Lines"),
87 _TL("The input line shapefile."),
88 PARAMETER_INPUT, SHAPE_TYPE_Line
89 );
90
91 Parameters.Add_Shapes("",
92 "LINES_OUT" , _TL("Closed Lines"),
93 _TL("The output line shapefile with the extracted lines."),
94 PARAMETER_OUTPUT, SHAPE_TYPE_Line
95 );
96
97 Parameters.Add_Double("",
98 "TOLERANCE" , _TL("Tolerance"),
99 _TL("The maximum distance between the first and last line vertex [map units]."),
100 0.001, 0.0, true
101 );
102
103 Parameters.Add_Double("",
104 "MAX_LENGTH" , _TL("Maximum Length"),
105 _TL("The maximum length of extracted lines [map units]."),
106 10000.0, 0.0, true
107 );
108 }
109
110
111 ///////////////////////////////////////////////////////////
112 // //
113 // //
114 // //
115 ///////////////////////////////////////////////////////////
116
117 //---------------------------------------------------------
On_Execute(void)118 bool CExtract_Closed_Lines::On_Execute(void)
119 {
120
121 CSG_Shapes *pLines = Parameters("LINES_IN")->asShapes();
122 CSG_Shapes *pClosed = Parameters("LINES_OUT")->asShapes();
123 double dTolerance = Parameters("TOLERANCE")->asDouble();
124 double dMaxLength = Parameters("MAX_LENGTH")->asDouble();
125
126 pClosed->Create(SHAPE_TYPE_Line, CSG_String::Format(SG_T("%s_closed_lines"), pLines->Get_Name()), pLines, pLines->Get_Vertex_Type());
127
128
129 //--------------------------------------------------------
130 for(int iLine=0; iLine<pLines->Get_Count() && Set_Progress(iLine, pLines->Get_Count()); iLine++)
131 {
132 CSG_Shape *pLineIn = pLines->Get_Shape(iLine);
133
134 //--------------------------------------------------------
135 for(int iPart=0; iPart<pLineIn->Get_Part_Count(); iPart++)
136 {
137 TSG_Point_Z p1, p2;
138
139 p1.x = pLineIn->Get_Point(0, iPart).x;
140 p1.y = pLineIn->Get_Point(0, iPart).y;
141 p2.x = pLineIn->Get_Point(pLineIn->Get_Point_Count(iPart) - 1, iPart).x;
142 p2.y = pLineIn->Get_Point(pLineIn->Get_Point_Count(iPart) - 1, iPart).y;
143
144 if( pLines->Get_Vertex_Type() != SG_VERTEX_TYPE_XY )
145 {
146 p1.z = pLineIn->Get_Z(0, iPart);
147 p2.z = pLineIn->Get_Z(pLineIn->Get_Point_Count(iPart) - 1, iPart);
148 }
149 else
150 {
151 p1.z = p2.z = 0.0;
152 }
153
154 //--------------------------------------------------------
155 if( SG_Get_Distance(p1, p2) <= dTolerance && ((CSG_Shape_Line *)pLineIn)->Get_Length(iPart) <= dMaxLength )
156 {
157 CSG_Shape *pLineOut = pClosed->Add_Shape(pLineIn, SHAPE_COPY_ATTR);
158
159 for(int iPoint=0; iPoint<pLineIn->Get_Point_Count(iPart); iPoint++)
160 {
161 pLineOut->Add_Point(pLineIn->Get_Point(iPoint), iPart);
162
163 if( pLines->Get_Vertex_Type() != SG_VERTEX_TYPE_XY )
164 {
165 pLineOut->Set_Z(pLineIn->Get_Z(iPoint, iPart), iPoint, iPart);
166
167 if( pLines->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM )
168 {
169 pLineOut->Set_M(pLineIn->Get_M(iPoint, iPart), iPoint, iPart);
170 }
171 }
172 }
173 }
174 } // iPart
175 } // iLine
176
177
178 return( true );
179 }
180
181
182 ///////////////////////////////////////////////////////////
183 // //
184 // //
185 // //
186 ///////////////////////////////////////////////////////////
187
188 //---------------------------------------------------------
189