SAGA API v9.10
Loading...
Searching...
No Matches
grids.cpp
Go to the documentation of this file.
1
3// //
4// SAGA //
5// //
6// System for Automated Geoscientific Analyses //
7// //
8// Application Programming Interface //
9// //
10// Library: SAGA_API //
11// //
12//-------------------------------------------------------//
13// //
14// grids.cpp //
15// //
16// Copyright (C) 2017 by //
17// Olaf Conrad //
18// //
19//-------------------------------------------------------//
20// //
21// This file is part of 'SAGA - System for Automated //
22// Geoscientific Analyses'. //
23// //
24// This library is free software; you can redistribute //
25// it and/or modify it under the terms of the GNU Lesser //
26// General Public License as published by the Free //
27// Software Foundation, either version 2.1 of the //
28// License, or (at your option) any later version. //
29// //
30// This library is distributed in the hope that it will //
31// be useful, but WITHOUT ANY WARRANTY; without even the //
32// implied warranty of MERCHANTABILITY or FITNESS FOR A //
33// PARTICULAR PURPOSE. See the GNU Lesser General Public //
34// License for more details. //
35// //
36// You should have received a copy of the GNU Lesser //
37// General Public License along with this program; if //
38// not, see <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 Hamburg //
47// Germany //
48// //
50
51//---------------------------------------------------------
52#include "saga_api.h"
53#include "grids.h"
54#include "data_manager.h"
55#include "tool_library.h"
56
57
59// //
60// //
61// //
63
64//---------------------------------------------------------
66{
67 return( new CSG_Grids );
68}
69
70//---------------------------------------------------------
72{
73 CSG_Grids *pGrids = new CSG_Grids(Grids);
74
75 if( !pGrids->is_Valid() )
76 {
77 delete(pGrids); pGrids = NULL;
78 }
79
80 return( pGrids );
81}
82
83//---------------------------------------------------------
84CSG_Grids * SG_Create_Grids(const CSG_Grids *_pGrids, bool bCopyData)
85{
86 CSG_Grids *pGrids = new CSG_Grids(_pGrids, bCopyData);
87
88 if( !pGrids->is_Valid() )
89 {
90 delete(pGrids); pGrids = NULL;
91 }
92
93 return( pGrids );
94}
95
96//---------------------------------------------------------
97CSG_Grids * SG_Create_Grids(const char *File, bool bLoadData) { return( SG_Create_Grids(CSG_String(File), bLoadData) ); }
98CSG_Grids * SG_Create_Grids(const wchar_t *File, bool bLoadData) { return( SG_Create_Grids(CSG_String(File), bLoadData) ); }
99CSG_Grids * SG_Create_Grids(const CSG_String &File, bool bLoadData)
100{
101 CSG_Grids *pGrids = new CSG_Grids();
102
103 if( !pGrids->Create(File, bLoadData) )
104 {
105 delete(pGrids); pGrids = NULL;
106 }
107
108 return( pGrids );
109}
110
111//---------------------------------------------------------
112CSG_Grids * SG_Create_Grids(const CSG_Grid_System &System, int NZ, double zMin, TSG_Data_Type Type)
113{
114 CSG_Grids *pGrids = new CSG_Grids(System, NZ, zMin, Type);
115
116 if( !pGrids->is_Valid() )
117 {
118 delete(pGrids); pGrids = NULL;
119 }
120
121 return( pGrids );
122}
123
124//---------------------------------------------------------
125CSG_Grids * SG_Create_Grids(const CSG_Grid_System &System, const CSG_Table &Attributes, int zAttribute, TSG_Data_Type Type, bool bCreateGrids)
126{
127 CSG_Grids *pGrids = new CSG_Grids(System, Attributes, zAttribute, Type, bCreateGrids);
128
129 if( bCreateGrids && !pGrids->is_Valid() )
130 {
131 delete(pGrids); pGrids = NULL;
132 }
133
134 return( pGrids );
135}
136
137//---------------------------------------------------------
138CSG_Grids * SG_Create_Grids(int NX, int NY, int NZ, double Cellsize, double xMin, double yMin, double zMin, TSG_Data_Type Type)
139{
140 CSG_Grids *pGrids = new CSG_Grids(NX, NY, NZ, Cellsize, xMin, yMin, zMin, Type);
141
142 if( !pGrids->is_Valid() )
143 {
144 delete(pGrids); pGrids = NULL;
145 }
146
147 return( pGrids );
148}
149
150//---------------------------------------------------------
151CSG_Grids * SG_Create_Grids(const CSG_Table &Attributes, int zAttribute)
152{
153 return( new CSG_Grids(Attributes, zAttribute) );
154}
155
156
158// //
159// //
160// //
162
163//---------------------------------------------------------
167//---------------------------------------------------------
169{
170 _On_Construction();
171}
172
173//---------------------------------------------------------
178{
179 Destroy();
180
181 delete(m_pGrids[0]); // The Dummy
182}
183
184//---------------------------------------------------------
188//---------------------------------------------------------
190{
191 _On_Construction();
192
193 Create(Grids);
194}
195
196//---------------------------------------------------------
203//---------------------------------------------------------
204CSG_Grids::CSG_Grids(const CSG_Grids *pGrids, bool bCopyData)
205{
206 _On_Construction();
207
208 Create(pGrids, bCopyData);
209}
210
211//---------------------------------------------------------
215//---------------------------------------------------------
216CSG_Grids::CSG_Grids(const char *File, bool bLoadData) { _On_Construction(); Create(File, bLoadData); }
217CSG_Grids::CSG_Grids(const wchar_t *File, bool bLoadData) { _On_Construction(); Create(File, bLoadData); }
218CSG_Grids::CSG_Grids(const CSG_String &File, bool bLoadData) { _On_Construction(); Create(File, bLoadData); }
219
220//---------------------------------------------------------
224//---------------------------------------------------------
225CSG_Grids::CSG_Grids(const CSG_Grid_System &System, int NZ, double zMin, TSG_Data_Type Type)
226{
227 _On_Construction();
228
229 Create(System, NZ, zMin, Type);
230}
231
232//---------------------------------------------------------
236//---------------------------------------------------------
237CSG_Grids::CSG_Grids(const CSG_Grid_System &System, const CSG_Table &Attributes, int zAttribute, TSG_Data_Type Type, bool bCreateGrids)
238{
239 _On_Construction();
240
241 Create(System, Attributes, zAttribute, Type, bCreateGrids);
242}
243
244//---------------------------------------------------------
248//---------------------------------------------------------
249CSG_Grids::CSG_Grids(int NX, int NY, int NZ, double Cellsize, double xMin, double yMin, double zMin, TSG_Data_Type Type)
250{
251 _On_Construction();
252
253 Create(NX, NY, NZ, Cellsize, xMin, yMin, zMin, Type);
254}
255
256//---------------------------------------------------------
260//---------------------------------------------------------
261CSG_Grids::CSG_Grids(const CSG_Table &Attributes, int zAttribute)
262{
263 _On_Construction();
264
265 Create(Attributes, zAttribute);
266}
267
268
270// //
272
273//---------------------------------------------------------
274void CSG_Grids::_On_Construction(void)
275{
276 m_pGrids = (CSG_Grid **)m_Grids.Create(1);
277 m_pGrids[0] = SG_Create_Grid(); // The Dummy
278 m_pGrids[0]->Set_Owner(this);
279
280 m_Attributes.Set_Owner(this);
281
282 m_Index = NULL;
283
284 Destroy();
285
287}
288
289//---------------------------------------------------------
294{
295 for(size_t i=1; i<m_Grids.Get_uSize(); i++)
296 {
297 delete(m_pGrids[i]); // do not delete the dummy before deconstruction
298 }
299
300 m_pGrids = (CSG_Grid **)m_Grids.Get_Array(1);
301
302 m_pGrids[0]->Destroy(); // The Dummy
303
304 SG_FREE_SAFE(m_Index);
305
306 m_Attributes.Destroy();
307 m_Attributes.Add_Field("Z", SG_DATATYPE_Double);
308 m_Z_Attribute = m_Z_Name = 0;
309
310 return( CSG_Data_Object::Destroy() );
311}
312
313
315// //
317
318//---------------------------------------------------------
319bool CSG_Grids::Create(const CSG_Grids &Grids)
320{
321 return( Create((CSG_Grids *)&Grids, true) );
322}
323
324//---------------------------------------------------------
325bool CSG_Grids::Create(const CSG_Grids *pGrids, bool bCopyData)
326{
327 if( pGrids && pGrids->is_Valid() && Create(pGrids->Get_System(), 0, 0., pGrids->Get_Type()) )
328 {
330
331 m_Attributes.Create(&pGrids->m_Attributes);
332 Set_Z_Attribute (pGrids->Get_Z_Attribute ());
334
335 if( bCopyData )
336 {
337 for(int i=0; i<pGrids->Get_NZ(); i++)
338 {
339 Add_Grid(pGrids->Get_Attributes(i), pGrids->Get_Grid_Ptr(i));
340 }
341 }
342
345
347
348 return( true );
349 }
350
351 return( false );
352}
353
354//---------------------------------------------------------
355bool CSG_Grids::Create(const char *File, bool bLoadData) { return( Load(CSG_String(File), bLoadData) ); }
356bool CSG_Grids::Create(const wchar_t *File, bool bLoadData) { return( Load(CSG_String(File), bLoadData) ); }
357bool CSG_Grids::Create(const CSG_String &File, bool bLoadData) { return( Load( File , bLoadData) ); }
358
359//---------------------------------------------------------
360bool CSG_Grids::Create(const CSG_Grid_System &System, int NZ, double zMin, TSG_Data_Type Type)
361{
362 Destroy();
363
364 if( m_pGrids[0]->Create(System, Type) )
365 {
366 Set_NoData_Value_Range(m_pGrids[0]->Get_NoData_Value(), m_pGrids[0]->Get_NoData_Value(true));
367
368 for(int i=0; i<NZ; i++, zMin+=System.Get_Cellsize())
369 {
370 if( !Add_Grid(zMin) )
371 {
372 return( false );
373 }
374 }
375
376 return( true );
377 }
378
379 return( false );
380}
381
382//---------------------------------------------------------
383bool CSG_Grids::Create(const CSG_Grid_System &System, const CSG_Table &Attributes, int zAttribute, TSG_Data_Type Type, bool bCreateGrids)
384{
385 Destroy();
386
387 if( m_Attributes.Create(&Attributes) && m_pGrids[0]->Create(System, Type) )
388 {
389 Set_Z_Attribute(zAttribute, true);
390
391 if( bCreateGrids )
392 {
393 for(int i=0; i<Attributes.Get_Count(); i++)
394 {
395 if( !Add_Grid(Attributes[i]) )
396 {
397 return( false );
398 }
399 }
400 }
401
402 return( true );
403 }
404
405 return( false );
406}
407
408//---------------------------------------------------------
409bool CSG_Grids::Create(int NX, int NY, int NZ, double Cellsize, double xMin, double yMin, double zMin, TSG_Data_Type Type)
410{
411 return( Create(CSG_Grid_System(Cellsize, xMin, yMin, NX, NY), NZ, zMin, Type) );
412}
413
414//---------------------------------------------------------
415bool CSG_Grids::Create(const CSG_Table &Attributes, int zAttribute)
416{
417 Destroy();
418
419 if( m_Attributes.Create(&Attributes) )
420 {
421 Set_Z_Attribute(zAttribute, true);
422
423 return( true );
424 }
425
426 return( false );
427}
428
429
431// //
432// Header //
433// //
435
436//---------------------------------------------------------
438{
439 m_pGrids[0]->Set_Unit(Unit);
440}
441
442//---------------------------------------------------------
443void CSG_Grids::Set_Scaling(double Scale, double Offset)
444{
445 m_pGrids[0]->Set_Scaling(Scale, Offset);
446
447 for(int i=1; i<Get_Grid_Count(); i++)
448 {
449 m_pGrids[i]->Set_Scaling(Scale, Offset);
450 }
451
453}
454
455//---------------------------------------------------------
456bool CSG_Grids::Set_NoData_Value_Range(double loValue, double hiValue)
457{
458 if( CSG_Data_Object::Set_NoData_Value_Range(loValue, hiValue) ) // this is a CSG_Data_Object base class property
459 {
460 m_pGrids[0]->Set_NoData_Value_Range(loValue, hiValue);
461
462 for(int i=1; i<Get_Grid_Count(); i++)
463 {
464 m_pGrids[i]->Set_NoData_Value_Range(loValue, hiValue);
465 }
466
467 return( true );
468 }
469
470 return( false );
471}
472
473//---------------------------------------------------------
474void CSG_Grids::_Synchronize(CSG_Grid *pGrid)
475{
476 if( !Get_Projection().is_Okay() && pGrid->Get_Projection().is_Okay() )
477 {
479 }
480
481 pGrid->Set_Owner(this);
482
483 if( pGrid == m_pGrids[0] )
484 {
485 Set_Scaling(pGrid->Get_Scaling(), pGrid->Get_Offset());
487 }
488 else // if( pGrid != m_pGrids[0] )
489 {
492 }
493}
494
495
497// //
498// Checks //
499// //
501
502//---------------------------------------------------------
503bool CSG_Grids::is_Valid(void) const
504{
505 return( Get_System().is_Valid() );
506}
507
508//---------------------------------------------------------
510{
511 return( pGrid && is_Compatible(pGrid->Get_System()) && Get_Type() == pGrid->Get_Type() );
512}
513
515{
516 return( pGrids && is_Compatible(pGrids->Get_System()) && Get_NZ() == pGrids->Get_NZ() );//&& Get_Type() == pGrids->Get_Type() );
517}
518
520{
521 return( Get_System() == System );
522}
523
524bool CSG_Grids::is_Compatible(int NX, int NY, double Cellsize, double xMin, double yMin) const
525{
526 return( is_Compatible(CSG_Grid_System(Cellsize, xMin, yMin, NX, NY)) );
527}
528
529
531// //
532// Attributes //
533// //
535
536//---------------------------------------------------------
537bool CSG_Grids::Set_Z_Attribute(int i, bool bSetNameField)
538{
539 if( i >= 0 && i < m_Attributes.Get_Field_Count() )
540 {
541 m_Z_Attribute = i;
542
543 if( bSetNameField )
544 {
545 m_Z_Name = i;
546 }
547
548 return( Update_Z_Order() );
549 }
550
551 return( false );
552}
553
554//---------------------------------------------------------
556{
557 if( i >= 0 && i < m_Attributes.Get_Field_Count() )
558 {
559 m_Z_Name = i;
560
561 return( true );
562 }
563
564 return( false );
565}
566
568{
569 return( m_Z_Name >= 0 && m_Z_Name < m_Attributes.Get_Field_Count() ? m_Z_Name : m_Z_Attribute );
570}
571
572//---------------------------------------------------------
573bool CSG_Grids::Add_Attribute(const char *Name, TSG_Data_Type Type, int Insert) { return( Add_Attribute(CSG_String(Name), Type, Insert) ); }
574bool CSG_Grids::Add_Attribute(const wchar_t *Name, TSG_Data_Type Type, int Insert) { return( Add_Attribute(CSG_String(Name), Type, Insert) ); }
575bool CSG_Grids::Add_Attribute(const CSG_String &Name, TSG_Data_Type Type, int Insert)
576{
577 return( m_Attributes.Add_Field(Name, Type, Insert) );
578}
579
580//---------------------------------------------------------
582{
583 if( i != m_Z_Attribute && m_Attributes.Get_Field_Count() > 0 && m_Attributes.Del_Field(i) )
584 {
585 if( m_Z_Attribute > i )
586 {
587 m_Z_Attribute--;
588 }
589
590 if( m_Z_Name > i )
591 {
592 m_Z_Name--;
593 }
594 else if( m_Z_Name == i )
595 {
596 m_Z_Name = -1; // same as m_Z_Attribute
597 }
598
599 return( true );
600 }
601
602 return( false );
603}
604
605//---------------------------------------------------------
606bool CSG_Grids::Set_Attribute(int i, const char *Field, const char *Value) { return( Set_Attribute(i, m_Attributes.Get_Field(Field), CSG_String(Value)) ); }
607bool CSG_Grids::Set_Attribute(int i, const wchar_t *Field, const wchar_t *Value) { return( Set_Attribute(i, m_Attributes.Get_Field(Field), CSG_String(Value)) ); }
608bool CSG_Grids::Set_Attribute(int i, const CSG_String &Field, const CSG_String &Value) { return( Set_Attribute(i, m_Attributes.Get_Field(Field), Value ) ); }
609bool CSG_Grids::Set_Attribute(int i, int Field, const CSG_String &Value)
610{
611 return( i >= 0 && i < (int)m_Attributes.Get_Count() && m_Attributes[i].Set_Value(Field, Value) );
612}
613
614//---------------------------------------------------------
615bool CSG_Grids::Set_Attribute(int i, const char *Field, double Value) { return( Set_Attribute(i, m_Attributes.Get_Field(Field), Value) ); }
616bool CSG_Grids::Set_Attribute(int i, const wchar_t *Field, double Value) { return( Set_Attribute(i, m_Attributes.Get_Field(Field), Value) ); }
617bool CSG_Grids::Set_Attribute(int i, const CSG_String &Field, double Value) { return( Set_Attribute(i, m_Attributes.Get_Field(Field), Value) ); }
618bool CSG_Grids::Set_Attribute(int i, int Field, double Value)
619{
620 return( i >= 0 && i < (int)m_Attributes.Get_Count() && m_Attributes[i].Set_Value(Field, Value) );
621}
622
623//---------------------------------------------------------
624bool CSG_Grids::Set_Z(int i, double Value)
625{
626 return( i >= 0 && i < Get_NZ() && m_Attributes[i].Set_Value(m_Z_Attribute, Value) );
627}
628
629//---------------------------------------------------------
631{
632 bool bChanged = false;
633
634 CSG_Table Attributes(m_Attributes);
635
636 if( Attributes.Set_Index(m_Z_Attribute, TABLE_INDEX_Ascending) )
637 {
638 CSG_Array_Pointer Grids; CSG_Grid **pGrids = (CSG_Grid **)Grids.Create(m_Grids);
639
640 for(int i=0; i<Get_Grid_Count(); i++)
641 {
642 int Index = (int)Attributes[i].Get_Index();
643
644 if( Index != i )
645 {
646 bChanged = true;
647
648 m_pGrids[i] = pGrids[Index];
649
650 m_Attributes[i].Assign(&Attributes[i]);
651 }
652 }
653
654 for(int i=0; i<Get_Grid_Count(); i++)
655 {
656 pGrids[i]->Set_Name(Get_Grid_Name(i));
657 }
658 }
659
660 return( bChanged );
661}
662
663
665// //
666// //
667// //
669
670//---------------------------------------------------------
672{
673 if( Count == Get_NZ() )
674 {
675 return( true );
676 }
677
678 if( Count < 0 || !Get_System().is_Valid() ) // only allowed for initialized grid systems)
679 {
680 return( false );
681 }
682
683 if( Count == 0 )
684 {
685 return( Del_Grids() );
686 }
687
688 //-----------------------------------------------------
689 SG_FREE_SAFE(m_Index); // invalidate index
690
691 if( Count < Get_NZ() )
692 {
693 for(int i=Count; i<Get_NZ(); i++)
694 {
695 delete(m_pGrids[i]);
696 }
697
698 m_pGrids = (CSG_Grid **)m_Grids.Get_Array(Count);
699
700 m_Attributes.Set_Count(Count);
701 }
702
703 //-----------------------------------------------------
704 else if( Count > Get_NZ() )
705 {
706 double z = Get_ZMax();
707
708 for(int i=Get_NZ(); i<=Count; i++, z+=Get_Cellsize())
709 {
710 if( !Add_Grid(z) )
711 {
712 return( false );
713 }
714 }
715 }
716
717 return( true );
718}
719
720
722// //
724
725//---------------------------------------------------------
727{
728 CSG_Table Attributes(&m_Attributes);
729
730 Attributes.Add_Record();
731
732 Attributes[0].Set_Value(m_Z_Attribute, Z);
733
734 return( Add_Grid(Attributes[0]) );
735}
736
737//---------------------------------------------------------
738bool CSG_Grids::Add_Grid(double Z, CSG_Grid *pGrid, bool bAttach)
739{
740 CSG_Table Attributes(&m_Attributes);
741
742 Attributes.Add_Record();
743
744 Attributes[0].Set_Value(m_Z_Attribute, Z);
745
746 return( Add_Grid(Attributes[0], pGrid, bAttach) );
747}
748
749//---------------------------------------------------------
751{
752 if( !Get_System().is_Valid() ) // only allowed for initialized grid systems
753 {
754 return( false );
755 }
756
757 //-----------------------------------------------------
758 int n = Get_NZ();
759
760 if( n < 1 ) // do some initializations
761 {
762 _Synchronize(m_pGrids[0]);
763 }
764 else // use dummy grid (m_pGrids[0] is always present)
765 {
767
768 if( !pGrid )
769 {
770 return( false );
771 }
772
773 m_pGrids = (CSG_Grid **)m_Grids.Get_Array((sLong)n + 1);
774 m_pGrids[n] = pGrid;
775
776 _Synchronize(pGrid);
777 }
778
779 //-----------------------------------------------------
780 m_Attributes.Add_Record(&Attributes);
781
782 SG_FREE_SAFE(m_Index); // invalidate index
783
785
786 return( true );
787}
788
789//---------------------------------------------------------
790bool CSG_Grids::Add_Grid(CSG_Table_Record &Attributes, CSG_Grid *pGrid, bool bAttach)
791{
792 if( !pGrid || !pGrid->is_Valid() )
793 {
794 return( false );
795 }
796
797 if( Get_NZ() > 0 && !is_Compatible(pGrid) ) // not allowed
798 {
799 return( false );
800 }
801
802 //-----------------------------------------------------
803 int n = Get_NZ();
804
805 if( n > 0 )
806 {
807 if( !bAttach && (pGrid = SG_Create_Grid(*pGrid)) == NULL ) // get a copy
808 {
809 return( false );
810 }
811
812 m_pGrids = (CSG_Grid **)m_Grids.Get_Array((sLong)n + 1);
813 m_pGrids[n] = pGrid;
814 }
815 else if( bAttach ) // if( n == 0 )
816 {
817 delete(m_pGrids[0]);
818
819 m_pGrids[0] = pGrid; // simply replace dummy
820 }
821 else if( m_pGrids[0]->Create(*pGrid) ) // make dummy a copy of grid
822 {
823 pGrid = m_pGrids[0];
824 }
825 else
826 {
827 return( false );
828 }
829
830 _Synchronize(pGrid);
831
832 //-----------------------------------------------------
833 m_Attributes.Add_Record(&Attributes);
834
835 if( !Get_Projection().is_Okay() && pGrid->Get_Projection().is_Okay() )
836 {
837 Get_Projection() = pGrid->Get_Projection();
838 }
839
840 SG_FREE_SAFE(m_Index); // invalidate index
841
843
844 return( true );
845}
846
847
849// //
851
852//---------------------------------------------------------
853bool CSG_Grids::Del_Grid(int i, bool bDetach)
854{
855 if( m_Attributes.Del_Record(i) ) // Get_NZ() is now decreased by one
856 {
857 SG_FREE_SAFE(m_Index); // invalidate index
858
859 if( Get_NZ() > 0 )
860 {
861 if( bDetach )
862 {
863 m_pGrids[i]->Set_Owner(NULL);
864 }
865 else
866 {
867 delete(m_pGrids[i]);
868 }
869
870 for( ; i<Get_NZ(); i++)
871 {
872 m_pGrids[i] = m_pGrids[i + 1];
873 }
874
875 m_pGrids = (CSG_Grid **)m_Grids.Get_Array(Get_NZ());
876 }
877 else if( bDetach ) // if( Get_NZ() == 0 )
878 {
879 m_pGrids[0]->Set_Owner(NULL);
880 m_pGrids[0] = SG_Create_Grid(*m_pGrids[0]); // needs a new dummy
881 m_pGrids[0]->Set_Owner(this);
882 }
883
884 return( true );
885 }
886
887 return( false );
888}
889
890//---------------------------------------------------------
891bool CSG_Grids::Del_Grids(bool bDetach)
892{
893 SG_FREE_SAFE(m_Index); // invalidate index
894
895 if( bDetach )
896 {
897 for(size_t i=0; i<m_Grids.Get_uSize(); i++)
898 {
899 if( m_pGrids[i]->Get_Owner() == this )
900 {
901 m_pGrids[i]->Set_Owner(NULL);
902 }
903 }
904
905 m_pGrids[0] = SG_Create_Grid(*m_pGrids[0]); // needs a new dummy
906 m_pGrids[0]->Set_Owner(this);
907 }
908 else
909 {
910 for(size_t i=1; i<m_Grids.Get_uSize(); i++)
911 {
912 delete(m_pGrids[i]); // do not delete the dummy before deconstruction
913 }
914 }
915
916 m_pGrids = (CSG_Grid **)m_Grids.Get_Array(1);
917
918 m_Attributes.Del_Records();
919
920 return( true );
921}
922
923
925// //
927
928//---------------------------------------------------------
930{
931 CSG_String s;
932
933 if( i >= 0 && i < Get_Grid_Count() )
934 {
935 if( Style == 0 )
936 {
938 }
939
940 if( (Style & SG_GRIDS_NAME_OWNER) != 0 )
941 {
942 s = CSG_String(Get_Name());
943 }
944
945 if( (Style & SG_GRIDS_NAME_INDEX) != 0 )
946 {
947 if( !s.is_Empty() ) { s += "."; }
948
949 s.Printf("%s %d", _TL("Band"), i + 1);
950 }
951
952 if( (Style & SG_GRIDS_NAME_VALUE) != 0 )
953 {
954 if( !s.is_Empty() ) { s += "."; }
955
956 s += SG_Get_String(Get_Z(i), -10);
957 }
958
959 if( (Style & SG_GRIDS_NAME_GRID ) != 0 )
960 {
961 if( !s.is_Empty() ) { s += "."; }
962
963 s += m_Attributes[i].asString(Get_Z_Name_Field());
964 }
965 }
966
967 return( s );
968}
969
970
972// //
973// //
974// //
976
977//---------------------------------------------------------
979{
980 for(int i=0; i<Get_Grid_Count(); i++)
981 {
982 m_pGrids[i]->Assign_NoData();
983 }
984}
985
986//---------------------------------------------------------
987bool CSG_Grids::Assign(double Value)
988{
989 for(int i=0; i<Get_Grid_Count(); i++)
990 {
991 m_pGrids[i]->Assign(Value);
992 }
993
994 return( true );
995}
996
997//---------------------------------------------------------
998bool CSG_Grids::Assign(CSG_Data_Object *pObject, bool bProgress)
999{
1000 if( pObject )
1001 {
1002 switch( pObject->Get_ObjectType() )
1003 {
1005 for(int i=0; i<Get_Grid_Count() && (!bProgress || SG_UI_Process_Get_Okay()); i++)
1006 {
1007 if( !m_pGrids[i]->Assign(pObject->asGrid(), bProgress) )
1008 {
1009 return( false );
1010 }
1011 }
1012
1013 return( true );
1014
1016 return( Assign(pObject->asGrids(), CSG_Grid_Resampling::Undefined, bProgress) );
1017
1018 default:
1019 break;
1020 }
1021 }
1022
1023 return( false );
1024}
1025
1026//---------------------------------------------------------
1027bool CSG_Grids::Assign(CSG_Grids *pGrids, CSG_Grid_Resampling Interpolation, bool bProgress)
1028{
1029 if( pGrids && Get_Grid_Count() == pGrids->Get_Grid_Count() )
1030 {
1031 bool bResult = true;
1032
1033 for(int i=0; i<Get_Grid_Count() && (!bProgress || SG_UI_Process_Get_Okay()); i++)
1034 {
1035 if( !m_pGrids[i]->Assign(pGrids->m_pGrids[i], Interpolation, bProgress) )
1036 {
1037 bResult = false;
1038 }
1039 }
1040
1041 return( bResult );
1042 }
1043
1044 return( false );
1045}
1046
1047
1049// //
1051
1052//---------------------------------------------------------
1054{
1055 Create(Grids); return( *this );
1056}
1057
1059{
1060 Assign(Value); return( *this );
1061}
1062
1063//---------------------------------------------------------
1065{
1066 return( Add(Value) );
1067}
1068
1070{
1071 for(int i=0; i<Get_Grid_Count(); i++)
1072 {
1073 m_pGrids[i]->Add(Value);
1074 }
1075
1076 return( *this );
1077}
1078
1079//---------------------------------------------------------
1081{
1082 return( Subtract(Value) );
1083}
1084
1086{
1087 for(int i=0; i<Get_Grid_Count(); i++)
1088 {
1089 m_pGrids[i]->Subtract(Value);
1090 }
1091
1092 return( *this );
1093}
1094
1095//---------------------------------------------------------
1097{
1098 return( Multiply(Value) );
1099}
1100
1102{
1103 for(int i=0; i<Get_Grid_Count(); i++)
1104 {
1105 m_pGrids[i]->Multiply(Value);
1106 }
1107
1108 return( *this );
1109}
1110
1111//---------------------------------------------------------
1113{
1114 return( Divide(Value) );
1115}
1116
1118{
1119 for(int i=0; i<Get_Grid_Count(); i++)
1120 {
1121 m_pGrids[i]->Divide(Value);
1122 }
1123
1124 return( *this );
1125}
1126
1127
1129// //
1130// Value access by Position (-> Interpolation) //
1131// //
1133
1134//---------------------------------------------------------
1135double CSG_Grids::Get_Value(const TSG_Point_3D &p, CSG_Grid_Resampling Resampling, CSG_Grid_Resampling ZResampling) const
1136{
1137 double Value; return( Get_Value(p.x, p.y, p.z, Value, Resampling, ZResampling) ? Value : Get_NoData_Value() );
1138}
1139
1140double CSG_Grids::Get_Value(double x, double y, double z, CSG_Grid_Resampling Resampling, CSG_Grid_Resampling ZResampling) const
1141{
1142 double Value; return( Get_Value( x, y, z, Value, Resampling, ZResampling) ? Value : Get_NoData_Value() );
1143}
1144
1145bool CSG_Grids::Get_Value(const TSG_Point_3D &p, double &Value, CSG_Grid_Resampling Resampling, CSG_Grid_Resampling ZResampling) const
1146{
1147 return( Get_Value(p.x, p.y, p.z, Value, Resampling, ZResampling) );
1148}
1149
1150//---------------------------------------------------------
1151bool CSG_Grids::Get_Value(double x, double y, double z, double &Value, CSG_Grid_Resampling Resampling, CSG_Grid_Resampling ZResampling) const
1152{
1153 if( !Get_System().Get_Extent(true).Contains(x, y) )
1154 {
1155 return( false );
1156 }
1157
1158 int iz; double dz;
1159
1160 if( !_Get_Z(z, iz, dz) )
1161 {
1162 return( false );
1163 }
1164
1165 if( dz == 0. )
1166 {
1167 return( m_pGrids[iz]->Get_Value(x, y, Value, Resampling) );
1168 }
1169
1170 if( ZResampling == CSG_Grid_Resampling::Undefined )
1171 {
1172 ZResampling = Resampling;
1173 }
1174
1175 if( (ZResampling == CSG_Grid_Resampling::Bicubic_1 || ZResampling == CSG_Grid_Resampling::Bicubic_2)
1176 && (iz < 1 || iz >= m_Attributes.Get_Count() - 2) )
1177 {
1178 ZResampling = CSG_Grid_Resampling::Bilinear;
1179 }
1180
1181 switch( ZResampling )
1182 {
1184 return( m_pGrids[dz < 0.5 ? iz : iz + 1]->Get_Value(x, y, Value, Resampling) );
1185
1187 {
1188 double v[2];
1189
1190 if( m_pGrids[iz ]->Get_Value(x, y, v[0], Resampling)
1191 && m_pGrids[iz + 1]->Get_Value(x, y, v[1], Resampling) )
1192 {
1193 Value = v[0] + dz * (v[1] - v[0]);
1194
1195 return( true );
1196 }
1197
1198 return( false );
1199 }
1200
1203 {
1204 CSG_Spline s;
1205
1206 #define ADD_TO_SPLINE(i) if( i < 0 || i >= Get_NZ() || !m_pGrids[i]->Get_Value(x, y, Value, Resampling) ) { return( false ); } s.Add(Get_Z(i), Value);
1207
1208 ADD_TO_SPLINE(iz - 1);
1209 ADD_TO_SPLINE(iz );
1210 ADD_TO_SPLINE(iz + 1);
1211 ADD_TO_SPLINE(iz + 2);
1212
1213 return( s.Get_Value(z, Value) );
1214 }
1215 break;
1216 }
1217
1218 return( false );
1219}
1220
1221//---------------------------------------------------------
1222bool CSG_Grids::_Get_Z(double z, int &iz, double &dz) const
1223{
1224 if( z < m_Attributes[0 ].asDouble(m_Z_Attribute)
1225 || z > m_Attributes[m_Attributes.Get_Count() - 1].asDouble(m_Z_Attribute) )
1226 {
1227 return( false );
1228 }
1229
1230 double z0, z1 = m_Attributes[0].asDouble(m_Z_Attribute);
1231
1232 for(iz=0; iz<m_Attributes.Get_Count()-1; iz++)
1233 {
1234 z0 = z1; z1 = m_Attributes[((sLong)iz) + 1].asDouble(m_Z_Attribute);
1235
1236 if( z < z1 )
1237 {
1238 dz = z0 < z1 ? (z - z0) / (z1 - z0) : 0.;
1239
1240 return( true );
1241 }
1242 }
1243
1244 return( (dz = z - z1) == 0. );
1245}
1246
1247
1249// //
1250// Index //
1251// //
1253
1254//---------------------------------------------------------
1255#define SORT_SWAP(a,b) {itemp=(a);(a)=(b);(b)=itemp;}
1256
1257bool CSG_Grids::_Set_Index(void)
1258{
1259 //-----------------------------------------------------
1260 if( m_Index == NULL && (m_Index = (sLong *)SG_Malloc((size_t)Get_NCells() * sizeof(sLong))) == NULL )
1261 {
1262 SG_UI_Msg_Add_Error(_TL("could not create index: insufficient memory"));
1263
1264 return( false );
1265 }
1266
1267 //-----------------------------------------------------
1268 const sLong M = 7;
1269
1270 sLong i, j, k, l, ir, n, *istack, jstack, nstack, indxt, itemp, nData;
1271 double a;
1272
1273 //-----------------------------------------------------
1274 SG_UI_Process_Set_Text(CSG_String::Format("%s: %s", _TL("Create index"), Get_Name()));
1275
1276 for(i=0, j=0, nData=Get_NCells(); i<Get_NCells(); i++)
1277 {
1278 if( is_NoData(i) )
1279 {
1280 m_Index[--nData] = i;
1281 }
1282 else // if( !is_NoData(i) )
1283 {
1284 m_Index[j++] = i;
1285 }
1286 }
1287
1288 //-----------------------------------------------------
1289 l = 0;
1290 n = 0;
1291 ir = nData - 1;
1292
1293 nstack = 64;
1294 istack = (sLong *)SG_Malloc((size_t)nstack * sizeof(sLong));
1295 jstack = 0;
1296
1297 for(;;)
1298 {
1299 if( ir - l < M )
1300 {
1301 if( !SG_UI_Process_Set_Progress((double)(n += M - 1), (double)nData) )
1302 {
1303 SG_FREE_SAFE(istack);
1304 SG_FREE_SAFE(m_Index);
1305
1306 SG_UI_Msg_Add_Error(_TL("index creation stopped by user"));
1308
1309 return( false );
1310 }
1311
1312 for(j=l+1; j<=ir; j++)
1313 {
1314 indxt = m_Index[j];
1315 a = asDouble(indxt);
1316
1317 for(i=j-1; i>=0; i--)
1318 {
1319 if( asDouble(m_Index[i]) <= a )
1320 {
1321 break;
1322 }
1323
1324 m_Index[i + 1] = m_Index[i];
1325 }
1326
1327 m_Index[i + 1] = indxt;
1328 }
1329
1330 if( jstack == 0 )
1331 {
1332 break;
1333 }
1334
1335 ir = istack[jstack--];
1336 l = istack[jstack--];
1337 }
1338
1339 //-------------------------------------------------
1340 else
1341 {
1342 k = (l + ir) >> 1;
1343
1344 SORT_SWAP(m_Index[k], m_Index[l + 1]);
1345
1346 if( asDouble( m_Index[l + 1]) > asDouble(m_Index[ir]) )
1347 SORT_SWAP(m_Index[l + 1], m_Index[ir]);
1348
1349 if( asDouble( m_Index[l ]) > asDouble(m_Index[ir]) )
1350 SORT_SWAP(m_Index[l ], m_Index[ir]);
1351
1352 if( asDouble( m_Index[l + 1]) > asDouble(m_Index[l ]) )
1353 SORT_SWAP(m_Index[l + 1], m_Index[l ]);
1354
1355 i = l + 1;
1356 j = ir;
1357 indxt = m_Index[l];
1358 a = asDouble(indxt);
1359
1360 for(;;)
1361 {
1362 do i++; while(asDouble(m_Index[i]) < a);
1363 do j--; while(asDouble(m_Index[j]) > a);
1364
1365 if( j < i )
1366 {
1367 break;
1368 }
1369
1370 SORT_SWAP(m_Index[i], m_Index[j]);
1371 }
1372
1373 m_Index[l] = m_Index[j];
1374 m_Index[j] = indxt;
1375 jstack += 2;
1376
1377 if( jstack >= nstack )
1378 {
1379 nstack += 64;
1380 istack = (sLong *)SG_Realloc(istack, (size_t)nstack * sizeof(int));
1381 }
1382
1383 if( ir - i + 1 >= j - l )
1384 {
1385 istack[jstack] = ir;
1386 istack[jstack - 1] = i;
1387 ir = j - 1;
1388 }
1389 else
1390 {
1391 istack[jstack] = j - 1;
1392 istack[jstack - 1] = l;
1393 l = i;
1394 }
1395 }
1396 }
1397
1398 //-----------------------------------------------------
1399 SG_Free(istack);
1400
1402
1403 return( true );
1404}
1405#undef SORT_SWAP
1406
1407
1409// //
1410// Statistics //
1411// //
1413
1414//---------------------------------------------------------
1416{
1417 if( is_Valid() )
1418 {
1419 SG_FREE_SAFE(m_Index);
1420
1421 m_Statistics.Invalidate();
1422 m_Histogram.Destroy();
1423
1424 double Offset = Get_Offset(), Scaling = is_Scaled() ? Get_Scaling() : 0.;
1425
1426 if( Get_Max_Samples() > 0 && Get_Max_Samples() < Get_NCells() )
1427 {
1428 double d = (double)Get_NCells() / (double)Get_Max_Samples();
1429
1430 for(double i=0; i<(double)Get_NCells(); i+=d)
1431 {
1432 double Value = asDouble((sLong)i, false);
1433
1434 if( !is_NoData_Value(Value) )
1435 {
1436 m_Statistics += Scaling ? Offset + Scaling * Value : Value;
1437 }
1438 }
1439
1440 m_Statistics.Set_Count(m_Statistics.Get_Count() >= Get_Max_Samples() ? Get_NCells() // any no-data cells ?
1441 : (sLong)(Get_NCells() * (double)m_Statistics.Get_Count() / (double)Get_Max_Samples())
1442 );
1443 }
1444 else
1445 {
1446 for(sLong i=0; i<Get_NCells(); i++)
1447 {
1448 double Value = asDouble(i, false);
1449
1450 if( !is_NoData_Value(Value) )
1451 {
1452 m_Statistics += Scaling ? Offset + Scaling * Value : Value;
1453 }
1454 }
1455 }
1456 }
1457
1458 return( true );
1459}
1460
1461//---------------------------------------------------------
1463{
1464 Update(); return( m_Statistics.Get_Mean() );
1465}
1466
1468{
1469 Update(); return( m_Statistics.Get_Minimum() );
1470}
1471
1473{
1474 Update(); return( m_Statistics.Get_Maximum() );
1475}
1476
1478{
1479 Update(); return( m_Statistics.Get_Range() );
1480}
1481
1483{
1484 Update(); return( m_Statistics.Get_StdDev() );
1485}
1486
1488{
1489 Update(); return( m_Statistics.Get_Variance() );
1490}
1491
1492//---------------------------------------------------------
1494{
1495 Update(); return( m_Statistics.Get_Count() );
1496}
1497
1499{
1500 Update(); return( Get_NCells() - m_Statistics.Get_Count() );
1501}
1502
1503//---------------------------------------------------------
1504double CSG_Grids::Get_Quantile(double Quantile, bool bFromHistogram)
1505{
1506 if( Quantile <= 0. ) { return( Get_Min() ); }
1507 if( Quantile >= 1. ) { return( Get_Max() ); }
1508
1509 if( bFromHistogram )
1510 {
1511 return( Get_Histogram().Get_Quantile(Quantile) );
1512 }
1513 else
1514 {
1515 sLong n = (sLong)(Quantile * (Get_Data_Count() - 1));
1516
1517 if( Get_Sorted(n, n, false) )
1518 {
1519 return( asDouble(n) );
1520 }
1521 }
1522
1523 return( Get_NoData_Value() );
1524}
1525
1526//---------------------------------------------------------
1527double CSG_Grids::Get_Percentile(double Percentile, bool bFromHistogram)
1528{
1529 return( Get_Quantile(0.01 * Percentile, bFromHistogram) );
1530}
1531
1532
1534// //
1536
1537//---------------------------------------------------------
1545{
1546 Update(); return( m_Statistics );
1547}
1548
1549//---------------------------------------------------------
1555//---------------------------------------------------------
1556bool CSG_Grids::Get_Statistics(const CSG_Rect &rWorld, CSG_Simple_Statistics &Statistics, bool bHoldValues) const
1557{
1558 int xMin = Get_System().Get_xWorld_to_Grid(rWorld.Get_XMin()); if( xMin < 0 ) { xMin = 0; }
1559 int yMin = Get_System().Get_yWorld_to_Grid(rWorld.Get_YMin()); if( yMin < 0 ) { yMin = 0; }
1560 int xMax = Get_System().Get_xWorld_to_Grid(rWorld.Get_XMax()); if( xMax >= Get_NX() ) { xMax = Get_NX() - 1; }
1561 int yMax = Get_System().Get_yWorld_to_Grid(rWorld.Get_YMax()); if( yMax >= Get_NY() ) { yMax = Get_NY() - 1; }
1562
1563 if( xMin > xMax || yMin > yMax )
1564 {
1565 return( false ); // no overlap
1566 }
1567
1568 Statistics.Create(bHoldValues);
1569
1570 int nx = 1 + (xMax - xMin);
1571 int ny = 1 + (yMax - yMin);
1572 sLong nCells = (sLong)nx * (sLong)ny;
1573
1574 double Offset = Get_Offset(), Scaling = is_Scaled() ? Get_Scaling() : 0.;
1575
1576 if( Get_Max_Samples() > 0 && Get_Max_Samples() < nCells )
1577 {
1578 double d = (double)nCells / (double)Get_Max_Samples();
1579
1580 for(double i=0; i<(double)nCells; i+=d)
1581 {
1582 int y = yMin + (int)i / nx;
1583 int x = xMin + (int)i % nx;
1584
1585 for(int z=0; z<Get_NZ(); z++)
1586 {
1587 double Value = asDouble(x, y, z, false);
1588
1589 if( !is_NoData_Value(Value) )
1590 {
1591 Statistics += Scaling ? Offset + Scaling * Value : Value;
1592 }
1593 }
1594 }
1595 }
1596 else
1597 {
1598 for(int x=xMin; x<=xMax; x++)
1599 {
1600 for(int y=yMin; y<=yMax; y++)
1601 {
1602 for(int z=0; z<Get_NZ(); z++)
1603 {
1604 double Value = asDouble(x, y, z, false);
1605
1606 if( !is_NoData_Value(Value) )
1607 {
1608 Statistics += Scaling ? Offset + Scaling * Value : Value;
1609 }
1610 }
1611 }
1612 }
1613 }
1614
1615 return( Statistics.Get_Count() > 0 );
1616}
1617
1618//---------------------------------------------------------
1620{
1621 if( CSG_Data_Object::Set_Max_Samples(Max_Samples) && Get_Grid_Count() > 0 )
1622 {
1623 Max_Samples /= Get_Grid_Count();
1624
1625 for(int i=0; i<Get_Grid_Count(); i++)
1626 {
1627 Get_Grid_Ptr(i)->Set_Max_Samples(Max_Samples);
1628 }
1629
1630 return( true );
1631 }
1632
1633 return( false );
1634}
1635
1636//---------------------------------------------------------
1637#define SG_GRID_HISTOGRAM_CLASSES_DEFAULT 255
1638
1639//---------------------------------------------------------
1645{
1646 Update();
1647
1648 if( nClasses > 1 && nClasses != m_Histogram.Get_Class_Count() )
1649 {
1650 m_Histogram.Destroy();
1651 }
1652
1653 if( m_Histogram.Get_Statistics().Get_Count() < 1 )
1654 {
1655 m_Histogram.Create(nClasses > 1 ? nClasses : SG_GRID_HISTOGRAM_CLASSES_DEFAULT, this, 0., 0., (size_t)Get_Max_Samples());
1656 }
1657
1658 return( m_Histogram );
1659}
1660
1661//---------------------------------------------------------
1662bool CSG_Grids::Get_Histogram(const CSG_Rect &rWorld, CSG_Histogram &Histogram, size_t nClasses) const
1663{
1664 CSG_Simple_Statistics Statistics;
1665
1666 if( !Get_Statistics(rWorld, Statistics) )
1667 {
1668 return( false );
1669 }
1670
1671 int xMin = Get_System().Get_xWorld_to_Grid(rWorld.Get_XMin()); if( xMin < 0 ) { xMin = 0; }
1672 int yMin = Get_System().Get_yWorld_to_Grid(rWorld.Get_YMin()); if( yMin < 0 ) { yMin = 0; }
1673 int xMax = Get_System().Get_xWorld_to_Grid(rWorld.Get_XMax()); if( xMax >= Get_NX() ) { xMax = Get_NX() - 1; }
1674 int yMax = Get_System().Get_yWorld_to_Grid(rWorld.Get_YMax()); if( yMax >= Get_NY() ) { yMax = Get_NY() - 1; }
1675
1676 if( xMin > xMax || yMin > yMax )
1677 {
1678 return( false ); // no overlap
1679 }
1680
1681 Histogram.Create(nClasses > 1 ? nClasses : SG_GRID_HISTOGRAM_CLASSES_DEFAULT, Statistics.Get_Minimum(), Statistics.Get_Maximum());
1682
1683 int nx = 1 + (xMax - xMin);
1684 int ny = 1 + (yMax - yMin);
1685 sLong nCells = (sLong)nx * (sLong)ny;
1686
1687 double Offset = Get_Offset(), Scaling = is_Scaled() ? Get_Scaling() : 0.;
1688
1689 if( Get_Max_Samples() > 0 && Get_Max_Samples() < nCells )
1690 {
1691 double d = (double)nCells / (double)Get_Max_Samples();
1692
1693 for(double i=0; i<(double)nCells; i+=d)
1694 {
1695 int y = yMin + (int)i / nx;
1696 int x = xMin + (int)i % nx;
1697
1698 for(int z=0; z<Get_NZ(); z++)
1699 {
1700 double Value = asDouble(x, y, z, false);
1701
1702 if( !is_NoData_Value(Value) )
1703 {
1704 Histogram += Scaling ? Offset + Scaling * Value : Value;
1705 }
1706 }
1707 }
1708 }
1709 else
1710 {
1711 for(int x=xMin; x<=xMax; x++) for(int y=yMin; y<=yMax; y++) for(int z=0; z<Get_NZ(); z++)
1712 {
1713 double Value = asDouble(x, y, z, false);
1714
1715 if( !is_NoData_Value(Value) )
1716 {
1717 Histogram += Scaling ? Offset + Scaling * Value : Value;
1718 }
1719 }
1720 }
1721
1722 return( Histogram.Update() );
1723}
1724
1725
1727// //
1728// //
1729// //
1731
1732//---------------------------------------------------------
1734{
1735 return( Create(Get_File_Name(false)) );
1736}
1737
1738//---------------------------------------------------------
1740{
1741 CSG_String File = Get_File_Name(true);
1742
1743 SG_File_Set_Extension(File, "sg-gds-z"); SG_File_Delete(File);
1744 SG_File_Set_Extension(File, "sg-gds" ); SG_File_Delete(File);
1745 SG_File_Set_Extension(File, "sg-info" ); SG_File_Delete(File);
1746 SG_File_Set_Extension(File, "sg-prj" ); SG_File_Delete(File);
1747
1748 int i = 0;
1749
1750 do
1751 {
1752 SG_File_Set_Extension(File, CSG_String::Format("sg-%03d", ++i));
1753 }
1754 while( SG_File_Delete(File) );
1755
1756 return( true );
1757}
1758
1759
1761// //
1763
1764//---------------------------------------------------------
1765bool CSG_Grids::Load(const CSG_String &File, bool bLoadData)
1766{
1767 Destroy();
1768
1769 SG_UI_Msg_Add(CSG_String::Format("%s: %s...", _TL("Loading grid collection"), File.c_str()), true);
1770
1771 if( _Load_PGSQL (File)
1772 || _Load_Normal (File)
1773 || _Load_Compressed(File)
1774 || _Load_External (File) )
1775 {
1776 Set_Modified(false);
1777
1779 SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
1780
1781 return( true );
1782 }
1783
1785 SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
1786
1787 return( false );
1788}
1789
1790//---------------------------------------------------------
1791bool CSG_Grids::Save(const CSG_String &File, int Format)
1792{
1793 if( File.is_Empty() )
1794 {
1795 return( *Get_File_Name(false) ? Save(Get_File_Name(false), Format) : false );
1796 }
1797
1798 SG_UI_Msg_Add(CSG_String::Format("%s %s: %s...", _TL("Saving"), _TL("grid collection"), File.c_str()), true);
1799
1800 if( Format == GRIDS_FILE_FORMAT_Undefined )
1801 {
1802 Format = GRIDS_FILE_FORMAT_Compressed; // default
1803
1804 if( SG_File_Cmp_Extension(File, "sg-gds" ) ) Format = GRIDS_FILE_FORMAT_Normal ;
1805 if( SG_File_Cmp_Extension(File, "sg-gds-z") ) Format = GRIDS_FILE_FORMAT_Compressed;
1806 if( SG_File_Cmp_Extension(File, "tif" ) ) Format = GRIDS_FILE_FORMAT_GeoTIFF ;
1807 }
1808
1809 bool bResult = false;
1810
1811 switch( Format )
1812 {
1814 bResult = _Save_Normal (File);
1815 break;
1816
1817 case GRIDS_FILE_FORMAT_Compressed: default:
1818 bResult = _Save_Compressed(File);
1819 break;
1820
1822 SG_RUN_TOOL(bResult, "io_gdal", 2, // Export GeoTIFF
1823 SG_TOOL_PARAMLIST_ADD("GRIDS", this)
1824 && SG_TOOL_PARAMETER_SET("FILE" , File)
1825 );
1826 break;
1827 }
1828
1829 //-----------------------------------------------------
1831
1832 if( bResult )
1833 {
1834 Set_Modified(false);
1835
1836 Set_File_Name(File, true);
1837
1838 SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
1839
1840 return( true );
1841 }
1842
1843 SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
1844
1845 return( false );
1846}
1847
1848
1850// //
1852
1853//---------------------------------------------------------
1854bool CSG_Grids::_Load_External(const CSG_String &File)
1855{
1856 bool bResult = false; CSG_Data_Manager Manager;
1857
1858 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("io_gdal", 0); // import raster
1859
1860 SG_UI_Msg_Lock(true);
1861
1862 if( pTool && pTool->On_Before_Execution() && pTool->Settings_Push(&Manager)
1863 && pTool->Set_Parameter("FILES" , File)
1864 && pTool->Set_Parameter("MULTIPLE", 1 ) // output as grid collection
1865 && pTool->Execute()
1866 && Manager.Grids().Count() && Manager.Grids(0).is_Valid() )
1867 {
1868 CSG_Grids *pGrids = Manager.Grids(0).asGrids();
1869
1870 m_Attributes.Create(&pGrids->m_Attributes);
1871
1872 for(int i=0; i<pGrids->Get_Grid_Count(); i++)
1873 {
1874 Add_Grid(pGrids->Get_Attributes(i), pGrids->Get_Grid_Ptr(i), true);
1875 }
1876
1877 Set_File_Name(File, false);
1878
1879 Set_Name (pGrids->Get_Name ());
1880 Set_Description (pGrids->Get_Description ());
1881 Set_Z_Attribute (pGrids->Get_Z_Attribute ());
1883
1884 pGrids->Del_Grids(true);
1885
1886 bResult = true;
1887 }
1888
1889 SG_UI_Msg_Lock(false);
1890
1892
1893 return( bResult );
1894}
1895
1896//---------------------------------------------------------
1897bool CSG_Grids::_Load_PGSQL(const CSG_String &File)
1898{
1899 bool bResult = false;
1900
1901 if( File.BeforeFirst(':').Cmp("PGSQL") == 0 ) // database source
1902 {
1903 CSG_String s(File);
1904
1905 s = s.AfterFirst(':'); CSG_String Host (s.BeforeFirst(':'));
1906 s = s.AfterFirst(':'); CSG_String Port (s.BeforeFirst(':'));
1907 s = s.AfterFirst(':'); CSG_String DBase(s.BeforeFirst(':'));
1908 s = s.AfterFirst(':'); CSG_String Table(s.BeforeFirst(':'));
1909 s = s.AfterFirst(':'); CSG_String rid (s.BeforeFirst(':').AfterFirst('='));
1910
1911 //-------------------------------------------------
1912 CSG_Strings rids(SG_String_Tokenize(rid, ",")); rid.Clear();
1913
1914 for(int i=0; i<rids.Get_Count(); i++)
1915 {
1916 if( !rid.is_Empty() )
1917 {
1918 rid += " OR ";
1919 }
1920
1921 rid += "rid=\'" + rids[i] + "\'";
1922 }
1923
1924 //-------------------------------------------------
1925 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("db_pgsql", 30); // CPGIS_Raster_Load
1926
1927 if( pTool )
1928 {
1930
1931 CSG_String Connection(DBase + " [" + Host + ":" + Port + "]"); CSG_Data_Manager Manager;
1932
1933 bResult = pTool->Settings_Push(&Manager) && pTool->On_Before_Execution()
1934 && pTool->Set_Parameter("CONNECTION", Connection)
1935 && pTool->Set_Parameter("DB_TABLE" , Table )
1936 && pTool->Set_Parameter("WHERE" , rid )
1937 && pTool->Set_Parameter("MULTIPLE" , 1 ) // grid collection
1938 && pTool->Execute();
1939
1941
1942 //-----------------------------------------
1943 if( Manager.Grids().Count() && Manager.Grids(0).is_Valid() )
1944 {
1945 CSG_Grids *pGrids = Manager.Grids(0).asGrids();
1946
1947 Set_File_Name(File);
1948
1949 Set_Name(SG_File_Get_Name(File, false));
1950
1951 Create(pGrids);
1952
1953 for(int i=0; i<pGrids->Get_Grid_Count(); i++)
1954 {
1955 Add_Grid(pGrids->Get_Attributes(i), pGrids->Get_Grid_Ptr(i), true);
1956 }
1957
1958 pGrids->Del_Grids(true);
1959
1960 bResult = Get_NZ() > 0;
1961 }
1962
1964 }
1965 }
1966
1967 return( bResult );
1968}
1969
1970
1972// //
1974
1975//---------------------------------------------------------
1976bool CSG_Grids::_Load_Normal(const CSG_String &_File)
1977{
1978 Set_File_Name(_File, true);
1979
1980 if( !SG_File_Cmp_Extension(_File, "sg-gds") ) // GRIDS_FILETYPE_Normal
1981 {
1982 return( false );
1983 }
1984
1985 CSG_String File(_File); CSG_File Stream;
1986
1987 //-----------------------------------------------------
1988 if( !Stream.Open(File, SG_FILE_R, false) || !_Load_Header(Stream) )
1989 {
1990 return( false );
1991 }
1992
1993 SG_File_Set_Extension(File, "sg-att");
1994
1995 if( m_Attributes.Get_Count() <= 0 ) // <<< DEPRECATED
1996 if( !Stream.Open(File, SG_FILE_R, false) || !_Load_Attributes(Stream) )
1997 {
1998 return( false );
1999 }
2000
2001 //-----------------------------------------------------
2002 for(int i=0; i<Get_NZ() && SG_UI_Process_Set_Progress(i, Get_NZ()); i++)
2003 {
2004 SG_File_Set_Extension(File, CSG_String::Format("sg-%03d", i + 1));
2005
2006 if( !Stream.Open(File, SG_FILE_R, true) || !_Load_Data(Stream, m_pGrids[i]) )
2007 {
2008 return( false );
2009 }
2010 }
2011
2012 //-----------------------------------------------------
2013 Load_MetaData(File);
2014
2015 Get_Projection().Load(SG_File_Make_Path("", File, "sg-prj"));
2016
2017 return( true );
2018}
2019
2020//---------------------------------------------------------
2021bool CSG_Grids::_Save_Normal(const CSG_String &_File)
2022{
2023 CSG_String File(_File); CSG_File Stream;
2024
2025 //-----------------------------------------------------
2026 SG_File_Set_Extension(File, "sg-gds");
2027
2028 if( !Stream.Open(File, SG_FILE_W, false) || !_Save_Header(Stream) )
2029 {
2030 return( false );
2031 }
2032
2033 SG_File_Set_Extension(File, "sg-att");
2034
2035 if( !Stream.Open(File, SG_FILE_W, false) || !_Save_Attributes(Stream) )
2036 {
2037 return( false );
2038 }
2039
2040 //-----------------------------------------------------
2041 for(int i=0; i<Get_NZ() && SG_UI_Process_Set_Progress(i, Get_NZ()); i++)
2042 {
2043 SG_File_Set_Extension(File, CSG_String::Format("sg-%03d", i + 1));
2044
2045 if( !Stream.Open(File, SG_FILE_W, true) || !_Save_Data(Stream, m_pGrids[i]) )
2046 {
2047 return( false );
2048 }
2049 }
2050
2051 //-----------------------------------------------------
2052 Save_MetaData(File);
2053
2054 Get_Projection().Save(SG_File_Make_Path("", File, "sg-prj"));
2055
2056 return( true );
2057}
2058
2059
2061// //
2063
2064//---------------------------------------------------------
2065bool CSG_Grids::_Load_Compressed(const CSG_String &_File)
2066{
2067 Set_File_Name(_File, true);
2068
2069 if( !SG_File_Cmp_Extension(_File, "sg-gds-z") ) // GRIDS_FILETYPE_Compressed
2070 {
2071 return( false );
2072 }
2073
2074 CSG_Archive Stream(_File, SG_FILE_R);
2075
2076 //-----------------------------------------------------
2077 CSG_String File(SG_File_Get_Name(_File, false) + ".");
2078
2079 if( !Stream.Get_File(File + "sg-gds") )
2080 {
2081 File.Clear();
2082
2083 for(size_t i=0; File.is_Empty() && i<Stream.Get_File_Count(); i++)
2084 {
2085 if( SG_File_Cmp_Extension(Stream.Get_File_Name(i), "sg-gds") )
2086 {
2087 File = SG_File_Get_Name(Stream.Get_File_Name(i), false) + ".";
2088 }
2089 }
2090 }
2091
2092 //-----------------------------------------------------
2093 if( !Stream.Get_File(File + "sg-gds") || !_Load_Header(Stream) )
2094 {
2095 return( false );
2096 }
2097
2098 if( m_Attributes.Get_Count() <= 0 ) // <<< DEPRECATED
2099 if( !Stream.Get_File(File + "sg-att") || !_Load_Attributes(Stream) )
2100 {
2101 return( false );
2102 }
2103
2104 //-----------------------------------------------------
2105 for(int i=0; i<Get_NZ() && SG_UI_Process_Set_Progress(i, Get_NZ()); i++)
2106 {
2107 if( !Stream.Get_File(File + CSG_String::Format("sg-%03d", i + 1)) || !_Load_Data(Stream, m_pGrids[i]) )
2108 {
2109 return( false );
2110 }
2111 }
2112
2113 //-----------------------------------------------------
2114 if( Stream.Get_File(File + "sg-info") )
2115 {
2116 Load_MetaData(Stream);
2117 }
2118
2119 if( Stream.Get_File(File + "sg-prj") )
2120 {
2121 Get_Projection().Load(Stream);
2122 }
2123
2124 return( true );
2125}
2126
2127//---------------------------------------------------------
2128bool CSG_Grids::_Save_Compressed(const CSG_String &_File)
2129{
2130 CSG_Archive Stream(_File, SG_FILE_W);
2131
2132 CSG_String File(SG_File_Get_Name(_File, false) + ".");
2133
2134 //-----------------------------------------------------
2135 if( !Stream.Add_File(File + "sg-gds") || !_Save_Header(Stream) )
2136 {
2137 return( false );
2138 }
2139
2140 if( !Stream.Add_File(File + "sg-att") || !_Save_Attributes(Stream) )
2141 {
2142 return( false );
2143 }
2144
2145 //-----------------------------------------------------
2146 for(int i=0; i<Get_NZ() && SG_UI_Process_Set_Progress(i, Get_NZ()); i++)
2147 {
2148 if( !Stream.Add_File(File + CSG_String::Format("sg-%03d", i + 1)) || !_Save_Data(Stream, m_pGrids[i]) )
2149 {
2150 return( false );
2151 }
2152 }
2153
2154 //-----------------------------------------------------
2155 if( Stream.Add_File(File + "sg-info") )
2156 {
2157 Save_MetaData(Stream);
2158 }
2159
2160 if( Stream.Add_File(File + "sg-prj") )
2161 {
2162 Get_Projection().Save(Stream);
2163 }
2164
2165 return( true );
2166}
2167
2168
2170// //
2172
2173//---------------------------------------------------------
2174bool CSG_Grids::_Load_Header(CSG_File &Stream)
2175{
2176 CSG_MetaData Header;
2177
2178 if( !Header.Load(Stream) )
2179 {
2180 return( false );
2181 }
2182
2183 //-----------------------------------------------------
2184 if( !Header("NX") || !Header("NY") || !Header("XMIN") || !Header("YMIN") || !Header("CELLSIZE") || !Header("TYPE") ) // necessary minimum information !!!
2185 {
2186 return( false );
2187 }
2188
2189 CSG_Grid_System System(Header["CELLSIZE"].Get_Content().asDouble(),
2190 Header["XMIN"].Get_Content().asDouble(), Header["YMIN"].Get_Content().asDouble(),
2191 Header["NX" ].Get_Content().asInt (), Header["NY" ].Get_Content().asInt ()
2192 );
2193
2194 TSG_Data_Type Type = SG_Data_Type_Get_Type(Header["TYPE"].Get_Content());
2195
2196 if( !System.is_Valid() || Type == SG_DATATYPE_Undefined || !m_pGrids[0]->Create(System, Type) )
2197 {
2198 return( false );
2199 }
2200
2201 //-----------------------------------------------------
2202 if( Header("NAME" ) ) { Set_Name (Header["NAME" ].Get_Content()); } else { Set_Name(SG_File_Get_Name(Stream.Get_File_Name(), false)); }
2203 if( Header("DESCRIPTION") ) { Set_Description(Header["DESCRIPTION"].Get_Content()); }
2204 if( Header("UNIT" ) ) { Set_Unit (Header["UNIT" ].Get_Content()); }
2205
2207 Header("SCALE" ) ? Header["SCALE" ].Get_Content().asDouble() : 1.,
2208 Header("OFFSET") ? Header["OFFSET"].Get_Content().asDouble() : 0.
2209 );
2210
2211 if( Header("NODATA_MIN") )
2212 {
2213 if( Header("NODATA_MAX") )
2214 {
2216 Header["NODATA_MIN"].Get_Content().asDouble(),
2217 Header["NODATA_MAX"].Get_Content().asDouble()
2218 );
2219 }
2220 else
2221 {
2223 Header["NODATA_MIN"].Get_Content().asDouble()
2224 );
2225 }
2226 }
2227
2228 //-----------------------------------------------------
2229 m_Attributes.Destroy();
2230
2231 if( Header("ATTRIBUTES") && Header["ATTRIBUTES"]("FIELDS") == NULL )
2232 {
2233 const CSG_MetaData &Fields = Header["ATTRIBUTES"];
2234
2235 for(int iField=0; iField<Fields.Get_Children_Count(); iField++)
2236 {
2237 if( Fields[iField].Cmp_Name("FIELD") && Fields[iField].Get_Property("TYPE") )
2238 {
2239 m_Attributes.Add_Field(Fields[iField].Get_Content(), SG_Data_Type_Get_Type(Fields[iField].Get_Property("TYPE")));
2240 }
2241 }
2242
2243 if( !Fields.Get_Property("Z_FIELD", m_Z_Attribute) || m_Z_Attribute >= m_Attributes.Get_Field_Count() )
2244 {
2245 m_Z_Attribute = 0;
2246 }
2247
2248 if( !Fields.Get_Property("Z_NAME", m_Z_Name ) || m_Z_Name >= m_Attributes.Get_Field_Count() )
2249 {
2250 m_Z_Name = -1; // same as m_Z_Attribute
2251 }
2252 }
2253
2254 //-----------------------------------------------------
2255 // >>> DEPRECATED >>> //
2256 if( Header("ATTRIBUTES") && Header["ATTRIBUTES"]("FIELDS") != NULL )
2257 {
2258 if( !Header["ATTRIBUTES"].Get_Property("ZATTRIBUTE", m_Z_Attribute) )
2259 {
2260 m_Z_Attribute = 0;
2261 }
2262
2263 const CSG_MetaData &Fields = Header["ATTRIBUTES"]["FIELDS"];
2264
2265 for(int iField=0; iField<Fields.Get_Children_Count(); iField++)
2266 {
2267 if( Fields[iField].Cmp_Name("FIELD") && Fields[iField].Get_Property("TYPE") )
2268 {
2269 m_Attributes.Add_Field(Fields[iField].Get_Content(), SG_Data_Type_Get_Type(Fields[iField].Get_Property("TYPE")));
2270 }
2271 }
2272
2273 if( m_Attributes.Get_Field_Count() > 0 && Header["ATTRIBUTES"]("RECORDS") )
2274 {
2275 CSG_Table Attributes(m_Attributes);
2276
2277 const CSG_MetaData &Records = Header["ATTRIBUTES"]["RECORDS"];
2278
2279 for(int iRecord=0; iRecord<Records.Get_Children_Count(); iRecord++)
2280 {
2281 if( Records[iRecord].Cmp_Name("RECORD") )
2282 {
2283 CSG_String_Tokenizer Values(Records[iRecord].Get_Content(), ";");
2284
2285 if( Values.Get_Tokens_Count() == (size_t)Attributes.Get_Field_Count() )
2286 {
2287 CSG_Table_Record *pRecord = Attributes.Add_Record();
2288
2289 for(int iField=0; iField<m_Attributes.Get_Field_Count(); iField++)
2290 {
2291 pRecord->Set_Value(iField, Values.Get_Next_Token());
2292 }
2293
2294 if( !Add_Grid(*pRecord) )
2295 {
2296 return( false );
2297 }
2298 }
2299 }
2300 }
2301 }
2302 }
2303 else if( Header("NZ") && Header["NZ"].Get_Content().asInt() > 0 )
2304 {
2305 m_Attributes.Add_Field("ID", SG_DATATYPE_Int);
2306
2307 for(int i=0, n=Header["NZ"].Get_Content().asInt(); i<n; i++)
2308 {
2309 if( !Add_Grid(i + 1.) )
2310 {
2311 return( false );
2312 }
2313 }
2314 }
2315 // <<< DEPRECATED <<< //
2316
2317 //-----------------------------------------------------
2318 return( m_Attributes.Get_Field_Count() > 0 );
2319}
2320
2321//---------------------------------------------------------
2322bool CSG_Grids::_Save_Header(CSG_File &Stream)
2323{
2324 CSG_MetaData Header;
2325
2326 Header.Set_Name("GRIDS");
2327
2328 Header.Add_Property("saga-version", SAGA_VERSION);
2329
2330 //-----------------------------------------------------
2331 // general
2332
2333 Header.Add_Child("NAME" , Get_Name ());
2334 Header.Add_Child("DESCRIPTION", Get_Description());
2335 Header.Add_Child("UNIT" , Get_Unit ());
2336
2337 Header.Add_Child("SCALE" , Get_Scaling ());
2338 Header.Add_Child("OFFSET" , Get_Offset ());
2339
2340 Header.Add_Child("NODATA_MIN" , Get_NoData_Value(false));
2341 Header.Add_Child("NODATA_MAX" , Get_NoData_Value(true ));
2342
2344
2345 //-----------------------------------------------------
2346 // grid system
2347
2348 Header.Add_Child("NX" , Get_NX ());
2349 Header.Add_Child("NY" , Get_NY ());
2350 Header.Add_Child("CELLSIZE" , Get_Cellsize());
2351 Header.Add_Child("XMIN" , Get_XMin ());
2352 Header.Add_Child("YMIN" , Get_YMin ());
2353
2354 //-----------------------------------------------------
2355 // attributes
2356
2357 CSG_MetaData &Attributes = *Header.Add_Child("ATTRIBUTES");
2358
2359 Attributes.Add_Property("Z_FIELD", m_Z_Attribute);
2360 Attributes.Add_Property("Z_NAME" , m_Z_Name );
2361
2362 for(int iField=0; iField<m_Attributes.Get_Field_Count(); iField++)
2363 {
2364 Attributes.Add_Child("FIELD", m_Attributes.Get_Field_Name(iField))->Add_Property(
2365 "TYPE", SG_Data_Type_Get_Identifier(m_Attributes.Get_Field_Type(iField))
2366 );
2367 }
2368
2369 //-----------------------------------------------------
2370 return( Header.Save(Stream) );
2371}
2372
2373
2375// //
2377
2378//---------------------------------------------------------
2379bool CSG_Grids::_Load_Attributes(CSG_File &Stream)
2380{
2381 CSG_Table Attributes(m_Attributes);
2382
2383 CSG_String sLine;
2384
2385 while( Stream.Read_Line(sLine) && !sLine.is_Empty() )
2386 {
2387 CSG_String_Tokenizer Values(sLine, "\t", SG_TOKEN_RET_EMPTY_ALL);
2388
2389 if( Values.Get_Tokens_Count() == (size_t)Attributes.Get_Field_Count() )
2390 {
2391 CSG_Table_Record *pRecord = Attributes.Add_Record();
2392
2393 for(int iField=0; iField<m_Attributes.Get_Field_Count(); iField++)
2394 {
2395 pRecord->Set_Value(iField, Values.Get_Next_Token());
2396 }
2397
2398 if( !Add_Grid(*pRecord) )
2399 {
2400 return( false );
2401 }
2402 }
2403 }
2404
2405 return( true );
2406}
2407
2408//---------------------------------------------------------
2409bool CSG_Grids::_Save_Attributes(CSG_File &Stream)
2410{
2411 for(int iRecord=0; iRecord<m_Attributes.Get_Count(); iRecord++)
2412 {
2413 for(int iField=0; iField<m_Attributes.Get_Field_Count(); iField++)
2414 {
2415 Stream.Write(m_Attributes[iRecord].asString(iField));
2416 Stream.Write(iField < m_Attributes.Get_Field_Count() - 1 ? "\t" : "\n");
2417 }
2418 }
2419
2420 return( true );
2421}
2422
2423
2425// //
2427
2428//---------------------------------------------------------
2429bool CSG_Grids::_Load_Data(CSG_File &Stream, CSG_Grid *pGrid)
2430{
2431 if( !pGrid )
2432 {
2433 return( false );
2434 }
2435
2436 TSG_Data_Type Type = Get_Type();
2437
2438 CSG_Array Line(1, Get_nLineBytes());
2439
2440 for(int y=0; y<Get_NY(); y++)
2441 {
2442 if( !Stream.Read(Line.Get_Array(), Get_nLineBytes()) )
2443 {
2444 return( false );
2445 }
2446
2447 char *pValue = (char *)Line.Get_Array();
2448
2449 for(int x=0, n=Get_nValueBytes(); x<Get_NX(); x++, pValue+=n)
2450 {
2451 switch( Type )
2452 {
2453 case SG_DATATYPE_Byte : pGrid->Set_Value(x, y, *(BYTE *)pValue, false); break;
2454 case SG_DATATYPE_Char : pGrid->Set_Value(x, y, *(char *)pValue, false); break;
2455 case SG_DATATYPE_Word : pGrid->Set_Value(x, y, *(WORD *)pValue, false); break;
2456 case SG_DATATYPE_Short : pGrid->Set_Value(x, y, *(short *)pValue, false); break;
2457 case SG_DATATYPE_DWord : pGrid->Set_Value(x, y, *(DWORD *)pValue, false); break;
2458 case SG_DATATYPE_Int : pGrid->Set_Value(x, y, *(int *)pValue, false); break;
2459 case SG_DATATYPE_Float : pGrid->Set_Value(x, y, *(float *)pValue, false); break;
2460 case SG_DATATYPE_Double: pGrid->Set_Value(x, y, *(double *)pValue, false); break;
2461 default: break;
2462 }
2463 }
2464 }
2465
2466 return( true );
2467}
2468
2469//---------------------------------------------------------
2470bool CSG_Grids::_Save_Data(CSG_File &Stream, CSG_Grid *pGrid)
2471{
2472 TSG_Data_Type Type = Get_Type();
2473
2474 CSG_Array Line(1, Get_nLineBytes());
2475
2476 for(int y=0; y<Get_NY(); y++)
2477 {
2478 char *pValue = (char *)Line.Get_Array();
2479
2480 for(int x=0, n=Get_nValueBytes(); x<Get_NX(); x++, pValue+=n)
2481 {
2482 switch( Type )
2483 {
2484 case SG_DATATYPE_Byte : *(BYTE *)pValue = pGrid->asByte (x, y, false); break;
2485 case SG_DATATYPE_Char : *(char *)pValue = pGrid->asChar (x, y, false); break;
2486 case SG_DATATYPE_Word : *(WORD *)pValue = pGrid->asShort (x, y, false); break;
2487 case SG_DATATYPE_Short : *(short *)pValue = pGrid->asShort (x, y, false); break;
2488 case SG_DATATYPE_DWord : *(DWORD *)pValue = pGrid->asInt (x, y, false); break;
2489 case SG_DATATYPE_Int : *(int *)pValue = pGrid->asInt (x, y, false); break;
2490 case SG_DATATYPE_Float : *(float *)pValue = pGrid->asFloat (x, y, false); break;
2491 case SG_DATATYPE_Double: *(double *)pValue = pGrid->asDouble(x, y, false); break;
2492 default: break;
2493 }
2494 }
2495
2496 if( !Stream.Write(Line.Get_Array(), Get_nLineBytes()) )
2497 {
2498 return( false );
2499 }
2500 }
2501
2502 return( true );
2503}
2504
2505
2507// //
2509
2510//-----------------------------------------------------
2511bool CSG_Grids::_Assign_Interpolated (CSG_Grids *pSource, CSG_Grid_Resampling Interpolation) { return( false ); }
2512bool CSG_Grids::_Assign_MeanValue (CSG_Grids *pSource, bool bVolumeProportional ) { return( false ); }
2513bool CSG_Grids::_Assign_ExtremeValue (CSG_Grids *pSource, bool bMaximum ) { return( false ); }
2514bool CSG_Grids::_Assign_Majority (CSG_Grids *pSource ) { return( false ); }
2515
2516
2518// //
2520
2521//-----------------------------------------------------
2522CSG_Grids & CSG_Grids::_Operation_Arithmetic(const CSG_Grids &Grids, TSG_Grid_Operation Operation) { return( *this ); }
2523CSG_Grids & CSG_Grids::_Operation_Arithmetic(double Value , TSG_Grid_Operation Operation) { return( *this ); }
2524
2525
2527// //
2528// //
2529// //
2531
2532//---------------------------------------------------------
void SG_UI_Msg_Add_Error(const char *Message)
bool SG_UI_Process_Get_Okay(bool bBlink)
void SG_UI_Msg_Add(const char *Message, bool bNewLine, TSG_UI_MSG_STYLE Style)
void SG_UI_Process_Set_Text(const CSG_String &Text)
bool SG_UI_Process_Set_Ready(void)
bool SG_UI_Process_Set_Progress(int Position, int Range)
int SG_UI_Msg_Lock(bool bOn)
void SG_UI_ProgressAndMsg_Lock(bool bOn)
TSG_Data_Type SG_Data_Type_Get_Type(const CSG_String &Identifier)
Definition api_core.cpp:153
CSG_String SG_Data_Type_Get_Identifier(TSG_Data_Type Type)
Definition api_core.cpp:147
@ SG_UI_MSG_STYLE_FAILURE
Definition api_core.h:1585
@ SG_UI_MSG_STYLE_SUCCESS
Definition api_core.h:1584
SAGA_API_DLL_EXPORT bool SG_File_Cmp_Extension(const CSG_String &File, const CSG_String &Extension)
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
signed long long sLong
Definition api_core.h:158
SAGA_API_DLL_EXPORT void SG_Free(void *memblock)
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
@ SG_TOKEN_RET_EMPTY_ALL
Definition api_core.h:754
SAGA_API_DLL_EXPORT bool SG_File_Delete(const CSG_String &FileName)
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
SAGA_API_DLL_EXPORT void * SG_Realloc(void *memblock, size_t size)
SAGA_API_DLL_EXPORT CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
#define SG_FREE_SAFE(PTR)
Definition api_core.h:205
SAGA_API_DLL_EXPORT bool SG_File_Set_Extension(CSG_String &File, const CSG_String &Extension)
TSG_Data_Type
Definition api_core.h:997
@ SG_DATATYPE_Byte
Definition api_core.h:999
@ SG_DATATYPE_Short
Definition api_core.h:1002
@ SG_DATATYPE_Word
Definition api_core.h:1001
@ SG_DATATYPE_Float
Definition api_core.h:1007
@ SG_DATATYPE_Undefined
Definition api_core.h:1013
@ SG_DATATYPE_Double
Definition api_core.h:1008
@ SG_DATATYPE_Int
Definition api_core.h:1004
@ SG_DATATYPE_Char
Definition api_core.h:1000
@ SG_DATATYPE_DWord
Definition api_core.h:1003
#define _TL(s)
Definition api_core.h:1568
SAGA_API_DLL_EXPORT CSG_String SG_Get_String(double Value, int Precision=-99)
@ SG_FILE_W
Definition api_core.h:1115
@ SG_FILE_R
Definition api_core.h:1114
void ** Create(const CSG_Array_Pointer &Array)
size_t Count(void) const
CSG_Data_Collection & Grids(void) const
const SG_Char * Get_Name(void) const
void Set_Name(const CSG_String &Name)
bool is_NoData_Value(double Value) const
Definition dataobject.h:255
void Set_Update_Flag(bool bOn=true)
Definition dataobject.h:285
virtual bool Set_Max_Samples(sLong Max_Samples)
bool Save_MetaData(const CSG_String &FileName)
double Get_NoData_Value(bool bUpper=false) const
Definition dataobject.h:253
virtual bool Set_NoData_Value_Range(double Lower, double Upper)
const SG_Char * Get_File_Name(bool bNative=true) const
bool Load_MetaData(const CSG_String &FileName)
bool Update(bool bForce=false)
virtual bool Destroy(void)
void Set_Description(const CSG_String &Description)
virtual bool Set_NoData_Value(double Value)
CSG_Data_Object * Get_Owner(void) const
Definition dataobject.h:231
void Set_Owner(CSG_Data_Object *pOwner)
Definition dataobject.h:232
const SG_Char * Get_Description(void) const
sLong Get_Max_Samples(void) const
Definition dataobject.h:263
CSG_Projection & Get_Projection(void)
class CSG_Grids * asGrids(bool bPolymorph=false) const
virtual TSG_Data_Object_Type Get_ObjectType(void) const =0
Returns the object type as defined by TSG_Data_Object_Type. Used for run time type checking.
class CSG_Grid * asGrid(bool bPolymorph=false) const
CSG_MetaData & Get_MetaData_DB(void) const
Definition dataobject.h:235
void Set_File_Name(const CSG_String &FileName)
virtual bool Open(const SG_Char *FileName, int Mode=SG_FILE_R, bool bBinary=true, int Encoding=SG_FILE_ENCODING_ANSI)
Definition api_file.cpp:113
virtual const CSG_String & Get_File_Name(void) const
Definition api_core.h:1140
bool Read_Line(CSG_String &Line) const
Definition api_file.cpp:399
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:370
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:338
int Get_xWorld_to_Grid(double xWorld) const
Definition grid.h:318
double Get_Cellsize(void) const
Definition grid.h:255
int Get_yWorld_to_Grid(double yWorld) const
Definition grid.h:319
double Get_Offset(void) const
Definition grid.cpp:428
virtual int asInt(int x, int y, bool bScaled=true) const
Definition grid.h:785
virtual char asChar(int x, int y, bool bScaled=true) const
Definition grid.h:781
double Get_Scaling(void) const
Definition grid.cpp:422
virtual short asShort(int x, int y, bool bScaled=true) const
Definition grid.h:783
virtual bool is_Valid(void) const
Definition grid.cpp:441
virtual double asDouble(sLong i, bool bScaled=true) const
Definition grid.h:793
virtual BYTE asByte(int x, int y, bool bScaled=true) const
Definition grid.h:779
virtual bool Assign(double Value=0.)
virtual float asFloat(int x, int y, bool bScaled=true) const
Definition grid.h:789
void Set_Scaling(double Scale=1., double Offset=0.)
Definition grid.cpp:406
const CSG_Grid_System & Get_System(void) const
Definition grid.h:559
virtual void Set_Value(sLong i, double Value, bool bScaled=true)
Definition grid.h:843
TSG_Data_Type Get_Type(void) const
Definition grid.h:547
TSG_Data_Type Get_Type(void) const
Definition grids.h:172
virtual bool On_Update(void)
Definition grids.cpp:1415
bool Del_Grids(bool bDetach=false)
Definition grids.cpp:891
CSG_String Get_Grid_Name(int i, int Style=0) const
Definition grids.cpp:929
bool Set_Grid_Count(int Count)
Definition grids.cpp:671
const CSG_Grid_System & Get_System(void) const
Definition grids.h:184
int Get_NZ(void) const
Definition grids.h:190
double Get_Max(void)
Definition grids.cpp:1472
virtual const CSG_Rect & Get_Extent(void)
Definition grids.h:186
const CSG_Simple_Statistics & Get_Statistics(void)
Definition grids.cpp:1544
bool Set_Z_Name_Field(int Field)
Definition grids.cpp:555
virtual bool is_NoData(int x, int y, int z) const
Definition grids.h:373
virtual void Set_Modified(bool bModified=true)
Definition grids.h:317
virtual CSG_Grids & Multiply(double Value)
Definition grids.cpp:1101
bool Set_Z_Attribute(int Field, bool bSetNameField=false)
Definition grids.cpp:537
virtual bool On_Delete(void)
Definition grids.cpp:1739
virtual bool Set_NoData_Value_Range(double loValue, double hiValue)
Definition grids.cpp:456
virtual bool is_Valid(void) const
Definition grids.cpp:503
sLong Get_NCells(void) const
Definition grids.h:191
double Get_Cellsize(void) const
Definition grids.h:195
bool is_Compatible(CSG_Grid *pGrid) const
Definition grids.cpp:509
double Get_Variance(void)
Definition grids.cpp:1487
virtual bool Create(const CSG_Grids &Grids)
Definition grids.cpp:319
bool Add_Grid(double Z)
Definition grids.cpp:726
virtual CSG_Grids & operator+=(double Value)
Definition grids.cpp:1064
double Get_StdDev(void)
Definition grids.cpp:1482
virtual bool Assign(double Value=0.)
Definition grids.cpp:987
virtual void Set_Value(sLong i, double Value, bool bScaled=true)
Definition grids.h:425
int Get_Z_Name_Field(void) const
Definition grids.cpp:567
sLong Get_Sorted(sLong Position, bool bDown=true, bool bCheckNoData=true)
Definition grids.h:453
bool Update_Z_Order(void)
Definition grids.cpp:630
virtual CSG_Grids & Add(double Value)
Definition grids.cpp:1069
const SG_Char * Get_Unit(void) const
Definition grids.h:178
bool Add_Attribute(const char *Name, TSG_Data_Type Type, int Insert=-1)
Definition grids.cpp:573
double Get_XMin(bool bCells=false) const
Definition grids.h:200
virtual ~CSG_Grids(void)
Definition grids.cpp:177
virtual CSG_Grids & Divide(double Value)
Definition grids.cpp:1117
double Get_ZMax(bool bCells=false) const
Definition grids.h:209
double Get_Offset(void) const
Definition grids.h:274
double Get_Value(double x, double y, double z, CSG_Grid_Resampling Resampling=CSG_Grid_Resampling::Bicubic_2, CSG_Grid_Resampling ZResampling=CSG_Grid_Resampling::Undefined) const
Definition grids.cpp:1140
double Get_Scaling(void) const
Definition grids.h:273
double Get_Z(int i) const
Definition grids.h:243
int Get_Grid_Count(void) const
Definition grids.h:252
virtual CSG_Grids & operator*=(double Value)
Definition grids.cpp:1096
int Get_Z_Attribute(void) const
Definition grids.h:217
void Assign_NoData(void)
Definition grids.cpp:978
CSG_Grid * Get_Grid_Ptr(int i) const
Definition grids.h:263
sLong Get_Data_Count(void)
Definition grids.cpp:1493
bool Set_Attribute(int i, int Field, const CSG_String &Value)
Definition grids.cpp:609
double Get_YMin(bool bCells=false) const
Definition grids.h:204
virtual int asInt(int x, int y, int z, bool bScaled=true) const
Definition grids.h:394
bool Del_Attribute(int Field)
Definition grids.cpp:581
virtual bool On_Reload(void)
Definition grids.cpp:1733
virtual bool Load(const CSG_String &File, bool bLoadData=true)
Definition grids.cpp:1765
int Get_NX(void) const
Definition grids.h:188
int Get_NY(void) const
Definition grids.h:189
virtual CSG_Grids & operator/=(double Value)
Definition grids.cpp:1112
double Get_Range(void)
Definition grids.cpp:1477
const CSG_Table & Get_Attributes(void) const
Definition grids.h:227
double Get_Mean(void)
Definition grids.cpp:1462
virtual double asDouble(sLong i, bool bScaled=true) const
Definition grids.h:402
void Set_Unit(const CSG_String &Unit)
Definition grids.cpp:437
sLong Get_NoData_Count(void)
Definition grids.cpp:1498
virtual bool Set_Max_Samples(sLong Max_Samples)
Definition grids.cpp:1619
const CSG_Histogram & Get_Histogram(size_t nClasses=0)
Definition grids.cpp:1644
CSG_Grids(void)
Definition grids.cpp:168
virtual CSG_Grids & operator=(const CSG_Grids &Grids)
Definition grids.cpp:1053
double Get_Percentile(double Percentile, bool bFromHistogram=true)
Definition grids.cpp:1527
double Get_Min(void)
Definition grids.cpp:1467
int Get_nValueBytes(void) const
Definition grids.h:174
virtual CSG_Grids & Subtract(double Value)
Definition grids.cpp:1085
bool is_Scaled(void) const
Definition grids.h:275
virtual CSG_Grids & operator-=(double Value)
Definition grids.cpp:1080
void Set_Scaling(double Scale=1., double Offset=0.)
Definition grids.cpp:443
virtual bool Save(const CSG_String &File, int Format=0)
Definition grids.cpp:1791
double Get_Quantile(double Quantile, bool bFromHistogram=true)
Definition grids.cpp:1504
bool Del_Grid(int i, bool bDetach=false)
Definition grids.cpp:853
int Get_nLineBytes(void) const
Definition grids.h:175
virtual bool Destroy(void)
Definition grids.cpp:293
bool Set_Z(int i, double Value)
Definition grids.cpp:624
bool Create(const CSG_Histogram &Histogram)
bool Update(void)
bool Save(const CSG_String &File, const SG_Char *Extension=NULL) const
Definition metadata.cpp:879
bool Del_Children(int Depth=0, const SG_Char *Name=NULL)
Definition metadata.cpp:381
int Get_Children_Count(void) const
Definition metadata.h:148
bool Add_Children(const CSG_MetaData &MetaData)
Definition metadata.cpp:359
const SG_Char * Get_Property(int Index) const
Definition metadata.h:181
void Set_Name(const CSG_String &Name)
Definition metadata.h:130
CSG_MetaData * Add_Child(void)
Definition metadata.cpp:166
bool Load(const CSG_String &File, const SG_Char *Extension=NULL)
Definition metadata.cpp:786
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition metadata.cpp:559
bool Save(const CSG_String &File, ESG_CRS_Format Format=ESG_CRS_Format::WKT) const
bool Create(const CSG_Projection &Projection)
bool is_Okay(void) const
Definition geo_tools.h:863
bool Load(const CSG_String &File)
double Get_XMax(void) const
Definition geo_tools.h:506
double Get_XMin(void) const
Definition geo_tools.h:505
double Get_YMin(void) const
Definition geo_tools.h:507
double Get_YMax(void) const
Definition geo_tools.h:508
double Get_Maximum(void)
Definition mat_tools.h:749
bool Create(bool bHoldValues=false)
sLong Get_Count(void) const
Definition mat_tools.h:745
double Get_Minimum(void)
Definition mat_tools.h:748
bool Get_Value(double x, double &y)
int Cmp(const CSG_String &String) const
void Clear(void)
CSG_String BeforeFirst(char Character) const
static CSG_String Format(const char *Format,...)
const SG_Char * c_str(void) const
int Printf(const char *Format,...)
bool is_Empty(void) const
bool Set_Value(int Field, const CSG_String &Value)
bool Create(void)
Definition table.cpp:153
sLong Get_Count(void) const
Definition table.h:400
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
Definition table.cpp:823
bool Set_Index(CSG_Index &Index, int Field, bool bAscending=true) const
Definition table.cpp:1508
virtual bool Set_Value(sLong Index, int Field, const SG_Char *Value)
Definition table.cpp:1159
bool Delete_Tool(CSG_Tool *pTool) const
CSG_Tool * Create_Tool(const CSG_String &Library, int Index, bool bWithGUI=false, bool bWithCMD=true) const
bool Settings_Push(class CSG_Data_Manager *pManager=NULL)
Definition tool.cpp:621
bool Set_Parameter(const CSG_String &ID, CSG_Parameter *pValue)
Definition tool.cpp:1284
virtual bool On_Before_Execution(void)
Definition tool.h:229
bool Execute(bool bAddHistory=false)
Definition tool.cpp:258
@ SG_DATAOBJECT_TYPE_Grids
Definition dataobject.h:119
@ SG_DATAOBJECT_TYPE_Grid
Definition dataobject.h:118
struct SSG_Point_3D TSG_Point_3D
#define SG_GRID_HISTOGRAM_CLASSES_DEFAULT
Definition grid.cpp:1168
#define SORT_SWAP(a, b)
CSG_Grid * SG_Create_Grid(void)
Definition grid.cpp:72
TSG_Grid_Operation
Definition grid.h:194
CSG_Grid_Resampling
Definition grid.h:156
#define ADD_TO_SPLINE(i)
CSG_Grids * SG_Create_Grids(void)
Definition grids.cpp:65
@ GRIDS_FILE_FORMAT_GeoTIFF
Definition grids.h:95
@ GRIDS_FILE_FORMAT_Normal
Definition grids.h:93
@ GRIDS_FILE_FORMAT_Compressed
Definition grids.h:94
@ GRIDS_FILE_FORMAT_Undefined
Definition grids.h:92
#define SG_GRIDS_NAME_INDEX
Definition grids.h:101
#define SG_GRIDS_NAME_VALUE
Definition grids.h:102
#define SG_GRIDS_NAME_GRID
Definition grids.h:103
#define SG_GRIDS_NAME_OWNER
Definition grids.h:100
#define SAGA_VERSION
Definition saga_api.h:90
@ TABLE_INDEX_Ascending
Definition table.h:105
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)
#define SG_TOOL_PARAMETER_SET(IDENTIFIER, VALUE)
#define SG_TOOL_PARAMLIST_ADD(IDENTIFIER, VALUE)
#define SG_RUN_TOOL(bRetVal, LIBRARY, TOOL, CONDITION)