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