1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                     Tool Library                      //
9 //                      Grid_Tools                       //
10 //                                                       //
11 //-------------------------------------------------------//
12 //                                                       //
13 //                Grid_Combine_Classes.cpp               //
14 //                                                       //
15 //                 Copyright (C) 2017 by                 //
16 //                      Olaf Conrad                      //
17 //                                                       //
18 //-------------------------------------------------------//
19 //                                                       //
20 // This file is part of 'SAGA - System for Automated     //
21 // Geoscientific Analyses'. SAGA is free software; you   //
22 // can redistribute it and/or modify it under the terms  //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the     //
25 // License, or (at your option) any later version.       //
26 //                                                       //
27 // SAGA is distributed in the hope that it will be       //
28 // useful, but WITHOUT ANY WARRANTY; without even the    //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
30 // PARTICULAR PURPOSE. See the GNU General Public        //
31 // License for more details.                             //
32 //                                                       //
33 // You should have received a copy of the GNU General    //
34 // Public License along with this program; if not, see   //
35 // <http://www.gnu.org/licenses/>.                       //
36 //                                                       //
37 //-------------------------------------------------------//
38 //                                                       //
39 //    e-mail:     oconrad@saga-gis.org                   //
40 //                                                       //
41 //    contact:    Olaf Conrad                            //
42 //                Institute of Geography                 //
43 //                University of Hamburg                  //
44 //                Germany                                //
45 //                                                       //
46 ///////////////////////////////////////////////////////////
47 
48 //---------------------------------------------------------
49 #include "Grid_Combine_Classes.h"
50 
51 
52 ///////////////////////////////////////////////////////////
53 //														 //
54 //														 //
55 //														 //
56 ///////////////////////////////////////////////////////////
57 
58 //---------------------------------------------------------
CGrid_Combine_Classes(void)59 CGrid_Combine_Classes::CGrid_Combine_Classes(void)
60 {
61 	Set_Name		(_TL("Combine Classes"));
62 
63 	Set_Author		("O.Conrad (c) 2017");
64 
65 	Set_Description	(_TW(
66 		"Based on the look-up table classfication of a grid, this tool "
67 		"allows to change and combine class belongings of the cells. "
68 	));
69 
70 	//-----------------------------------------------------
71 	Parameters.Add_Grid("",
72 		"GRID"		, _TL("Grid"),
73 		_TL(""),
74 		PARAMETER_INPUT
75 	);
76 
77 	Parameters.Add_Grid("",
78 		"OUTPUT"	, _TL("Output"),
79 		_TL(""),
80 		PARAMETER_OUTPUT_OPTIONAL
81 	);
82 
83 	Parameters.Add_Parameters("",
84 		"CLASSES"	, _TL("Classes"),
85 		_TL("")
86 	);
87 }
88 
89 
90 ///////////////////////////////////////////////////////////
91 //														 //
92 ///////////////////////////////////////////////////////////
93 
94 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter)95 int CGrid_Combine_Classes::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
96 {
97 	if(	pParameter->Cmp_Identifier("GRID") )
98 	{
99 		Set_Classes(pParameters);
100 	}
101 
102 	//-----------------------------------------------------
103 	return( CSG_Tool_Grid::On_Parameter_Changed(pParameters, pParameter) );
104 }
105 
106 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)107 int CGrid_Combine_Classes::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
108 {
109 	if(	pParameter->Cmp_Identifier("GRID") )
110 	{
111 		pParameters->Set_Enabled("OUTPUT" , pParameter->asPointer() != NULL);
112 		pParameters->Set_Enabled("CLASSES", pParameter->asPointer() != NULL);
113 	}
114 
115 	//-----------------------------------------------------
116 	return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
117 }
118 
119 
120 ///////////////////////////////////////////////////////////
121 //														 //
122 ///////////////////////////////////////////////////////////
123 
124 //---------------------------------------------------------
Set_Classes(CSG_Parameters * pParameters)125 bool CGrid_Combine_Classes::Set_Classes(CSG_Parameters *pParameters)
126 {
127 	CSG_Parameter	*pLUT	= DataObject_Get_Parameter(pParameters->Get_Parameter("GRID")->asGrid(), "LUT");
128 
129 	if( !pLUT || !pLUT->asTable() )
130 	{
131 		return( false );
132 	}
133 
134 	CSG_Table	&LUT	= *pLUT->asTable();
135 
136 	//-----------------------------------------------------
137 	CSG_String	Classes;
138 
139 	for(int i=0; i<LUT.Get_Count(); i++)
140 	{
141 		if( i > 0 )
142 		{
143 			Classes	+= '|';
144 		}
145 
146 		Classes	+= LUT[i].asString(1);
147 	}
148 
149 	//-----------------------------------------------------
150 	CSG_Parameters	*pClasses	= pParameters->Get_Parameter("CLASSES")->asParameters();
151 
152 	pClasses->Del_Parameters();
153 
154 	for(int i=0; i<LUT.Get_Count(); i++)
155 	{
156 		pClasses->Add_Choice("", CSG_String::Format("CLASS%d", i), LUT[i].asString(1), "", Classes, i);
157 	}
158 
159 	//-----------------------------------------------------
160 	return( true );
161 }
162 
163 
164 ///////////////////////////////////////////////////////////
165 //														 //
166 ///////////////////////////////////////////////////////////
167 
168 //---------------------------------------------------------
On_Execute(void)169 bool CGrid_Combine_Classes::On_Execute(void)
170 {
171 	CSG_Parameter	*pLUT	= DataObject_Get_Parameter(Parameters("GRID")->asGrid(), "LUT");
172 
173 	if( !pLUT || !pLUT->asTable() )
174 	{
175 		Message_Add(_TL("unexpected error"));
176 
177 		return( false );
178 	}
179 
180 	CSG_Table	LUT	= *pLUT->asTable();
181 
182 	//-----------------------------------------------------
183 	CSG_Parameters	&Classes	= *Parameters("CLASSES")->asParameters();
184 
185 	if( Classes.Get_Count() != LUT.Get_Count() || LUT.Get_Count() == 0 )
186 	{
187 		Message_Add(_TL("unexpected error"));
188 
189 		return( false );
190 	}
191 	else
192 	{
193 		bool	bCombine	= false;
194 
195 		for(int i=0; !bCombine && i<Classes.Get_Count(); i++)
196 		{
197 			bCombine	= i != Classes[i].asInt();
198 		}
199 
200 		if( !bCombine )
201 		{
202 			Error_Set(_TL("no classes to combine"));
203 
204 			return( false );
205 		}
206 	}
207 
208 	//-----------------------------------------------------
209 	CSG_Grid	*pGrid	= Parameters("OUTPUT")->asGrid();
210 
211 	if( !pGrid )
212 	{
213 		pGrid	= Parameters("GRID")->asGrid();
214 	}
215 	else if( pGrid != Parameters("GRID")->asGrid() )
216 	{
217 		pGrid->Create(*Parameters("GRID")->asGrid());
218 	}
219 
220 	//-----------------------------------------------------
221 	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
222 	{
223 		#ifndef _DEBUG
224 		#pragma omp parallel for
225 		#endif
226 		for(int x=0; x<Get_NX(); x++)
227 		{
228 			int	i	= Get_Class(LUT, pGrid->asDouble(x, y));
229 
230 			if( i >= 0 && i != Classes[i].asInt() )
231 			{
232 				pGrid->Set_Value(x, y, LUT[Classes[i].asInt()].asDouble(3));
233 			}
234 		}
235 	}
236 
237 	//-----------------------------------------------------
238 	pLUT	= DataObject_Get_Parameter(pGrid, "LUT");
239 
240 	pLUT->asTable()->Del_Records();
241 
242 	for(int i=0; i<LUT.Get_Count(); i++)
243 	{
244 		bool	bAdd	= false;
245 
246 		for(int j=0; !bAdd && j<Classes.Get_Count(); j++)
247 		{
248 			bAdd	= i == Classes[j].asInt();
249 		}
250 
251 		if( bAdd )
252 		{
253 			pLUT->asTable()->Add_Record(LUT.Get_Record(i));
254 		}
255 	}
256 
257 	DataObject_Set_Parameter(pGrid, pLUT);
258 	DataObject_Set_Parameter(pGrid, "COLORS_TYPE", 1);	// Color Classification Type: Lookup Table
259 
260 	//-----------------------------------------------------
261 	if( pGrid != Parameters("GRID")->asGrid() )
262 	{
263 		pGrid->Fmt_Name("%s [%s]", Parameters("GRID")->asGrid()->Get_Name(), _TL("Combine Classes"));
264 	}
265 	else
266 	{
267 		Set_Classes(&Parameters);
268 	}
269 
270 	//-----------------------------------------------------
271 	return( true );
272 }
273 
274 
275 ///////////////////////////////////////////////////////////
276 //														 //
277 ///////////////////////////////////////////////////////////
278 
279 //---------------------------------------------------------
Get_Class(const CSG_Table & LUT,double Value)280 int CGrid_Combine_Classes::Get_Class(const CSG_Table &LUT, double Value)
281 {
282 	for(int i=0; i<LUT.Get_Count(); i++)
283 	{
284 		if( LUT[i].asDouble(3) <= Value && Value <= LUT[i].asDouble(4) )
285 		{
286 			return( i );
287 		}
288 	}
289 
290 	return( -1 );
291 }
292 
293 
294 ///////////////////////////////////////////////////////////
295 //														 //
296 //														 //
297 //														 //
298 ///////////////////////////////////////////////////////////
299 
300 //---------------------------------------------------------
301