1 /**********************************************************
2  * Version $Id$
3  *********************************************************/
4 
5 ///////////////////////////////////////////////////////////
6 //                                                       //
7 //                         SAGA                          //
8 //                                                       //
9 //      System for Automated Geoscientific Analyses      //
10 //                                                       //
11 //                     Tool Library                      //
12 //                   CreateGridSystem                    //
13 //                                                       //
14 //-------------------------------------------------------//
15 //                                                       //
16 //                  CreateGridSystem.cpp                 //
17 //                                                       //
18 //                 Copyright (C) 2007 by                 //
19 //                    Volker Wichmann                    //
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:     reklovw@web.de                         //
43 //                                                       //
44 //                                                       //
45 ///////////////////////////////////////////////////////////
46 
47 
48 
49 
50 ///////////////////////////////////////////////////////////
51 //														 //
52 //														 //
53 //														 //
54 ///////////////////////////////////////////////////////////
55 
56 //---------------------------------------------------------
57 #include "CreateGridSystem.h"
58 
59 
60 ///////////////////////////////////////////////////////////
61 //														 //
62 //				Construction/Destruction				 //
63 //														 //
64 ///////////////////////////////////////////////////////////
65 
66 //---------------------------------------------------------
CCreateGridSystem(void)67 CCreateGridSystem::CCreateGridSystem(void)
68 {
69 	Set_Name		(_TL("Create Grid System"));
70 
71 	Set_Author		("Volker Wichmann (c) 2007");
72 
73 	Set_Description(_TW(
74 		"This tool creates a new user specified Grid System for use with other tools.\n\n"
75 		"First of all, please consider the following issues before using the tool:\n"
76 		"(a) all calculations of the tool refer to the lower left corner of the grid system, i.e. "
77 		"the xMin and yMin values. This coordinate is fixed unless you specify an offset.\n"
78 		"(b) the tool follows the philosophy of SAGA in that the values describing the extent refer to the "
79 		"cell centers. If you like to match the extent with the border of a grid, use an offset.\n\n"
80 		"The tool provides four possibilities to set/determine the extent of the grid system:\n"
81 		"(1) by specifying the coordinate of the lower left cell (xMin, yMin) and the number of cells in W-E (NX) and S-N (NY) direction\n"
82 		"(2) by specifying the coordinates the of lower left (xMin, yMin) and the upper right (xMax, yMax) cell\n"
83 		"(3) by the extent of the shape(s) provided in the Data Objects section\n"
84 		"(4) by the extent of the grid(s) provided in the Data Objects section\n\n"
85 		"After selecting the appropriate method to determine the extent, the next step is to specify the "
86 		"Cellsize of the new grid system.\n"
87 		"For all methods supplied to determine the extent but number (1), three possibilities are provided to "
88 		"adjust Cellsize and grid system extent (please remember, the lower left corner is fixed!):\n"
89 		"(I) adjust the extent to match the Cellsize\n"
90 		"(II) adjust the Cellsize to match the extent in E-W direction\n"
91 		"(III) adjust the Cellsize to match the extent in S-N direction\n\n"
92 		"Finally it is possible to apply an offset to the lower left corner of the grid system. "
93 		"In this case check the Use Offset option and specify the offset in W-E and S-N direction. Positive values "
94 		"result in a shift in E/N, negative in W/S direction.\n"
95 		"In order to create the grid system the tool needs to create a dummy grid."
96 	));
97 
98 	//-----------------------------------------------------
99 	Parameters.Add_Grid_Output(
100 		NULL	, "GRID"		, _TL("Dummy Grid"),
101 		_TL("")
102 	);
103 
104 	Parameters.Add_Double(
105 		NULL	, "INIT"		, _TL("Initialization Value"),
106 		_TL("Value which is assigned to the dummy grid.")
107 	);
108 
109 	Parameters.Add_Double(
110 		NULL	, "CELLSIZE"	, _TL("Cellsize"),
111 		_TL(""),
112 		10.0, 0.0, true
113 	);
114 
115 	Parameters.Add_Choice(
116 		NULL	, "M_EXTENT"	, _TL("Extent Definition"),
117 		_TL(""),
118 		CSG_String::Format("%s|%s|%s|%s|",
119 			_TL("lower left coordinate and number of rows and columns"),
120 			_TL("lower left and upper right coordinates"),
121 			_TL("one or more shapes layers"),
122 			_TL("one or more grids")
123 		), 0
124 	);
125 
126 	Parameters.Add_Choice(
127 		NULL	, "ADJUST"		, _TL("Adjust"),
128 		_TL(""),
129 		CSG_String::Format("%s|%s|%s|",
130 			_TL("extent to cell size"),
131 			_TL("cell size to left-right extent"),
132 			_TL("cell size to bottom-top extent")
133 		), 0
134 	);
135 
136 	//-----------------------------------------------------
137 	CSG_Parameter	*pNode;
138 
139 	pNode	= Parameters.Add_Node(NULL, "X_NODE", _TL("Left-Right"), _TL(""));
140 	Parameters.Add_Double(pNode, "XMIN", _TL("Left"   ), _TL(""),   0.0);
141 	Parameters.Add_Double(pNode, "XMAX", _TL("Right"  ), _TL(""), 100.0);
142 	Parameters.Add_Int   (pNode, "NX"  , _TL("Columns"), _TL(""), 10, 1, true);
143 
144 	pNode	= Parameters.Add_Node(NULL, "Y_NODE", _TL("Bottom-Top"), _TL(""));
145 	Parameters.Add_Double(pNode, "YMIN", _TL("Bottom" ), _TL(""),   0.0);
146 	Parameters.Add_Double(pNode, "YMAX", _TL("Top"    ), _TL(""), 100.0);
147 	Parameters.Add_Int   (pNode, "NY"  , _TL("Rows"   ), _TL(""), 10, 1, true);
148 
149 	//-----------------------------------------------------
150 	Parameters.Add_Shapes_List(
151 		NULL	, "SHAPESLIST"	, _TL("Shapes Layers"),
152 		_TL(""),
153 		PARAMETER_INPUT
154 	);
155 
156 	Parameters.Add_Grid_List(
157 		NULL	, "GRIDLIST"	, _TL("Grids"),
158 		_TL(""),
159 		PARAMETER_INPUT
160 	);
161 
162 	//-----------------------------------------------------
163 	pNode	= Parameters.Add_Bool(
164 		NULL	, "USEOFF"		, _TL("Use Offset"),
165 		_TL(""),
166 		false
167 	);
168 
169 	Parameters.Add_Double(pNode, "XOFFSET", _TL("X Offset"), _TL("Positive values result in a shift in E direction."));
170 	Parameters.Add_Double(pNode, "YOFFSET", _TL("Y Offset"), _TL("Positive values result in a shift in N direction."));
171 }
172 
173 
174 ///////////////////////////////////////////////////////////
175 //														 //
176 ///////////////////////////////////////////////////////////
177 
178 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter)179 int CCreateGridSystem::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
180 {
181 	return( CSG_Tool::On_Parameter_Changed(pParameters, pParameter) );
182 }
183 
184 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)185 int CCreateGridSystem::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
186 {
187 	if( pParameter->Cmp_Identifier("M_EXTENT") )
188 	{
189 		pParameters->Set_Enabled("NX"        , pParameter->asInt() == 0);
190 		pParameters->Set_Enabled("NY"        , pParameter->asInt() == 0);
191 		pParameters->Set_Enabled("XMAX"      , pParameter->asInt() == 1);
192 		pParameters->Set_Enabled("YMAX"      , pParameter->asInt() == 1);
193 		pParameters->Set_Enabled("XMIN"      , pParameter->asInt() <= 1);
194 		pParameters->Set_Enabled("YMIN"      , pParameter->asInt() <= 1);
195 		pParameters->Set_Enabled("X_NODE"    , pParameter->asInt() <= 1);
196 		pParameters->Set_Enabled("Y_NODE"    , pParameter->asInt() <= 1);
197 		pParameters->Set_Enabled("ADJUST"    , pParameter->asInt() >= 1);
198 		pParameters->Set_Enabled("SHAPESLIST", pParameter->asInt() == 2);
199 		pParameters->Set_Enabled("GRIDLIST"  , pParameter->asInt() == 3);
200 	}
201 
202 	if( pParameter->Cmp_Identifier("USEOFF") )
203 	{
204 		pParameters->Set_Enabled("XOFFSET", pParameter->asBool());
205 		pParameters->Set_Enabled("YOFFSET", pParameter->asBool());
206 	}
207 
208 	return( CSG_Tool::On_Parameters_Enable(pParameters, pParameter) );
209 }
210 
211 
212 ///////////////////////////////////////////////////////////
213 //														 //
214 ///////////////////////////////////////////////////////////
215 
216 //---------------------------------------------------------
On_Execute(void)217 bool CCreateGridSystem::On_Execute(void)
218 {
219 	CSG_Grid_System		System;
220 
221 	switch( Parameters("M_EXTENT")->asInt() )
222 	{
223 	//-----------------------------------------------------
224 	default:	// lower left coordinate and number of rows and columns
225 		{
226 			System.Assign(Parameters("CELLSIZE")->asDouble(),
227 				Parameters("XMIN")->asDouble(), Parameters("YMIN")->asDouble(),
228 				Parameters("NX"  )->asInt   (), Parameters("NY"  )->asInt   ()
229 			);
230 		}
231 		break;
232 
233 	//-----------------------------------------------------
234 	case  1:	// lower left and upper right coordinates
235 		{
236 			CSG_Rect	Extent(
237 				Parameters("XMIN")->asDouble(), Parameters("YMIN")->asDouble(),
238 				Parameters("XMAX")->asDouble(), Parameters("YMAX")->asDouble()
239 			);
240 
241 			System	= Get_Adjusted(Parameters("CELLSIZE")->asDouble(), Extent);
242 		}
243 		break;
244 
245 	//-----------------------------------------------------
246 	case  2:	// one or more shapes layers
247 		{
248 			CSG_Parameter_Shapes_List	*pList	= Parameters("SHAPESLIST")->asShapesList();
249 
250 			if( pList->Get_Item_Count() > 0 )
251 			{
252 				CSG_Rect	Extent(pList->Get_Shapes(0)->Get_Extent());
253 
254 				for(int i=1; i<pList->Get_Item_Count(); i++)
255 				{
256 					Extent.Union(pList->Get_Shapes(i)->Get_Extent());
257 				}
258 
259 				System	= Get_Adjusted(Parameters("CELLSIZE")->asDouble(), Extent);
260 			}
261 		}
262 		break;
263 
264 	//-----------------------------------------------------
265 	case  3:	// one or more grids
266 		{
267 			CSG_Parameter_Grid_List	*pList	= Parameters("GRIDLIST")->asGridList();
268 
269 			if( pList->Get_Grid_Count() > 0 )
270 			{
271 				CSG_Rect	Extent(pList->Get_Grid(0)->Get_Extent());
272 
273 				for(int i=1; i<pList->Get_Grid_Count(); i++)
274 				{
275 					Extent.Union(pList->Get_Grid(i)->Get_Extent());
276 				}
277 
278 				System	= Get_Adjusted(Parameters("CELLSIZE")->asDouble(), Extent);
279 			}
280 		}
281 		break;
282 	}
283 
284 	//-----------------------------------------------------
285 	if( !System.is_Valid() )
286 	{
287 		Error_Set(_TL("invalid grid system"));
288 
289 		return( false );
290 	}
291 
292 	//-----------------------------------------------------
293 	if( Parameters("USEOFF")->asBool() )
294 	{
295 		CSG_Rect	Extent	= System.Get_Extent();
296 
297 		Extent.Move(
298 			Parameters("XOFFSET")->asDouble(),
299 			Parameters("YOFFSET")->asDouble()
300 		);
301 
302 		System.Assign(System.Get_Cellsize(), Extent.Get_XMin(), Extent.Get_YMin(), System.Get_NX(), System.Get_NY());
303 	}
304 
305 	//-----------------------------------------------------
306 	CSG_Grid	*pGrid	= SG_Create_Grid(System);
307 
308 	if( pGrid )
309 	{
310 		pGrid->Set_Name(_TL("Dummy Grid"));
311 		pGrid->Assign(Parameters("INIT")->asDouble());
312 		Parameters("GRID")->Set_Value(pGrid);
313 
314 		return( true );
315 	}
316 
317 	return( false );
318 }
319 
320 
321 ///////////////////////////////////////////////////////////
322 //														 //
323 ///////////////////////////////////////////////////////////
324 
325 //---------------------------------------------------------
Get_Adjusted(double Cellsize,TSG_Rect Extent)326 CSG_Grid_System CCreateGridSystem::Get_Adjusted(double Cellsize, TSG_Rect Extent)
327 {
328 	CSG_Grid_System	System;
329 
330 	if( Cellsize > 0.0 )
331 	{
332 		double	xRange	= Extent.xMax - Extent.xMin;
333 		double	yRange	= Extent.yMax - Extent.yMin;
334 		double	n;
335 
336 		switch( Parameters("ADJUST")->asInt() )
337 		{
338 		case 0:	// extent to cell size
339 			if( modf(xRange / Cellsize, &n) != 0.0 )
340 			{
341 				Extent.xMax	= Extent.xMin + Cellsize * floor(0.5 + xRange / Cellsize);
342 			}
343 
344 			if( modf(yRange / Cellsize, &n) != 0.0 )
345 			{
346 				Extent.yMax = Extent.yMin + Cellsize * floor(0.5 + yRange / Cellsize);
347 			}
348 			break;
349 
350 		case 1:	// cell size to left-right extent
351 			if( modf(xRange / Cellsize, &n) != 0.0 )
352 			{
353 				Cellsize	= xRange / floor(xRange / Cellsize);
354 			}
355 
356 			if( modf(yRange / Cellsize, &n) != 0.0 )
357 			{
358 				Extent.yMax = Extent.yMin + Cellsize * floor(0.5 + yRange / Cellsize);
359 			}
360 			break;
361 
362 		case 2:	// cell size to bottom-top extent
363 			if( modf(yRange / Cellsize, &n) != 0.0 )
364 			{
365 				Cellsize	= yRange / floor(yRange / Cellsize);
366 			}
367 
368 			if( modf(xRange / Cellsize, &n) != 0.0 )
369 			{
370 				Extent.xMax = Extent.xMin + Cellsize * floor(0.5 + xRange / Cellsize);
371 			}
372 			break;
373 		}
374 
375 		System.Assign(Cellsize, Extent);
376 	}
377 
378 	return( System );
379 }
380 
381 
382 ///////////////////////////////////////////////////////////
383 //														 //
384 //														 //
385 //														 //
386 ///////////////////////////////////////////////////////////
387 
388 //---------------------------------------------------------
389