1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // grid_io.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Hamburg //
44 // Germany //
45 // //
46 // e-mail: oconrad@saga-gis.org //
47 // //
48 ///////////////////////////////////////////////////////////
49
50 //---------------------------------------------------------
51 #include <stdint.h>
52 #include <string.h>
53
54 #ifdef _SAGA_LINUX
55 #include "config.h"
56 #include <arpa/inet.h>
57 #include <netinet/in.h>
58 #else
59 #include <WinSock2.h>
60 #endif
61
62 #include "grid.h"
63 #include "data_manager.h"
64 #include "tool_library.h"
65
66
67 ///////////////////////////////////////////////////////////
68 // //
69 // //
70 // //
71 ///////////////////////////////////////////////////////////
72
73 //---------------------------------------------------------
On_Reload(void)74 bool CSG_Grid::On_Reload(void)
75 {
76 return( Create(Get_File_Name(false)) );
77 }
78
79 //---------------------------------------------------------
On_Delete(void)80 bool CSG_Grid::On_Delete(void)
81 {
82 CSG_String FileName = Get_File_Name(true);
83
84 SG_File_Set_Extension(FileName, "sg-grd-z"); SG_File_Delete(FileName);
85 SG_File_Set_Extension(FileName, "sg-grd" ); SG_File_Delete(FileName);
86 SG_File_Set_Extension(FileName, "sgrd" ); SG_File_Delete(FileName);
87 SG_File_Set_Extension(FileName, "sdat" ); SG_File_Delete(FileName); SG_File_Delete(FileName + ".aux.xml");
88 SG_File_Set_Extension(FileName, "mgrd" ); SG_File_Delete(FileName);
89 SG_File_Set_Extension(FileName, "dgm" ); SG_File_Delete(FileName);
90 SG_File_Set_Extension(FileName, "dat" ); SG_File_Delete(FileName);
91
92 return( true );
93 }
94
95
96 ///////////////////////////////////////////////////////////
97 // //
98 // //
99 // //
100 ///////////////////////////////////////////////////////////
101
102 //---------------------------------------------------------
103 static TSG_Grid_File_Format gSG_Grid_File_Format_Default = GRID_FILE_FORMAT_Binary_old;
104
105 //---------------------------------------------------------
SG_Grid_Set_File_Format_Default(int Format)106 bool SG_Grid_Set_File_Format_Default (int Format)
107 {
108 switch( Format )
109 {
110 case GRID_FILE_FORMAT_Binary_old:
111 case GRID_FILE_FORMAT_Binary :
112 case GRID_FILE_FORMAT_Compressed:
113 case GRID_FILE_FORMAT_ASCII :
114 case GRID_FILE_FORMAT_GeoTIFF :
115 gSG_Grid_File_Format_Default = (TSG_Grid_File_Format)Format;
116 return( true );
117 }
118
119 return( false );
120 }
121
122 //---------------------------------------------------------
SG_Grid_Get_File_Format_Default(void)123 TSG_Grid_File_Format SG_Grid_Get_File_Format_Default (void)
124 {
125 return( gSG_Grid_File_Format_Default );
126 }
127
128 //---------------------------------------------------------
SG_Grid_Get_File_Extension_Default(void)129 CSG_String SG_Grid_Get_File_Extension_Default (void)
130 {
131 switch( gSG_Grid_File_Format_Default )
132 {
133 default:
134 case GRID_FILE_FORMAT_Compressed: return( "sg-grd-z" );
135 case GRID_FILE_FORMAT_Binary : return( "sg-grd" );
136 case GRID_FILE_FORMAT_Binary_old: return( "sgrd" );
137 case GRID_FILE_FORMAT_GeoTIFF : return( "tif" );
138 }
139 }
140
141
142 ///////////////////////////////////////////////////////////
143 // //
144 ///////////////////////////////////////////////////////////
145
146 //---------------------------------------------------------
Save(const CSG_String & FileName,int Format)147 bool CSG_Grid::Save(const CSG_String &FileName, int Format)
148 {
149 SG_UI_Msg_Add(CSG_String::Format("%s %s: %s...", _TL("Saving"), _TL("grid"), FileName.c_str()), true);
150
151 //-----------------------------------------------------
152 if( Format == GRID_FILE_FORMAT_Undefined )
153 {
154 Format = gSG_Grid_File_Format_Default;
155
156 if( SG_File_Cmp_Extension(FileName, "sg-grd-z") ) Format = GRID_FILE_FORMAT_Compressed;
157 if( SG_File_Cmp_Extension(FileName, "sg-grd" ) ) Format = GRID_FILE_FORMAT_Binary ;
158 if( SG_File_Cmp_Extension(FileName, "sgrd" ) ) Format = GRID_FILE_FORMAT_Binary_old;
159 if( SG_File_Cmp_Extension(FileName, "tif" ) ) Format = GRID_FILE_FORMAT_GeoTIFF ;
160 }
161
162 //-----------------------------------------------------
163 bool bResult = false;
164
165 switch( Format )
166 {
167 default:
168 bResult = _Save_Native(FileName, (TSG_Grid_File_Format)Format);
169 break;
170
171 case GRID_FILE_FORMAT_Compressed:
172 bResult = _Save_Compressed(FileName);
173 break;
174
175 case GRID_FILE_FORMAT_GeoTIFF:
176 SG_RUN_TOOL(bResult, "io_gdal", 2, // Export GeoTIFF
177 SG_TOOL_PARAMLIST_ADD("GRIDS", this)
178 && SG_TOOL_PARAMETER_SET("FILE" , FileName)
179 );
180 break;
181 }
182
183 SG_UI_Process_Set_Ready();
184
185 //-----------------------------------------------------
186 if( bResult )
187 {
188 Set_Modified(false);
189
190 Set_File_Name(FileName, true);
191
192 SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
193
194 return( true );
195 }
196
197 SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
198
199 return( false );
200 }
201
202
203 ///////////////////////////////////////////////////////////
204 // //
205 // //
206 // //
207 ///////////////////////////////////////////////////////////
208
209 //---------------------------------------------------------
_Load_External(const CSG_String & FileName,bool bCached,bool bLoadData)210 bool CSG_Grid::_Load_External(const CSG_String &FileName, bool bCached, bool bLoadData)
211 {
212 bool bResult = false;
213
214 CSG_Data_Manager Data;
215
216 CSG_Tool *pTool = NULL;
217
218 SG_UI_Msg_Lock(true);
219
220 //-----------------------------------------------------
221 // Image Import
222
223 if( ( SG_File_Cmp_Extension(FileName, "bmp")
224 || SG_File_Cmp_Extension(FileName, "gif")
225 || SG_File_Cmp_Extension(FileName, "jpg")
226 || SG_File_Cmp_Extension(FileName, "png")
227 || SG_File_Cmp_Extension(FileName, "pcx") )
228 && !bResult && (pTool = SG_Get_Tool_Library_Manager().Create_Tool("io_grid_image", 1)) != NULL )
229 {
230 pTool->Settings_Push(&Data);
231
232 bResult = pTool->Set_Parameter("FILE", FileName)
233 && pTool->Execute();
234
235 SG_Get_Tool_Library_Manager().Delete_Tool(pTool);
236 }
237
238 //-----------------------------------------------------
239 // GDAL Import
240
241 if( !bResult && (pTool = SG_Get_Tool_Library_Manager().Create_Tool("io_gdal", 0)) != NULL )
242 {
243 pTool->Settings_Push(&Data);
244
245 bResult = pTool->Set_Parameter("FILES" , FileName)
246 && pTool->Set_Parameter("MULTIPLE", 0 ) // output as single grid(s)
247 && pTool->Execute();
248
249 SG_Get_Tool_Library_Manager().Delete_Tool(pTool);
250 }
251
252 SG_UI_Msg_Lock(false);
253
254 //-----------------------------------------------------
255 if( bResult && Data.Get_Grid_System(0) && Data.Get_Grid_System(0)->Get(0) && Data.Get_Grid_System(0)->Get(0)->is_Valid() )
256 {
257 CSG_Grid *pGrid = (CSG_Grid *)Data.Get_Grid_System(0)->Get(0);
258
259 if( pGrid->is_Cached() )
260 {
261 return( Create(*pGrid) );
262 }
263
264 Set_File_Name(FileName, false);
265
266 Set_Name (pGrid->Get_Name());
267 Set_Description (pGrid->Get_Description());
268
269 m_System = pGrid->m_System;
270 m_Type = pGrid->m_Type;
271 m_Values = pGrid->m_Values; pGrid->m_Values = NULL; // take ownership of data array
272
273 m_zOffset = pGrid->m_zOffset;
274 m_zScale = pGrid->m_zScale;
275 m_Unit = pGrid->m_Unit;
276
277 m_nBytes_Value = pGrid->m_nBytes_Value;
278 m_nBytes_Line = pGrid->m_nBytes_Line;
279
280 Get_MetaData () = pGrid->Get_MetaData ();
281 Get_Projection() = pGrid->Get_Projection();
282
283 Set_NoData_Value_Range(pGrid->Get_NoData_Value(), pGrid->Get_NoData_Value(true));
284
285 return( true );
286 }
287
288 return( false );
289 }
290
291 //---------------------------------------------------------
_Load_PGSQL(const CSG_String & FileName,bool bCached,bool bLoadData)292 bool CSG_Grid::_Load_PGSQL(const CSG_String &FileName, bool bCached, bool bLoadData)
293 {
294 bool bResult = false;
295
296 if( FileName.BeforeFirst(':').Cmp("PGSQL") == 0 ) // database source
297 {
298 CSG_String s(FileName);
299
300 s = s.AfterFirst(':'); CSG_String Host (s.BeforeFirst(':'));
301 s = s.AfterFirst(':'); CSG_String Port (s.BeforeFirst(':'));
302 s = s.AfterFirst(':'); CSG_String DBName(s.BeforeFirst(':'));
303 s = s.AfterFirst(':'); CSG_String Table (s.BeforeFirst(':'));
304 s = s.AfterFirst(':'); CSG_String rid (s.BeforeFirst(':').AfterFirst('='));
305
306 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("db_pgsql", 0, true); // CGet_Connections
307
308 if( pTool != NULL )
309 {
310 SG_UI_ProgressAndMsg_Lock(true);
311
312 //---------------------------------------------
313 CSG_Table Connections;
314 CSG_String Connection = DBName + " [" + Host + ":" + Port + "]";
315
316 pTool->Set_Manager(NULL);
317 pTool->On_Before_Execution();
318
319 if( SG_TOOL_PARAMETER_SET("CONNECTIONS", &Connections) && pTool->Execute() ) // CGet_Connections
320 {
321 for(int i=0; !bResult && i<Connections.Get_Count(); i++)
322 {
323 if( !Connection.Cmp(Connections[i].asString(0)) )
324 {
325 bResult = true;
326 }
327 }
328 }
329
330 SG_Get_Tool_Library_Manager().Delete_Tool(pTool);
331
332 //---------------------------------------------
333 if( bResult && (bResult = (pTool = SG_Get_Tool_Library_Manager().Create_Tool("db_pgsql", 33, true)) != NULL) == true ) // CPGIS_Raster_Load_Band
334 {
335 pTool->Set_Manager(NULL);
336 pTool->On_Before_Execution();
337
338 bResult = SG_TOOL_PARAMETER_SET("CONNECTION", Connection)
339 && SG_TOOL_PARAMETER_SET("TABLES" , Table)
340 && SG_TOOL_PARAMETER_SET("RID" , rid)
341 && SG_TOOL_PARAMETER_SET("GRID" , this)
342 && pTool->Execute();
343
344 SG_Get_Tool_Library_Manager().Delete_Tool(pTool);
345 }
346
347 SG_UI_ProgressAndMsg_Lock(false);
348 }
349 }
350
351 return( bResult );
352 }
353
354
355 ///////////////////////////////////////////////////////////
356 // //
357 // Native //
358 // //
359 ///////////////////////////////////////////////////////////
360
361 //---------------------------------------------------------
_Load_Native(const CSG_String & FileName,bool bCached,bool bLoadData)362 bool CSG_Grid::_Load_Native(const CSG_String &FileName, bool bCached, bool bLoadData)
363 {
364 CSG_Grid_File_Info Info;
365
366 if( !Info.Create(FileName) )
367 {
368 return( false );
369 }
370
371 Set_File_Name(FileName, true);
372
373 Set_Name (Info.m_Name);
374 Set_Description (Info.m_Description);
375 Set_Unit (Info.m_Unit);
376
377 Set_NoData_Value_Range(Info.m_NoData[0], Info.m_NoData[1]);
378
379 m_System = Info.m_System;
380 m_Type = Info.m_Type;
381 m_zScale = Info.m_zScale;
382 m_zOffset = Info.m_zOffset;
383
384 m_nBytes_Value = SG_Data_Type_Get_Size(m_Type);
385 m_nBytes_Line = m_Type == SG_DATATYPE_Bit ? 1 + Get_NX() / 8 : Get_NX() * m_nBytes_Value;
386
387 Get_Projection().Load(SG_File_Make_Path("", FileName, "prj"), SG_PROJ_FMT_WKT);
388
389 if( !bLoadData )
390 {
391 return( _Memory_Create(bCached) );
392 }
393
394 Load_MetaData(FileName);
395
396 //-----------------------------------------------------
397 CSG_File Stream;
398
399 if( !SG_Data_Type_is_Numeric(m_Type) ) // ASCII...
400 {
401 if( Stream.Open(Info.m_Data_File , SG_FILE_R, false)
402 || Stream.Open(SG_File_Make_Path("", FileName, "dat"), SG_FILE_R, false)
403 || Stream.Open(SG_File_Make_Path("", FileName, "sdat"), SG_FILE_R, false) )
404 {
405 Stream.Seek(Info.m_Offset);
406
407 return( _Load_ASCII(Stream, bCached, Info.m_bFlip) );
408 }
409 }
410
411 //-----------------------------------------------------
412 else // Binary...
413 {
414 if( bCached || _Cache_Check() )
415 {
416 if( _Cache_Create(Info.m_Data_File , m_Type, Info.m_Offset, Info.m_bSwapBytes, Info.m_bFlip)
417 || _Cache_Create(SG_File_Make_Path("", FileName, "dat"), m_Type, Info.m_Offset, Info.m_bSwapBytes, Info.m_bFlip)
418 || _Cache_Create(SG_File_Make_Path("", FileName, "sdat"), m_Type, Info.m_Offset, Info.m_bSwapBytes, Info.m_bFlip) )
419 {
420 return( true );
421 }
422 }
423
424 m_Cache_File = Info.m_Data_File;
425 m_Cache_Offset = Info.m_Offset;
426 m_Cache_bSwap = Info.m_bSwapBytes;
427 m_Cache_bFlip = Info.m_bFlip;
428
429 if( _Memory_Create(bCached) )
430 {
431 if( Stream.Open(Info.m_Data_File , SG_FILE_R, true)
432 || Stream.Open(SG_File_Make_Path("", FileName, "dat"), SG_FILE_R, true)
433 || Stream.Open(SG_File_Make_Path("", FileName, "sdat"), SG_FILE_R, true) )
434 {
435 Stream.Seek(Info.m_Offset);
436
437 return( _Load_Binary(Stream, m_Type, Info.m_bFlip, Info.m_bSwapBytes) );
438 }
439 }
440 }
441
442 return( false );
443 }
444
445 //---------------------------------------------------------
_Save_Native(const CSG_String & _FileName,TSG_Grid_File_Format Format)446 bool CSG_Grid::_Save_Native(const CSG_String &_FileName, TSG_Grid_File_Format Format)
447 {
448 #ifdef WORDS_BIGENDIAN
449 bool bBigEndian = true;
450 #else
451 bool bBigEndian = false;
452 #endif
453
454 CSG_String FileName(_FileName);
455
456 bool bBinary;
457
458 if( Format == GRID_FILE_FORMAT_ASCII )
459 {
460 bBinary = false;
461 }
462 else if( Format == GRID_FILE_FORMAT_Binary_old )
463 {
464 bBinary = true; SG_File_Set_Extension(FileName, "sgrd");
465 }
466 else
467 {
468 bBinary = true; SG_File_Set_Extension(FileName, "sg-grd");
469 }
470
471 CSG_Grid_File_Info Info(*this);
472
473 if( Info.Save(FileName, bBinary) )
474 {
475 CSG_File Stream(SG_File_Make_Path("", FileName, "sdat"), SG_FILE_W, true);
476
477 if( bBinary ? _Save_Binary(Stream, m_Type, false, bBigEndian) : _Save_ASCII (Stream) )
478 {
479 Save_MetaData(FileName);
480
481 Get_Projection().Save(SG_File_Make_Path("", FileName, "prj"), SG_PROJ_FMT_WKT);
482
483 Info.Save_AUX_XML(SG_File_Make_Path("", FileName, "sdat"));
484
485 return( true );
486 }
487 }
488
489 return( false );
490 }
491
492
493 ///////////////////////////////////////////////////////////
494 // //
495 // Compressed //
496 // //
497 ///////////////////////////////////////////////////////////
498
499 //---------------------------------------------------------
_Load_Compressed(const CSG_String & _FileName,bool bCached,bool bLoadData)500 bool CSG_Grid::_Load_Compressed(const CSG_String &_FileName, bool bCached, bool bLoadData)
501 {
502 Set_File_Name(_FileName, true);
503
504 CSG_File_Zip Stream(_FileName, SG_FILE_R);
505
506 if( !Stream.is_Reading() )
507 {
508 return( false );
509 }
510
511 //-----------------------------------------------------
512 CSG_String FileName(SG_File_Get_Name(_FileName, false) + ".");
513
514 if( !Stream.Get_File(FileName + "sgrd" )
515 && !Stream.Get_File(FileName + "sg-grd") )
516 {
517 FileName.Clear();
518
519 for(size_t i=0; i<Stream.Get_File_Count(); i++)
520 {
521 if( SG_File_Cmp_Extension(Stream.Get_File_Name(i), "sgrd" )
522 || SG_File_Cmp_Extension(Stream.Get_File_Name(i), "sg-grd") )
523 {
524 FileName = SG_File_Get_Name(Stream.Get_File_Name(i), false) + ".";
525 Stream.Get_File(Stream.Get_File_Name(i));
526 break;
527 }
528 }
529
530 if( FileName.is_Empty() )
531 {
532 return( false );
533 }
534 }
535
536 //-----------------------------------------------------
537 CSG_Grid_File_Info Info;
538
539 if( !Info.Create(Stream) )
540 {
541 return( false );
542 }
543
544 Set_Name (Info.m_Name);
545 Set_Description (Info.m_Description);
546 Set_Unit (Info.m_Unit);
547
548 Set_NoData_Value_Range(Info.m_NoData[0], Info.m_NoData[1]);
549
550 m_System = Info.m_System;
551 m_Type = Info.m_Type;
552 m_zScale = Info.m_zScale;
553 m_zOffset = Info.m_zOffset;
554
555 m_nBytes_Value = SG_Data_Type_Get_Size(m_Type);
556 m_nBytes_Line = m_Type == SG_DATATYPE_Bit ? 1 + Get_NX() / 8 : Get_NX() * m_nBytes_Value;
557
558 if( Stream.Get_File(FileName + "prj") )
559 {
560 Get_Projection().Load(Stream, SG_PROJ_FMT_WKT);
561 }
562
563 if( !bLoadData )
564 {
565 return( _Memory_Create(bCached) );
566 }
567
568 if( Stream.Get_File(FileName + "mgrd") )
569 {
570 Load_MetaData(Stream);
571 }
572
573 //-----------------------------------------------------
574 if( _Cache_Check() )
575 {
576 bCached = true;
577 }
578
579 return( Stream.Get_File(FileName + "sdat") && _Memory_Create(bCached)
580 && _Load_Binary(Stream, m_Type, Info.m_bFlip, Info.m_bSwapBytes)
581 );
582 }
583
584 //---------------------------------------------------------
_Save_Compressed(const CSG_String & _FileName)585 bool CSG_Grid::_Save_Compressed(const CSG_String &_FileName)
586 {
587 #ifdef WORDS_BIGENDIAN
588 bool bBigEndian = true;
589 #else
590 bool bBigEndian = false;
591 #endif
592
593 CSG_File_Zip Stream(_FileName, SG_FILE_W);
594
595 if( Stream.is_Writing() )
596 {
597 CSG_String FileName(SG_File_Get_Name(_FileName, false) + ".");
598
599 CSG_Grid_File_Info Info(*this);
600
601 if( Stream.Add_File(FileName + "sgrd") && Info.Save(Stream, true)
602 && Stream.Add_File(FileName + "sdat") && _Save_Binary(Stream, m_Type, false, bBigEndian) )
603 {
604 Stream.Add_File(FileName + "mgrd" ); Save_MetaData(Stream);
605 Stream.Add_File(FileName + "prj" ); Get_Projection().Save(Stream, SG_PROJ_FMT_WKT);
606 Stream.Add_File(FileName + "sdat.aux.xml"); Info.Save_AUX_XML(Stream);
607
608 return( true );
609 }
610 }
611
612 return( false );
613 }
614
615
616 ///////////////////////////////////////////////////////////
617 // //
618 // Binary //
619 // //
620 ///////////////////////////////////////////////////////////
621
622 //---------------------------------------------------------
_Swap_Bytes(char * Bytes,int nBytes) const623 void CSG_Grid::_Swap_Bytes(char *Bytes, int nBytes) const
624 {
625 if( nBytes == 2 )
626 {
627 uint16_t val, valSwapped;
628 memcpy(&val, Bytes, nBytes);
629 valSwapped = ntohs(val);
630 memcpy(Bytes, &valSwapped, nBytes);
631 }
632 else if( nBytes == 4 )
633 {
634 uint32_t val, valSwapped;
635 memcpy(&val, Bytes, nBytes);
636 valSwapped = ntohl(val);
637 memcpy(Bytes, &valSwapped, nBytes);
638 }
639 }
640
641 //---------------------------------------------------------
_Load_Binary(CSG_File & Stream,TSG_Data_Type File_Type,bool bFlip,bool bSwapBytes)642 bool CSG_Grid::_Load_Binary(CSG_File &Stream, TSG_Data_Type File_Type, bool bFlip, bool bSwapBytes)
643 {
644 if( !Stream.is_Open() || !is_Valid() )
645 {
646 return( false );
647 }
648
649 Set_File_Type(GRID_FILE_FORMAT_Binary);
650
651 //-----------------------------------------------------
652 if( File_Type == SG_DATATYPE_Bit )
653 {
654 int nLineBytes = Get_NX() / 8 + 1;
655
656 if( m_Type == File_Type && !is_Cached() )
657 {
658 for(int y=0; y<Get_NY() && !Stream.is_EOF() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
659 {
660 Stream.Read(m_Values[bFlip ? Get_NY() - y - 1 : y], sizeof(char), nLineBytes);
661 }
662 }
663 else
664 {
665 CSG_Array Line(1, nLineBytes);
666
667 for(int y=0; y<Get_NY() && !Stream.is_EOF() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
668 {
669 Stream.Read(Line.Get_Array(), nLineBytes);
670
671 char *pValue = (char *)Line.Get_Array();
672
673 for(int x=0, yy=bFlip ? Get_NY()-y-1 : y; x<Get_NX(); pValue++)
674 {
675 for(int i=0; i<8 && x<Get_NX(); i++, x++)
676 {
677 Set_Value(x, yy, (*pValue & m_Bitmask[i]) == 0 ? 0.0 : 1.0);
678 }
679 }
680 }
681 }
682 }
683
684 //-----------------------------------------------------
685 else
686 {
687 int nValueBytes = (int)SG_Data_Type_Get_Size(File_Type);
688 int nLineBytes = Get_NX() * nValueBytes;
689
690 if( m_Type == File_Type && !is_Cached() && !bSwapBytes )
691 {
692 for(int y=0; y<Get_NY() && !Stream.is_EOF() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
693 {
694 Stream.Read(m_Values[bFlip ? Get_NY() - y - 1 : y], nLineBytes);
695 }
696 }
697 else
698 {
699 CSG_Array Line(1, nLineBytes);
700
701 for(int y=0; y<Get_NY() && !Stream.is_EOF() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
702 {
703 Stream.Read(Line.Get_Array(), nLineBytes);
704
705 char *pValue = (char *)Line.Get_Array();
706
707 for(int x=0, yy=bFlip ? Get_NY()-y-1 : y; x<Get_NX(); x++, pValue+=nValueBytes)
708 {
709 if( bSwapBytes )
710 {
711 _Swap_Bytes(pValue, nValueBytes);
712 }
713
714 switch( File_Type )
715 {
716 case SG_DATATYPE_Byte : Set_Value(x, yy, *(BYTE *)pValue, false); break;
717 case SG_DATATYPE_Char : Set_Value(x, yy, *(char *)pValue, false); break;
718 case SG_DATATYPE_Word : Set_Value(x, yy, *(WORD *)pValue, false); break;
719 case SG_DATATYPE_Short : Set_Value(x, yy, *(short *)pValue, false); break;
720 case SG_DATATYPE_DWord : Set_Value(x, yy, *(DWORD *)pValue, false); break;
721 case SG_DATATYPE_Int : Set_Value(x, yy, *(int *)pValue, false); break;
722 case SG_DATATYPE_Float : Set_Value(x, yy, *(float *)pValue, false); break;
723 case SG_DATATYPE_Double: Set_Value(x, yy, *(double *)pValue, false); break;
724 default: break;
725 }
726 }
727 }
728 }
729 }
730
731 //-----------------------------------------------------
732 return( true );
733 }
734
735 //---------------------------------------------------------
_Save_Binary(CSG_File & Stream,TSG_Data_Type File_Type,bool bFlip,bool bSwapBytes)736 bool CSG_Grid::_Save_Binary(CSG_File &Stream, TSG_Data_Type File_Type, bool bFlip, bool bSwapBytes)
737 {
738 //-----------------------------------------------------
739 if( !Stream.is_Writing() || !is_Valid() )
740 {
741 return( false );
742 }
743
744 Set_File_Type(GRID_FILE_FORMAT_Binary);
745
746 //-----------------------------------------------------
747 if( File_Type == SG_DATATYPE_Bit )
748 {
749 int nLineBytes = Get_NX() / 8 + 1;
750
751 if( m_Type == File_Type && !is_Cached() )
752 {
753 for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
754 {
755 Stream.Write((char *)m_Values[bFlip ? Get_NY() - y - 1 : y], sizeof(char), nLineBytes);
756 }
757 }
758 else
759 {
760 CSG_Array Line(1, nLineBytes);
761
762 for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
763 {
764 char *pValue = (char *)Line.Get_Array();
765
766 for(int x=0, yy=bFlip ? Get_NY()-y-1 : y; x<Get_NX(); pValue++)
767 {
768 for(int i=0; i<8 && x<Get_NX(); i++, x++)
769 {
770 *pValue = asChar(x, yy) != 0.0 ? *pValue | m_Bitmask[i] : *pValue & (~m_Bitmask[i]);
771 }
772 }
773
774 Stream.Write(Line.Get_Array(), nLineBytes);
775 }
776 }
777 }
778
779 //-----------------------------------------------------
780 else
781 {
782 int nValueBytes = (int)SG_Data_Type_Get_Size(File_Type);
783 int nLineBytes = Get_NX() * nValueBytes;
784
785 if( m_Type == File_Type && !is_Cached() && !bSwapBytes )
786 {
787 for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
788 {
789 Stream.Write((char *)m_Values[bFlip ? Get_NY() - y - 1 : y], nLineBytes);
790 }
791 }
792 else
793 {
794 CSG_Array Line(1, nLineBytes);
795
796 for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
797 {
798 char *pValue = (char *)Line.Get_Array();
799
800 for(int x=0, yy=bFlip ? Get_NY()-y-1 : y; x<Get_NX(); x++, pValue+=nValueBytes)
801 {
802 switch( File_Type )
803 {
804 case SG_DATATYPE_Byte : *(BYTE *)pValue = asByte (x, yy, false); break;
805 case SG_DATATYPE_Char : *(char *)pValue = asChar (x, yy, false); break;
806 case SG_DATATYPE_Word : *(WORD *)pValue = asShort (x, yy, false); break;
807 case SG_DATATYPE_Short : *(short *)pValue = asShort (x, yy, false); break;
808 case SG_DATATYPE_DWord : *(DWORD *)pValue = asInt (x, yy, false); break;
809 case SG_DATATYPE_Int : *(int *)pValue = asInt (x, yy, false); break;
810 case SG_DATATYPE_Float : *(float *)pValue = asFloat (x, yy, false); break;
811 case SG_DATATYPE_Double: *(double *)pValue = asDouble(x, yy, false); break;
812 default: break;
813 }
814
815 if( bSwapBytes )
816 {
817 _Swap_Bytes(pValue, nValueBytes);
818 }
819 }
820
821 Stream.Write(Line.Get_Array(), nLineBytes);
822 }
823 }
824 }
825
826 //-----------------------------------------------------
827 return( true );
828 }
829
830
831 ///////////////////////////////////////////////////////////
832 // //
833 // ASCII //
834 // //
835 ///////////////////////////////////////////////////////////
836
837 //---------------------------------------------------------
_Load_ASCII(CSG_File & Stream,bool bCached,bool bFlip)838 bool CSG_Grid::_Load_ASCII(CSG_File &Stream, bool bCached, bool bFlip)
839 {
840 if( !Stream.is_Reading() || !_Memory_Create(bCached) )
841 {
842 return( false );
843 }
844
845 Set_File_Type(GRID_FILE_FORMAT_ASCII);
846
847 for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
848 {
849 for(int x=0, yy=bFlip ? Get_NY()-y-1 : y; x<Get_NX(); x++)
850 {
851 Set_Value(x, yy, Stream.Scan_Double());
852 }
853 }
854
855 return( true );
856 }
857
858 //---------------------------------------------------------
_Save_ASCII(CSG_File & Stream,bool bFlip)859 bool CSG_Grid::_Save_ASCII(CSG_File &Stream, bool bFlip)
860 {
861 if( !Stream.is_Writing() || !is_Valid() )
862 {
863 return( false );
864 }
865
866 Set_File_Type(GRID_FILE_FORMAT_ASCII);
867
868 for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
869 {
870 for(int x=0, yy=bFlip ? Get_NY()-y-1 : y; x<Get_NX(); x++)
871 {
872 Stream.Printf("%lf ", asDouble(x, yy));
873 }
874
875 Stream.Printf("\n");
876 }
877
878 return( true );
879 }
880
881
882 ///////////////////////////////////////////////////////////
883 // //
884 ///////////////////////////////////////////////////////////
885
886 //---------------------------------------------------------
_Load_Surfer(const CSG_String & FileName,bool bCached,bool bLoadData)887 bool CSG_Grid::_Load_Surfer(const CSG_String &FileName, bool bCached, bool bLoadData)
888 {
889 const float NoData = 1.70141e38f;
890
891 if( !SG_File_Cmp_Extension(FileName, "grd") )
892 {
893 return( false );
894 }
895
896 Set_File_Name(FileName, true);
897
898 //-----------------------------------------------------
899 CSG_File Stream;
900
901 if( !Stream.Open(FileName, SG_FILE_R, true) )
902 {
903 return( false );
904 }
905
906 char Identifier[4];
907
908 Stream.Read(Identifier, sizeof(char), 4);
909
910 //-----------------------------------------------------
911 if( !strncmp(Identifier, "DSBB", 4) ) // Binary...
912 {
913 short nx, ny;
914 double d;
915 TSG_Rect r;
916
917 Stream.Read(&nx , sizeof(short ));
918 Stream.Read(&ny , sizeof(short ));
919 Stream.Read(&r.xMin, sizeof(double));
920 Stream.Read(&r.xMax, sizeof(double));
921 Stream.Read(&r.yMin, sizeof(double));
922 Stream.Read(&r.yMax, sizeof(double));
923 Stream.Read(&d , sizeof(double)); // zMin
924 Stream.Read(&d , sizeof(double)); // zMax
925
926 d = (r.xMax - r.xMin) / (nx - 1.0);
927 // d = (r.yMax - r.yMin) / (ny - 1.0); // we could proof for equal cellsize in direction of y...
928
929 //-------------------------------------------------
930 if( !Create(SG_DATATYPE_Float, nx, ny, d, r.xMin, r.yMin, bCached) || Stream.is_EOF() )
931 {
932 return( false );
933 }
934
935 //-------------------------------------------------
936 if( bLoadData )
937 {
938 CSG_Array Line(sizeof(float), Get_NX()); float *Values = (float *)Line.Get_Array();
939
940 for(int y=0; y<Get_NY() && !Stream.is_EOF() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
941 {
942 Stream.Read(Values, sizeof(float), Get_NX());
943
944 for(int x=0; x<Get_NX(); x++)
945 {
946 if( Values[x] == NoData )
947 {
948 Set_NoData(x, y);
949 }
950 else
951 {
952 Set_Value(x, y, Values[x]);
953 }
954 }
955 }
956 }
957
958 Get_MetaData().Add_Child("SURFER_GRID", "Surfer Grid (Binary)");
959 }
960
961 //-----------------------------------------------------
962 else if( !strncmp(Identifier, "DSAA", 4) ) // ASCII...
963 {
964 int nx = Stream.Scan_Int ();
965 int ny = Stream.Scan_Int ();
966 double xMin = Stream.Scan_Double();
967 double xMax = Stream.Scan_Double();
968 double yMin = Stream.Scan_Double(); Stream.Scan_Double();
969 // double yMax = Stream.Scan_Double();
970 double dx = Stream.Scan_Double(); Stream.Scan_Double();
971 // double dy = Stream.Scan_Double();
972
973 dx = (xMax - xMin) / (nx - 1.0);
974 // dy = (yMax - yMin) / (ny - 1.0); // we could proof for equal cellsize in direction of y...
975
976 //-------------------------------------------------
977 if( !Create(SG_DATATYPE_Float, nx, ny, dx, xMin, yMin, bCached) || Stream.is_EOF() )
978 {
979 return( false );
980 }
981
982 //-------------------------------------------------
983 if( bLoadData )
984 {
985 for(int y=0; y<Get_NY() && !Stream.is_EOF() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
986 {
987 for(int x=0; x<Get_NX(); x++)
988 {
989 double Value;
990
991 if( Stream.Scan(Value) && Value != NoData )
992 {
993 Set_Value(x, y, Value);
994 }
995 else
996 {
997 Set_NoData(x, y);
998 }
999 }
1000 }
1001 }
1002
1003 Get_MetaData().Add_Child("SURFER_GRID", "Surfer Grid (ASCII)");
1004 }
1005
1006 //-------------------------------------------------
1007 SG_UI_Process_Set_Ready();
1008
1009 Set_File_Name(FileName);
1010 Load_MetaData(FileName);
1011
1012 return( true );
1013 }
1014
1015
1016 ///////////////////////////////////////////////////////////
1017 // //
1018 // //
1019 // //
1020 ///////////////////////////////////////////////////////////
1021
1022 //---------------------------------------------------------
CSG_Grid_File_Info(void)1023 CSG_Grid_File_Info::CSG_Grid_File_Info(void)
1024 {
1025 _On_Construction();
1026 }
1027
_On_Construction(void)1028 void CSG_Grid_File_Info::_On_Construction(void)
1029 {
1030 m_Name .Clear();
1031 m_Description .Clear();
1032 m_Unit .Clear();
1033 m_System .Assign(0.0, 0.0, 0.0, 0, 0);
1034 m_Type = SG_DATATYPE_Float; // defaults to float
1035 m_zScale = 1.0;
1036 m_zOffset = 0;
1037 m_NoData[0] = -99999.0;
1038 m_NoData[1] = -99999.0;
1039 m_Data_File .Clear();
1040 m_bFlip = false;
1041 m_bSwapBytes = false;
1042 m_Offset = 0;
1043 m_Projection .Destroy();
1044 }
1045
1046 //---------------------------------------------------------
CSG_Grid_File_Info(const CSG_Grid_File_Info & Info)1047 CSG_Grid_File_Info::CSG_Grid_File_Info(const CSG_Grid_File_Info &Info)
1048 {
1049 Create(Info);
1050 }
1051
Create(const CSG_Grid_File_Info & Info)1052 bool CSG_Grid_File_Info::Create(const CSG_Grid_File_Info &Info)
1053 {
1054 m_Name = Info.m_Name;
1055 m_Description = Info.m_Description;
1056 m_Unit = Info.m_Unit;
1057 m_System = Info.m_System;
1058 m_Type = Info.m_Type;
1059 m_zScale = Info.m_zScale;
1060 m_zOffset = Info.m_zOffset;
1061 m_NoData[0] = Info.m_NoData[0];
1062 m_NoData[1] = Info.m_NoData[1];
1063 m_Data_File = Info.m_Data_File;
1064 m_bFlip = Info.m_bFlip;
1065 m_bSwapBytes = Info.m_bSwapBytes;
1066 m_Offset = Info.m_Offset;
1067 m_Projection = Info.m_Projection;
1068
1069 return( true );
1070 }
1071
1072 //---------------------------------------------------------
CSG_Grid_File_Info(const CSG_Grid & Grid)1073 CSG_Grid_File_Info::CSG_Grid_File_Info(const CSG_Grid &Grid)
1074 {
1075 Create(Grid);
1076 }
1077
Create(const CSG_Grid & Grid)1078 bool CSG_Grid_File_Info::Create(const CSG_Grid &Grid)
1079 {
1080 m_Name = Grid.Get_Name();
1081 m_Description = Grid.Get_Description();
1082 m_Unit = Grid.Get_Unit();
1083 m_System = Grid.Get_System();
1084 m_Type = Grid.Get_Type();
1085 m_zScale = Grid.Get_Scaling();
1086 m_zOffset = Grid.Get_Offset();
1087 m_NoData[0] = Grid.Get_NoData_Value();
1088 m_NoData[1] = Grid.Get_NoData_Value(true);
1089 m_Data_File .Clear();
1090 m_bFlip = false;
1091 m_bSwapBytes = false;
1092 m_Offset = 0;
1093 m_Projection = Grid.Get_Projection();
1094
1095 return( true );
1096 }
1097
1098 //---------------------------------------------------------
CSG_Grid_File_Info(const CSG_String & FileName)1099 CSG_Grid_File_Info::CSG_Grid_File_Info(const CSG_String &FileName)
1100 {
1101 Create(FileName);
1102 }
1103
Create(const CSG_String & FileName)1104 bool CSG_Grid_File_Info::Create(const CSG_String &FileName)
1105 {
1106 if( !SG_File_Cmp_Extension(FileName, "sg-grd-z") )
1107 {
1108 if( SG_File_Cmp_Extension(FileName, "sgrd")
1109 || SG_File_Cmp_Extension(FileName, "sg-grd") )
1110 {
1111 CSG_File Stream(FileName, SG_FILE_R, false);
1112
1113 return( Create(Stream) );
1114 }
1115
1116 return( false );
1117 }
1118
1119 //-----------------------------------------------------
1120 CSG_File_Zip Stream(FileName, SG_FILE_R);
1121
1122 if( Stream.is_Reading() )
1123 {
1124 CSG_String File(SG_File_Get_Name(FileName, false) + ".");
1125
1126 if( !Stream.Get_File(File + "sgrd" )
1127 && !Stream.Get_File(File + "sg-grd") )
1128 {
1129 for(size_t i=0; i<Stream.Get_File_Count(); i++)
1130 {
1131 if( SG_File_Cmp_Extension(Stream.Get_File_Name(i), "sgrd" )
1132 || SG_File_Cmp_Extension(Stream.Get_File_Name(i), "sg-grd") )
1133 {
1134 Stream.Get_File(Stream.Get_File_Name(i));
1135 break;
1136 }
1137 }
1138 }
1139
1140 return( Create(Stream) );
1141 }
1142
1143 //-----------------------------------------------------
1144 return( false );
1145 }
1146
1147 //---------------------------------------------------------
CSG_Grid_File_Info(CSG_File & Stream)1148 CSG_Grid_File_Info::CSG_Grid_File_Info(CSG_File &Stream)
1149 {
1150 Create(Stream);
1151 }
1152
Create(CSG_File & Stream)1153 bool CSG_Grid_File_Info::Create(CSG_File &Stream)
1154 {
1155 _On_Construction();
1156
1157 //-----------------------------------------------------
1158 if( !Stream.is_Reading() )
1159 {
1160 return( false );
1161 }
1162
1163 //-----------------------------------------------------
1164 sLong NX = 0, NY = 0;
1165 double Cellsize = 0.0, xMin = 0.0, yMin = 0.0;
1166
1167 do
1168 {
1169 CSG_String Value;
1170
1171 switch( _Get_Key(Stream, Value) )
1172 {
1173 case GRID_FILE_KEY_NAME : m_Name = Value; break;
1174 case GRID_FILE_KEY_DESCRIPTION : m_Description = Value; break;
1175 case GRID_FILE_KEY_UNITNAME : m_Unit = Value; break;
1176
1177 case GRID_FILE_KEY_CELLCOUNT_X : NX = Value.asInt (); break;
1178 case GRID_FILE_KEY_CELLCOUNT_Y : NY = Value.asInt (); break;
1179 case GRID_FILE_KEY_POSITION_XMIN : xMin = Value.asDouble(); break;
1180 case GRID_FILE_KEY_POSITION_YMIN : yMin = Value.asDouble(); break;
1181 case GRID_FILE_KEY_CELLSIZE : Cellsize = Value.asDouble(); break;
1182
1183 case GRID_FILE_KEY_Z_FACTOR : m_zScale = Value.asDouble(); break;
1184 case GRID_FILE_KEY_Z_OFFSET : m_zOffset = Value.asDouble(); break;
1185 case GRID_FILE_KEY_NODATA_VALUE : m_NoData[0] = Value.asDouble();
1186 Value = Value.AfterFirst(';'); m_NoData[1] = Value.is_Empty() ? m_NoData[0] : Value.asDouble(); break;
1187
1188 case GRID_FILE_KEY_DATAFILE_OFFSET: m_Offset = Value.asInt (); break;
1189 case GRID_FILE_KEY_BYTEORDER_BIG : m_bSwapBytes = Value.Find(GRID_FILE_KEY_TRUE) >= 0; break;
1190 case GRID_FILE_KEY_TOPTOBOTTOM : m_bFlip = Value.Find(GRID_FILE_KEY_TRUE) >= 0; break;
1191
1192 case GRID_FILE_KEY_DATAFILE_NAME:
1193 if( SG_File_Get_Path(Value).Length() > 0 )
1194 {
1195 m_Data_File = Value;
1196 }
1197 else
1198 {
1199 m_Data_File = SG_File_Make_Path(SG_File_Get_Path(Stream.Get_File_Name()), Value);
1200 }
1201 break;
1202
1203 case GRID_FILE_KEY_DATAFORMAT:
1204 {
1205 for(int i=0; i<SG_DATATYPE_Undefined; i++)
1206 {
1207 if( Value.Find(gSG_Data_Type_Identifier[i]) >= 0 )
1208 {
1209 m_Type = (TSG_Data_Type)i;
1210
1211 break;
1212 }
1213 }
1214 }
1215 break;
1216 }
1217 }
1218 while( !Stream.is_EOF() );
1219
1220 //-----------------------------------------------------
1221 return( m_System.Assign(Cellsize, xMin, yMin, (int)NX, (int)NY) );
1222 }
1223
1224 //---------------------------------------------------------
_Get_Key(CSG_File & Stream,CSG_String & Value)1225 int CSG_Grid_File_Info::_Get_Key(CSG_File &Stream, CSG_String &Value)
1226 {
1227 int i;
1228 CSG_String sLine;
1229
1230 if( Stream.Read_Line(sLine) && (i = sLine.Find('=')) > 0 )
1231 {
1232 Value = sLine.AfterFirst('=');
1233 Value.Trim();
1234
1235 sLine.Remove(i);
1236
1237 for(i=0; i<GRID_FILE_KEY_Count; i++)
1238 {
1239 CSG_String s(gSG_Grid_File_Key_Names[i]);
1240
1241 if( s.Find(sLine.Left(s.Length())) >= 0 )
1242 {
1243 return( i );
1244 }
1245 }
1246 }
1247
1248 return( -1 );
1249 }
1250
1251
1252 ///////////////////////////////////////////////////////////
1253 // //
1254 ///////////////////////////////////////////////////////////
1255
1256 //---------------------------------------------------------
Save(const CSG_String & FileName,bool bBinary)1257 bool CSG_Grid_File_Info::Save(const CSG_String &FileName, bool bBinary)
1258 {
1259 return( Save(CSG_File(FileName, SG_FILE_W, false), bBinary) );
1260 }
1261
1262 //---------------------------------------------------------
Save(const CSG_File & Stream,bool bBinary)1263 bool CSG_Grid_File_Info::Save(const CSG_File &Stream, bool bBinary)
1264 {
1265 if( !Stream.is_Writing() )
1266 {
1267 return( false );
1268 }
1269
1270 #define GRID_FILE_PRINT(Key, Val) { CSG_String s(gSG_Grid_File_Key_Names[Key]); s += "\t= " + Val + "\n"; Stream.Write(s); }
1271
1272 GRID_FILE_PRINT(GRID_FILE_KEY_NAME , CSG_String::Format("%s" , m_Name .c_str() ));
1273 GRID_FILE_PRINT(GRID_FILE_KEY_DESCRIPTION , CSG_String::Format("%s" , m_Description.c_str() ));
1274 GRID_FILE_PRINT(GRID_FILE_KEY_UNITNAME , CSG_String::Format("%s" , m_Unit .c_str() ));
1275 GRID_FILE_PRINT(GRID_FILE_KEY_DATAFORMAT , CSG_String::Format("%s" , CSG_String(bBinary ? gSG_Data_Type_Identifier[m_Type] : "ASCII").c_str()));
1276 GRID_FILE_PRINT(GRID_FILE_KEY_DATAFILE_OFFSET, CSG_String::Format("%d" , 0 ));
1277 #ifdef WORDS_BIGENDIAN
1278 GRID_FILE_PRINT(GRID_FILE_KEY_BYTEORDER_BIG , CSG_String::Format("%s" , GRID_FILE_KEY_TRUE ));
1279 #else
1280 GRID_FILE_PRINT(GRID_FILE_KEY_BYTEORDER_BIG , CSG_String::Format("%s" , GRID_FILE_KEY_FALSE ));
1281 #endif
1282 GRID_FILE_PRINT(GRID_FILE_KEY_TOPTOBOTTOM , CSG_String::Format("%s" , GRID_FILE_KEY_FALSE ));
1283 GRID_FILE_PRINT(GRID_FILE_KEY_POSITION_XMIN , CSG_String::Format("%.*f" , CSG_Grid_System::Get_Precision(), m_System.Get_XMin()));
1284 GRID_FILE_PRINT(GRID_FILE_KEY_POSITION_YMIN , CSG_String::Format("%.*f" , CSG_Grid_System::Get_Precision(), m_System.Get_YMin()));
1285 GRID_FILE_PRINT(GRID_FILE_KEY_CELLCOUNT_X , CSG_String::Format("%d" , m_System.Get_NX() ));
1286 GRID_FILE_PRINT(GRID_FILE_KEY_CELLCOUNT_Y , CSG_String::Format("%d" , m_System.Get_NY() ));
1287 GRID_FILE_PRINT(GRID_FILE_KEY_CELLSIZE , CSG_String::Format("%.*f" , CSG_Grid_System::Get_Precision(), m_System.Get_Cellsize()));
1288 GRID_FILE_PRINT(GRID_FILE_KEY_Z_FACTOR , CSG_String::Format("%f" , m_zScale ));
1289 GRID_FILE_PRINT(GRID_FILE_KEY_Z_OFFSET , CSG_String::Format("%f" , m_zOffset ));
1290 GRID_FILE_PRINT(GRID_FILE_KEY_NODATA_VALUE , CSG_String::Format("%f;%f", m_NoData[0], m_NoData[1]));
1291
1292 return( true );
1293 }
1294
1295 //---------------------------------------------------------
Save(const CSG_String & FileName,const CSG_Grid & Grid,bool bBinary)1296 bool CSG_Grid_File_Info::Save(const CSG_String &FileName, const CSG_Grid &Grid, bool bBinary)
1297 {
1298 CSG_Grid_File_Info Info(Grid);
1299
1300 return( Info.Save(FileName, bBinary) );
1301 }
1302
1303 //---------------------------------------------------------
Save(const CSG_File & Stream,const CSG_Grid & Grid,bool bBinary)1304 bool CSG_Grid_File_Info::Save(const CSG_File &Stream, const CSG_Grid &Grid, bool bBinary)
1305 {
1306 CSG_Grid_File_Info Info(Grid);
1307
1308 return( Info.Save(Stream, bBinary) );
1309 }
1310
1311
1312 ///////////////////////////////////////////////////////////
1313 // //
1314 ///////////////////////////////////////////////////////////
1315
1316 //---------------------------------------------------------
Save_AUX_XML(const CSG_String & FileName)1317 bool CSG_Grid_File_Info::Save_AUX_XML(const CSG_String &FileName)
1318 {
1319 CSG_File Stream;
1320
1321 return( m_Projection.is_Okay() && Stream.Open(FileName + ".aux.xml", SG_FILE_W, false) && Save_AUX_XML(Stream) );
1322 }
1323
1324 //---------------------------------------------------------
Save_AUX_XML(CSG_File & Stream)1325 bool CSG_Grid_File_Info::Save_AUX_XML(CSG_File &Stream)
1326 {
1327 if( m_Projection.is_Okay() && Stream.is_Writing() ) // store srs information that is recognized by ArcGIS
1328 {
1329 Stream.Write("<PAMDataset>\n<SRS>");
1330 Stream.Write(m_Projection.Get_WKT());
1331 Stream.Write("</SRS>\n</PAMDataset>\n");
1332
1333 return( true );
1334 }
1335
1336 return( false );
1337 }
1338
1339
1340 ///////////////////////////////////////////////////////////
1341 // //
1342 // //
1343 // //
1344 ///////////////////////////////////////////////////////////
1345
1346 //---------------------------------------------------------
1347