1 /**********************************************************
2  * Version $Id$
3  *********************************************************/
4 
5 ///////////////////////////////////////////////////////////
6 //                                                       //
7 //                         SAGA                          //
8 //                                                       //
9 //      System for Automated Geoscientific Analyses      //
10 //                                                       //
11 //                     Tool Library                      //
12 //                     Table_Tools                       //
13 //                                                       //
14 //-------------------------------------------------------//
15 //                                                       //
16 //                separate_by_direction.cpp              //
17 //                                                       //
18 //                 Copyright (C) 2008 by                 //
19 //                      Olaf Conrad                      //
20 //                                                       //
21 //-------------------------------------------------------//
22 //                                                       //
23 // This file is part of 'SAGA - System for Automated     //
24 // Geoscientific Analyses'. SAGA is free software; you   //
25 // can redistribute it and/or modify it under the terms  //
26 // of the GNU General Public License as published by the //
27 // Free Software Foundation, either version 2 of the     //
28 // License, or (at your option) any later version.       //
29 //                                                       //
30 // SAGA is distributed in the hope that it will be       //
31 // useful, but WITHOUT ANY WARRANTY; without even the    //
32 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
33 // PARTICULAR PURPOSE. See the GNU General Public        //
34 // License for more details.                             //
35 //                                                       //
36 // You should have received a copy of the GNU General    //
37 // Public License along with this program; if not, see   //
38 // <http://www.gnu.org/licenses/>.                       //
39 //                                                       //
40 //-------------------------------------------------------//
41 //                                                       //
42 //    e-mail:     oconrad@saga-gis.org                   //
43 //                                                       //
44 //    contact:    Olaf Conrad                            //
45 //                Institute of Geography                 //
46 //                University of Goettingen               //
47 //                Goldschmidtstr. 5                      //
48 //                37077 Goettingen                       //
49 //                Germany                                //
50 //                                                       //
51 ///////////////////////////////////////////////////////////
52 
53 //---------------------------------------------------------
54 
55 
56 ///////////////////////////////////////////////////////////
57 //														 //
58 //														 //
59 //														 //
60 ///////////////////////////////////////////////////////////
61 
62 //---------------------------------------------------------
63 #include "separate_by_direction.h"
64 
65 
66 ///////////////////////////////////////////////////////////
67 //														 //
68 //														 //
69 //														 //
70 ///////////////////////////////////////////////////////////
71 
72 //---------------------------------------------------------
CSeparate_by_Direction(void)73 CSeparate_by_Direction::CSeparate_by_Direction(void)
74 {
75 	Set_Name		(_TL("Separate points by direction"));
76 
77 	Set_Author		(SG_T("O. Conrad (c) 2008"));
78 
79 	Set_Description	(_TW(
80 		"Separates points by direction. Direction is determined as average direction of three consecutive points A, B, C. "
81 		"If the angle between the directions of A-B and B-C is higher than given tolerance angle the point is dropped. "
82 		"This tool has been designed to separate GPS tracks recorded by tractors while preparing a field. "
83 	));
84 
85 	//-----------------------------------------------------
86 	Parameters.Add_Shapes_List(
87 		NULL	, "OUTPUT"		, _TL("Ouput"),
88 		_TL(""),
89 		PARAMETER_OUTPUT
90 	);
91 
92 	Parameters.Add_Shapes(
93 		NULL	, "POINTS"		, _TL("Points"),
94 		_TL(""),
95 		PARAMETER_INPUT, SHAPE_TYPE_Point
96 	);
97 
98 	Parameters.Add_Value(
99 		NULL	, "DIRECTIONS"	, _TL("Number of Directions"),
100 		_TL(""),
101 		PARAMETER_TYPE_Double	, 4.0, 2.0, true
102 	);
103 
104 	Parameters.Add_Value(
105 		NULL	, "TOLERANCE"	, _TL("Tolerance (Degree)"),
106 		_TL(""),
107 		PARAMETER_TYPE_Double	, 5.0, 0.0, true
108 	);
109 }
110 
111 
112 ///////////////////////////////////////////////////////////
113 //														 //
114 //														 //
115 //														 //
116 ///////////////////////////////////////////////////////////
117 
118 //---------------------------------------------------------
On_Execute(void)119 bool CSeparate_by_Direction::On_Execute(void)
120 {
121 	int							iSector, dir_Field;
122 	CSG_Shapes					*pPoints;
123 	CSG_Parameter_Shapes_List	*pOutput;
124 
125 	//-----------------------------------------------------
126 	pOutput		= Parameters("OUTPUT")		->asShapesList();
127 	pPoints		= Parameters("POINTS")		->asShapes();
128 	m_Tolerance	= Parameters("TOLERANCE")	->asDouble() * M_DEG_TO_RAD;
129 	m_nSectors	= Parameters("DIRECTIONS")	->asInt();
130 	m_dSector	= M_PI_360 / m_nSectors;
131 
132 	if( !pPoints || !pPoints->is_Valid() || pPoints->Get_Count() < 3 )
133 	{
134 		return( false );
135 	}
136 
137 	//-----------------------------------------------------
138 	pOutput->Del_Items();
139 
140 	dir_Field	= pPoints->Get_Field_Count();
141 
142 	for(iSector=0; iSector<m_nSectors; iSector++)
143 	{
144 		pOutput->Add_Item(SG_Create_Shapes(SHAPE_TYPE_Point, CSG_String::Format(SG_T("Direction %.2f"), iSector * m_dSector * M_RAD_TO_DEG), pPoints));
145 		pOutput->Get_Shapes(iSector)->Add_Field(_TL("Direction"), SG_DATATYPE_Double);
146 	}
147 
148 	//-----------------------------------------------------
149 	int			iPoint;
150 	double		dir_A, dir_B, dir, dif;
151 	CSG_Shape	*pt_A, *pt_B;
152 
153 	pt_B	= pPoints->Get_Shape(pPoints->Get_Count() - 2);
154 	pt_A	= pPoints->Get_Shape(pPoints->Get_Count() - 1);
155 
156 	dir_A	= SG_Get_Angle_Of_Direction(pt_B->Get_Point(0), pt_A->Get_Point(0));
157 
158 	for(iPoint=0; iPoint<pPoints->Get_Count() && Set_Progress(iPoint, pPoints->Get_Count()); iPoint++)
159 	{
160 		pt_B	= pt_A;
161 		pt_A	= pPoints->Get_Shape(iPoint);
162 
163 		dir_B	= dir_A;
164 		dir_A	= SG_Get_Angle_Of_Direction(pt_B->Get_Point(0), pt_A->Get_Point(0));
165 
166 		dif		= fmod(dir_A - dir_B, M_PI_360);
167 
168 		if( dif > M_PI_180 )
169 		{
170 			dif	-= M_PI_360;
171 		}
172 		else if( dif < -M_PI_180 )
173 		{
174 			dif	+= M_PI_360;
175 		}
176 
177 		if( fabs(dif) <= m_Tolerance )
178 		{
179 			dir		= dir_B + 0.5 * dif;
180 
181 			iSector	= (int)(fmod(M_PI_360 + 0.5 * m_dSector + dir, M_PI_360) / m_dSector);
182 
183 			if( iSector >= 0 && iSector < m_nSectors )
184 			{
185 				pOutput->Get_Shapes(iSector)->Add_Shape(pt_B)->Set_Value(dir_Field, dir * M_RAD_TO_DEG);
186 			}
187 		}
188 	}
189 
190 	//-----------------------------------------------------
191 	for(iSector=pOutput->Get_Item_Count()-1; iSector>=0; iSector--)
192 	{
193 		if( pOutput->Get_Shapes(iSector)->Get_Count() == 0 )
194 		{
195 			delete(pOutput->Get_Shapes(iSector));
196 
197 			pOutput->Del_Item(iSector);
198 		}
199 	}
200 
201 	//-----------------------------------------------------
202 	return( pOutput->Get_Item_Count() > 0 );
203 }
204 
205 
206 ///////////////////////////////////////////////////////////
207 //														 //
208 //														 //
209 //														 //
210 ///////////////////////////////////////////////////////////
211 
212 //---------------------------------------------------------
213