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