1 /**********************************************************
2  * Version $Id: gradient_cartes_polar.cpp 911 2011-02-14 16:38:15Z reklov_w $
3  *********************************************************/
4 /*******************************************************************************
5     gradient_cartes_polar.cpp
6     Copyright (C) Victor Olaya
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301, USA
21 *******************************************************************************/
22 
23 ///////////////////////////////////////////////////////////
24 //                                                       //
25 //                                                       //
26 //                                                       //
27 ///////////////////////////////////////////////////////////
28 
29 //---------------------------------------------------------
30 #include "gradient_cartes_polar.h"
31 
32 
33 ///////////////////////////////////////////////////////////
34 //                                                       //
35 //                                                       //
36 //                                                       //
37 ///////////////////////////////////////////////////////////
38 
39 //---------------------------------------------------------
CGradient_Cartes_To_Polar(void)40 CGradient_Cartes_To_Polar::CGradient_Cartes_To_Polar(void)
41 {
42 	CSG_Parameter	*pNode;
43 
44 	Set_Name		(_TL("Gradient Vector from Cartesian to Polar Coordinates"));
45 
46 	Set_Author		(SG_T("Victor Olaya & Volker Wichmann (c) 2004-2010"));
47 
48 	Set_Description	(_TW(
49 		"Converts gradient vector from directional components (Cartesian) "
50 		"to polar coordinates (direction or aspect angle and length or tangens of slope).\n"
51 		"The tool supports three conventions on how to measure and output the angle of direction:\n"
52 		"(a) mathematical: direction angle is zero in East direction and the angle increases counterclockwise\n"
53 		"(b) geographical: direction angle is zero in North direction and the angle increases clockwise\n"
54 		"(c) zero direction and orientation are user defined\n"
55 	));
56 
57 	Parameters.Add_Grid(NULL, "DX"	, _TL("X Component")	, _TL(""), PARAMETER_INPUT);
58 	Parameters.Add_Grid(NULL, "DY"	, _TL("Y Component")	, _TL(""), PARAMETER_INPUT);
59 
60 	Parameters.Add_Grid(NULL, "DIR"	, _TL("Direction")		, _TL(""), PARAMETER_OUTPUT);
61 	Parameters.Add_Grid(NULL, "LEN"	, _TL("Length")			, _TL(""), PARAMETER_OUTPUT);
62 
63 	Parameters.Add_Choice(
64 		NULL	, "UNITS"			, _TL("Polar Angle Units"),
65 		_TL(""),
66 		CSG_String::Format(SG_T("%s|%s|"),
67 			_TL("radians"),
68 			_TL("degree")
69 		), 0
70 	);
71 
72 	pNode	= Parameters.Add_Choice(
73 		NULL	, "SYSTEM"			, _TL("Polar Coordinate System"),
74 		_TL(""),
75 		CSG_String::Format(SG_T("%s|%s|%s|"),
76 			_TL("mathematical"),
77 			_TL("geographical"),
78 			_TL("user defined")
79 		), 1
80 	);
81 
82 	Parameters.Add_Value(
83 		pNode	, "SYSTEM_ZERO"		, _TL("User defined Zero Direction"),
84 		_TL("given in degree clockwise from North direction"),
85 		PARAMETER_TYPE_Double, 0.0, 0.0, true, 360.0, true
86 	);
87 
88 	Parameters.Add_Choice(
89 		pNode	, "SYSTEM_ORIENT"	, _TL("User defined Orientation"),
90 		_TL(""),
91 		CSG_String::Format(SG_T("%s|%s|"),
92 			_TL("clockwise"),
93 			_TL("counterclockwise")
94 		), 0
95 	);
96 }
97 
98 
99 ///////////////////////////////////////////////////////////
100 //                                                       //
101 ///////////////////////////////////////////////////////////
102 
103 //---------------------------------------------------------
On_Execute(void)104 bool CGradient_Cartes_To_Polar::On_Execute(void)
105 {
106 	bool		bDegree, bClockwise;
107 	int			Method;
108 	double		DX, DY, DIR, Zero;
109 	CSG_Grid	*pDX, *pDY, *pDIR, *pLEN;
110 
111 	//-----------------------------------------------------
112 	pDX		= Parameters("DX")		->asGrid();
113 	pDY		= Parameters("DY")		->asGrid();
114 	pDIR	= Parameters("DIR")		->asGrid();
115 	pLEN	= Parameters("LEN")		->asGrid();
116 
117 	bDegree	= Parameters("UNITS")	->asInt() == 1;
118 	Method	= Parameters("SYSTEM")	->asInt();
119 
120 	if( Method == 0 )	// mathematic
121 	{
122 		Zero		= M_PI_090;
123 		bClockwise	= false;
124 	}
125 	else
126 	{
127 		Zero		= Parameters("SYSTEM_ZERO")->asDouble() * M_DEG_TO_RAD;
128 		bClockwise	= Parameters("SYSTEM_ORIENT")->asInt() == 0;
129 	}
130 
131 	//-----------------------------------------------------
132 	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
133 	{
134 		for(int x=0; x<Get_NX(); x++)
135 		{
136 			if( pDX->is_NoData(x, y) || pDY->is_NoData(x, y) )
137 			{
138 				pLEN->Set_NoData(x, y);
139 				pDIR->Set_NoData(x, y);
140 			}
141 			else
142 			{
143 				DX	= pDX->asDouble(x, y);
144 			    DY	= pDY->asDouble(x, y);
145 
146 				if( DX == 0.0 && DY == 0.0 )
147 				{
148 					pLEN->Set_Value (x, y, 0.0);
149 					pDIR->Set_NoData(x, y);
150 				}
151 				else
152 				{
153 					DIR	= DY != 0.0 ? fmod(M_PI_360 + atan2(DX, DY), M_PI_360) : DX < 0.0 ? M_PI_270 : M_PI_090;
154 
155 					if( Method != 1 )	// not geographic
156 					{
157 						DIR	= fmod(M_PI_360 + (bClockwise ? DIR - Zero : Zero - DIR), M_PI_360);
158 					}
159 
160 					pLEN->Set_Value(x, y, sqrt(DX*DX + DY*DY));
161 					pDIR->Set_Value(x, y, bDegree ? M_RAD_TO_DEG * DIR : DIR);
162 				}
163 			}
164 		}
165 	}
166 
167 	return( true );
168 }
169 
170 
171 ///////////////////////////////////////////////////////////
172 //                                                       //
173 //                                                       //
174 //                                                       //
175 ///////////////////////////////////////////////////////////
176 
177 //---------------------------------------------------------
CGradient_Polar_To_Cartes(void)178 CGradient_Polar_To_Cartes::CGradient_Polar_To_Cartes(void)
179 {
180 	CSG_Parameter	*pNode;
181 
182 	Set_Name		(_TL("Gradient Vector from Polar to Cartesian Coordinates"));
183 
184 	Set_Author		(SG_T("Victor Olaya & Volker Wichmann (c) 2004-2010"));
185 
186 	Set_Description	(_TW(
187 		"Converts gradient vector from polar coordinates (direction or aspect angle and length or tangens of slope) "
188 		"to directional components (Cartesian).\n"
189 		"The tool supports three conventions on how the angle of direction can be supplied:\n"
190 		"(a) mathematical: direction angle is zero in East direction and the angle increases counterclockwise\n"
191 		"(b) geographical: direction angle is zero in North direction and the angle increases clockwise\n"
192 		"(c) zero direction and orientation are user defined\n"
193 	));
194 
195 	Parameters.Add_Grid(NULL, "DIR"	, _TL("Direction")		, _TL(""), PARAMETER_INPUT);
196 	Parameters.Add_Grid(NULL, "LEN"	, _TL("Length")			, _TL(""), PARAMETER_INPUT);
197 
198 	Parameters.Add_Grid(NULL, "DX"	, _TL("X Component")	, _TL(""), PARAMETER_OUTPUT);
199 	Parameters.Add_Grid(NULL, "DY"	, _TL("Y Component")	, _TL(""), PARAMETER_OUTPUT);
200 
201 	Parameters.Add_Choice(
202 		NULL	, "UNITS"			, _TL("Polar Angle Units"),
203 		_TL(""),
204 		CSG_String::Format(SG_T("%s|%s|"),
205 			_TL("radians"),
206 			_TL("degree")
207 		), 0
208 	);
209 
210 	pNode	= Parameters.Add_Choice(
211 		NULL	, "SYSTEM"			, _TL("Polar Coordinate System"),
212 		_TL(""),
213 		CSG_String::Format(SG_T("%s|%s|%s|"),
214 			_TL("mathematical"),
215 			_TL("geographical"),
216 			_TL("user defined")
217 		), 1
218 	);
219 
220 	Parameters.Add_Value(
221 		pNode	, "SYSTEM_ZERO"		, _TL("User defined Zero Direction"),
222 		_TL("given in degree clockwise from North direction"),
223 		PARAMETER_TYPE_Double, 0.0, 0.0, true, 360.0, true
224 	);
225 
226 	Parameters.Add_Choice(
227 		pNode	, "SYSTEM_ORIENT"	, _TL("User defined Orientation"),
228 		_TL(""),
229 		CSG_String::Format(SG_T("%s|%s|"),
230 			_TL("clockwise"),
231 			_TL("counterclockwise")
232 		), 0
233 	);
234 }
235 
236 
237 ///////////////////////////////////////////////////////////
238 //                                                       //
239 ///////////////////////////////////////////////////////////
240 
241 //---------------------------------------------------------
On_Execute(void)242 bool CGradient_Polar_To_Cartes::On_Execute(void)
243 {
244 	bool		bDegree, bClockwise;
245 	int			Method;
246 	double		LEN, DIR, Zero;
247 	CSG_Grid	*pDX, *pDY, *pDIR, *pLEN;
248 
249 	//-----------------------------------------------------
250 	pDX		= Parameters("DX")		->asGrid();
251 	pDY		= Parameters("DY")		->asGrid();
252 	pDIR	= Parameters("DIR")		->asGrid();
253 	pLEN	= Parameters("LEN")		->asGrid();
254 
255 	bDegree	= Parameters("UNITS")	->asInt() == 1;
256 	Method	= Parameters("SYSTEM")	->asInt();
257 
258 	if( Method == 0 )	// mathematic
259 	{
260 		Zero		= M_PI_090;
261 		bClockwise	= false;
262 	}
263 	else
264 	{
265 		Zero		= Parameters("SYSTEM_ZERO")->asDouble() * M_DEG_TO_RAD;
266 		bClockwise	= Parameters("SYSTEM_ORIENT")->asInt() == 0;
267 	}
268 
269 	//-----------------------------------------------------
270 	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
271 	{
272 		for(int x=0; x<Get_NX(); x++)
273 		{
274 			if( pLEN->is_NoData(x, y) || pDIR->is_NoData(x, y) )
275 			{
276 				pDX->Set_NoData(x, y);
277 				pDY->Set_NoData(x, y);
278 			}
279 			else
280 			{
281 				LEN	= pLEN->asDouble(x, y);
282 			    DIR	= pDIR->asDouble(x, y);
283 
284 				if( bDegree )
285 				{
286 					DIR	*= M_DEG_TO_RAD;
287 				}
288 
289 				if( Method != 1 )	// not geographic
290 				{
291 					DIR	= bClockwise ? DIR - Zero : Zero - DIR;
292 				}
293 
294 				pDX->Set_Value(x, y, LEN * sin(DIR));
295 				pDY->Set_Value(x, y, LEN * cos(DIR));
296 			}
297 		}
298 	}
299 
300 	return( true );
301 }
302 
303 
304 ///////////////////////////////////////////////////////////
305 //                                                       //
306 //                                                       //
307 //                                                       //
308 ///////////////////////////////////////////////////////////
309 
310 //---------------------------------------------------------
311