1 /**********************************************************
2  * Version $Id: GEOTRANS_Grid.cpp 1921 2014-01-09 10:24:11Z oconrad $
3  *********************************************************/
4 
5 ///////////////////////////////////////////////////////////
6 //                                                       //
7 //                         SAGA                          //
8 //                                                       //
9 //      System for Automated Geoscientific Analyses      //
10 //                                                       //
11 //                     Tool Library                      //
12 //                  Projection_GeoTRANS                  //
13 //                                                       //
14 //-------------------------------------------------------//
15 //                                                       //
16 //                   GEOTRANS_Grid.cpp                   //
17 //                                                       //
18 //                 Copyright (C) 2003 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 "GEOTRANS_Grid.h"
64 
65 
66 ///////////////////////////////////////////////////////////
67 //														 //
68 //														 //
69 //														 //
70 ///////////////////////////////////////////////////////////
71 
72 //---------------------------------------------------------
CGEOTRANS_Grid(void)73 CGEOTRANS_Grid::CGEOTRANS_Grid(void)
74 {
75 	//-----------------------------------------------------
76 	Set_Name		(_TL("GeoTrans (Grid)"));
77 
78 	Set_Author		("O.Conrad (c) 2003");
79 
80 	Set_Description	(_TW(
81 		"Coordinate Transformation for Grids. "
82 		"This library makes use of the Geographic Translator (GeoTrans) library. "
83 		"The GeoTrans library is maintained by the National Geospatial Agency (NGA)."
84 	));
85 
86 	Add_Reference("http://earth-info.nga.mil/GandG/geotrans/");
87 
88 	//-----------------------------------------------------
89 	Parameters.Add_Grid_Output("",
90 		"OUT_GRID"	, _TL("Grid"),
91 		_TL("")
92 	);
93 
94 	Parameters.Add_Grid_Output("",
95 		"OUT_X"		, _TL("X Coordinates"),
96 		_TL("")
97 	);
98 
99 	Parameters.Add_Grid_Output("",
100 		"OUT_Y"		, _TL("Y Coordinates"),
101 		_TL("")
102 	);
103 
104 	Parameters.Add_Shapes_Output("",
105 		"OUT_SHAPES", _TL("Shapes"),
106 		_TL("")
107 	);
108 
109 	//-----------------------------------------------------
110 	Parameters.Add_Grid("SOURCE_NODE",
111 		"SOURCE"	, _TL("Source"),
112 		_TL(""),
113 		PARAMETER_INPUT
114 	);
115 
116 	Parameters.Add_Bool("TARGET_NODE",
117 		"CREATE_XY"	, _TL("Create X/Y Grids"),
118 		_TL(""),
119 		false
120 	);
121 
122 	Parameters.Add_Choice("TARGET_NODE",
123 		"RESAMPLING", _TL("Resampling"),
124 		_TL(""),
125 		CSG_String::Format("%s|%s|%s|%s|",
126 			_TL("Nearest Neighbour"),
127 			_TL("Bilinear Interpolation"),
128 			_TL("Bicubic Spline Interpolation"),
129 			_TL("B-Spline Interpolation")
130 		), 3
131 	);
132 
133 	//-----------------------------------------------------
134 	m_Grid_Target.Create(Add_Parameters("TARGET", _TL("Target Grid System"), _TL("")));
135 }
136 
137 
138 ///////////////////////////////////////////////////////////
139 //														 //
140 ///////////////////////////////////////////////////////////
141 
142 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter)143 int CGEOTRANS_Grid::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
144 {
145 	return( m_Grid_Target.On_Parameter_Changed(pParameters, pParameter) ? 1 : 0 );
146 }
147 
148 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)149 int CGEOTRANS_Grid::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
150 {
151 	return( m_Grid_Target.On_Parameters_Enable(pParameters, pParameter) ? 1 : 0 );
152 }
153 
154 
155 ///////////////////////////////////////////////////////////
156 //														 //
157 ///////////////////////////////////////////////////////////
158 
159 //---------------------------------------------------------
On_Execute_Conversion(void)160 bool CGEOTRANS_Grid::On_Execute_Conversion(void)
161 {
162 	TSG_Data_Type	Type;
163 	TSG_Rect		Extent;
164 	CSG_Grid		*pSource, *pGrid;
165 
166 	//-----------------------------------------------------
167 	TSG_Grid_Resampling	Resampling;
168 
169 	switch( Parameters("RESAMPLING")->asInt() )
170 	{
171 	default:	Resampling	= GRID_RESAMPLING_NearestNeighbour;	break;
172 	case  1:	Resampling	= GRID_RESAMPLING_Bilinear        ;	break;
173 	case  2:	Resampling	= GRID_RESAMPLING_BicubicSpline   ;	break;
174 	case  3:	Resampling	= GRID_RESAMPLING_BSpline         ;	break;
175 	}
176 
177 	//-----------------------------------------------------
178 	pSource	= Parameters("SOURCE")->asGrid();
179 	Type	= Resampling == GRID_RESAMPLING_NearestNeighbour ? pSource->Get_Type() : SG_DATATYPE_Float;
180 
181 	//-----------------------------------------------------
182 	if( Get_Target_Extent(pSource, Extent, true) )
183 	{
184 		m_Grid_Target.Set_User_Defined(Get_Parameters("TARGET"), Extent, pSource->Get_NY());
185 	}
186 
187 	if( Dlg_Parameters("TARGET") && (pGrid = m_Grid_Target.Get_Grid(Type)) != NULL )
188 	{
189 		return( Set_Grid(pSource, pGrid, Resampling) );
190 	}
191 
192 	return( false );
193 }
194 
195 
196 ///////////////////////////////////////////////////////////
197 //														 //
198 //														 //
199 //														 //
200 ///////////////////////////////////////////////////////////
201 
202 //---------------------------------------------------------
Get_MinMax(TSG_Rect & r,double x,double y)203 inline void CGEOTRANS_Grid::Get_MinMax(TSG_Rect &r, double x, double y)
204 {
205 	if( Get_Converted(x, y) )
206 	{
207 		if( r.xMin > r.xMax )
208 		{
209 			r.xMin	= r.xMax	= x;
210 		}
211 		else if( r.xMin > x )
212 		{
213 			r.xMin	= x;
214 		}
215 		else if( r.xMax < x )
216 		{
217 			r.xMax	= x;
218 		}
219 
220 		if( r.yMin > r.yMax )
221 		{
222 			r.yMin	= r.yMax	= y;
223 		}
224 		else if( r.yMin > y )
225 		{
226 			r.yMin	= y;
227 		}
228 		else if( r.yMax < y )
229 		{
230 			r.yMax	= y;
231 		}
232 	}
233 }
234 
235 //---------------------------------------------------------
Get_Target_Extent(CSG_Grid * pSource,TSG_Rect & Extent,bool bEdge)236 bool CGEOTRANS_Grid::Get_Target_Extent(CSG_Grid *pSource, TSG_Rect &Extent, bool bEdge)
237 {
238 	if( !pSource )
239 	{
240 		return( false );
241 	}
242 
243 	int			x, y;
244 
245 	Extent.xMin	= Extent.yMin	= 1.0;
246 	Extent.xMax	= Extent.yMax	= 0.0;
247 
248 	if( bEdge )
249 	{
250 		double		d;
251 
252 		for(y=0, d=pSource->Get_YMin(); y<pSource->Get_NY(); y++, d+=pSource->Get_Cellsize())
253 		{
254 			Get_MinMax(Extent, pSource->Get_XMin(), d);
255 			Get_MinMax(Extent, pSource->Get_XMax(), d);
256 		}
257 
258 		for(x=0, d=pSource->Get_XMin(); x<pSource->Get_NX(); x++, d+=pSource->Get_Cellsize())
259 		{
260 			Get_MinMax(Extent, d, pSource->Get_YMin());
261 			Get_MinMax(Extent, d, pSource->Get_YMax());
262 		}
263 	}
264 	else
265 	{
266 		TSG_Point	p;
267 
268 		for(y=0, p.y=pSource->Get_YMin(); y<pSource->Get_NY() && Set_Progress(y, pSource->Get_NY()); y++, p.y+=pSource->Get_Cellsize())
269 		{
270 			for(x=0, p.x=pSource->Get_XMin(); x<pSource->Get_NX(); x++, p.x+=pSource->Get_Cellsize())
271 			{
272 				if( !pSource->is_NoData(x, y) )
273 				{
274 					Get_MinMax(Extent, p.x, p.y);
275 				}
276 			}
277 		}
278 	}
279 
280 	return( is_Progress() && Extent.xMin < Extent.xMax && Extent.yMin < Extent.yMax );
281 }
282 
283 
284 ///////////////////////////////////////////////////////////
285 //														 //
286 //														 //
287 //														 //
288 ///////////////////////////////////////////////////////////
289 
290 //---------------------------------------------------------
Set_Grid(CSG_Grid * pSource,CSG_Grid * pTarget,TSG_Grid_Resampling Resampling)291 bool CGEOTRANS_Grid::Set_Grid(CSG_Grid *pSource, CSG_Grid *pTarget, TSG_Grid_Resampling Resampling)
292 {
293 	int			x, y;
294 	double		z;
295 	TSG_Point	Pt_Source, Pt_Target;
296 	CSG_Grid	*pX, *pY;
297 
298 	if( pSource && pTarget && Set_Transformation_Inverse() )
299 	{
300 		pTarget->Set_NoData_Value_Range(pSource->Get_NoData_Value(), pSource->Get_NoData_Value(true));
301 		pTarget->Set_Scaling(pSource->Get_Scaling(), pSource->Get_Offset());
302 		pTarget->Set_Name	(pSource->Get_Name());
303 		pTarget->Set_Unit	(pSource->Get_Unit());
304 
305 		pTarget->Assign_NoData();
306 
307 		if( Parameters("CREATE_XY")->asBool() )
308 		{
309 			pX	= SG_Create_Grid(pTarget->Get_System(), SG_DATATYPE_Float);
310 			pX->Assign_NoData();
311 			pX->Set_Name(_TL("X-Coordinate"));
312 			Parameters("OUT_X")->Set_Value(pX);
313 
314 			pY	= SG_Create_Grid(pTarget->Get_System(), SG_DATATYPE_Float);
315 			pY->Assign_NoData();
316 			pY->Set_Name(_TL("Y-Coordinate"));
317 			Parameters("OUT_Y")->Set_Value(pY);
318 		}
319 		else
320 		{
321 			pX	= pY	= NULL;
322 		}
323 
324 		//-------------------------------------------------
325 		for(y=0, Pt_Target.y=pTarget->Get_YMin(); y<pTarget->Get_NY() && Set_Progress(y, pTarget->Get_NY()); y++, Pt_Target.y+=pTarget->Get_Cellsize())
326 		{
327 			for(x=0, Pt_Target.x=pTarget->Get_XMin(); x<pTarget->Get_NX(); x++, Pt_Target.x+=pTarget->Get_Cellsize())
328 			{
329 				Pt_Source	= Pt_Target;
330 
331 				if( Get_Converted(Pt_Source) )
332 				{
333 					if( pSource->Get_Value(Pt_Source, z, Resampling) )
334 					{
335 						pTarget->Set_Value(x, y, z);
336 					}
337 
338 					if( pX && pY )
339 					{
340 						pX->Set_Value(x, y, Pt_Source.x);
341 						pY->Set_Value(x, y, Pt_Source.y);
342 					}
343 				}
344 			}
345 		}
346 
347 		return( true );
348 	}
349 
350 	return( false );
351 }
352 
353 //---------------------------------------------------------
Set_Shapes(CSG_Grid * pSource,CSG_Shapes * pTarget)354 bool CGEOTRANS_Grid::Set_Shapes(CSG_Grid *pSource, CSG_Shapes *pTarget)
355 {
356 	int			x, y;
357 	TSG_Point	Pt_Source, Pt_Target;
358 	CSG_Shape		*pShape;
359 
360 	if( pSource && pTarget )
361 	{
362 		pTarget->Create(SHAPE_TYPE_Point, pSource->Get_Name());
363 		pTarget->Add_Field("Z", SG_DATATYPE_Double);
364 
365 		for(y=0, Pt_Source.y=pSource->Get_YMin(); y<pSource->Get_NY() && Set_Progress(y, pSource->Get_NY()); y++, Pt_Source.y+=pSource->Get_Cellsize())
366 		{
367 			for(x=0, Pt_Source.x=pSource->Get_XMin(); x<pSource->Get_NX(); x++, Pt_Source.x+=pSource->Get_Cellsize())
368 			{
369 				if( !pSource->is_NoData(x, y) )
370 				{
371 					Pt_Target	= Pt_Source;
372 
373 					if( Get_Converted(Pt_Target) )
374 					{
375 						pShape		= pTarget->Add_Shape();
376 						pShape->Add_Point(Pt_Target);
377 						pShape->Set_Value(0, pSource->asDouble(x, y));
378 					}
379 				}
380 			}
381 		}
382 
383 		return( true );
384 	}
385 
386 	return( false );
387 }
388 
389 
390 ///////////////////////////////////////////////////////////
391 //														 //
392 //														 //
393 //														 //
394 ///////////////////////////////////////////////////////////
395 
396 //---------------------------------------------------------
397