SAGA API  v9.2
table.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 // table.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 Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 // e-mail: oconrad@saga-gis.org //
49 // //
51 
52 //---------------------------------------------------------
53 #include "table.h"
54 #include "shapes.h"
55 #include "tool_library.h"
56 
57 
59 // //
60 // //
61 // //
63 
64 //---------------------------------------------------------
66 {
67  return( new CSG_Table );
68 }
69 
70 //---------------------------------------------------------
72 {
73  switch( Table.Get_ObjectType() )
74  {
76  return( new CSG_Table(Table) );
77 
80  return( SG_Create_Shapes(*((CSG_Shapes *)&Table)) );
81 
82  default:
83  return( NULL );
84  }
85 }
86 
87 //---------------------------------------------------------
89 {
90  if( pTemplate )
91  {
92  switch( pTemplate->Get_ObjectType() )
93  {
95  return( new CSG_Table(pTemplate) );
96 
99  return( SG_Create_Shapes((CSG_Shapes *)pTemplate) );
100 
101  default:
102  break;
103  }
104  }
105 
106  return( new CSG_Table() );
107 }
108 
109 //---------------------------------------------------------
110 CSG_Table * SG_Create_Table(const char *File, TSG_Table_File_Type Format, int Encoding) { return( SG_Create_Table(CSG_String(File), Format, Encoding) ); }
111 CSG_Table * SG_Create_Table(const wchar_t *File, TSG_Table_File_Type Format, int Encoding) { return( SG_Create_Table(CSG_String(File), Format, Encoding) ); }
112 CSG_Table * SG_Create_Table(const CSG_String &File, TSG_Table_File_Type Format, int Encoding)
113 {
114  return( new CSG_Table(File, Format, Encoding) );
115 }
116 
117 //---------------------------------------------------------
118 CSG_Table * SG_Create_Table(const char *File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding) { return( SG_Create_Table(CSG_String(File), Format, Separator, Encoding) ); }
119 CSG_Table * SG_Create_Table(const wchar_t *File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding) { return( SG_Create_Table(CSG_String(File), Format, Separator, Encoding) ); }
120 CSG_Table * SG_Create_Table(const CSG_String &File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding)
121 {
122  return( new CSG_Table(File, Format, Encoding) );
123 }
124 
125 
127 // //
128 // //
129 // //
131 
132 //---------------------------------------------------------
134  : CSG_Data_Object()
135 {
137 }
138 
139 //---------------------------------------------------------
141  : CSG_Data_Object()
142 {
143  _On_Construction(); Create(Table);
144 }
145 
146 bool CSG_Table::Create(const CSG_Table &Table)
147 {
148  return( Assign((CSG_Data_Object *)&Table) );
149 }
150 
151 //---------------------------------------------------------
152 CSG_Table::CSG_Table(const char *File, TSG_Table_File_Type Format, int Encoding) : CSG_Table(CSG_String(File), Format, Encoding) {}
153 CSG_Table::CSG_Table(const wchar_t *File, TSG_Table_File_Type Format, int Encoding) : CSG_Table(CSG_String(File), Format, Encoding) {}
154 CSG_Table::CSG_Table(const CSG_String &File, TSG_Table_File_Type Format, int Encoding)
155  : CSG_Data_Object()
156 {
157  _On_Construction(); Create(File, Format, Encoding);
158 }
159 
160 bool CSG_Table::Create(const char *File, TSG_Table_File_Type Format, int Encoding) { return( Create(CSG_String(File), Format, Encoding) ); }
161 bool CSG_Table::Create(const wchar_t *File, TSG_Table_File_Type Format, int Encoding) { return( Create(CSG_String(File), Format, Encoding) ); }
162 bool CSG_Table::Create(const CSG_String &File, TSG_Table_File_Type Format, int Encoding)
163 {
164  Destroy();
165 
166  SG_UI_Msg_Add(CSG_String::Format("%s %s: %s...", _TL("Loading"), _TL("table"), File.c_str()), true);
167 
168  //-----------------------------------------------------
169  bool bResult = File.BeforeFirst(':').Cmp("PGSQL") && SG_File_Exists(File) && Load(File, (int)Format, '\0', Encoding);
170 
171  if( bResult )
172  {
173  Set_File_Name(File, true);
174  }
175 
176  //-----------------------------------------------------
177  else if( File.BeforeFirst(':').Cmp("PGSQL") == 0 ) // database source
178  {
179  CSG_String s(File);
180 
181  s = s.AfterFirst(':'); CSG_String Host (s.BeforeFirst(':'));
182  s = s.AfterFirst(':'); CSG_String Port (s.BeforeFirst(':'));
183  s = s.AfterFirst(':'); CSG_String DBName(s.BeforeFirst(':'));
184  s = s.AfterFirst(':'); CSG_String Table (s.BeforeFirst(':'));
185 
186  CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("db_pgsql", 0, true); // CGet_Connections
187 
188  if( pTool != NULL )
189  {
191 
192  //---------------------------------------------
193  CSG_Table Connections; CSG_String Connection(DBName + " [" + Host + ":" + Port + "]");
194 
195  pTool->Set_Manager(NULL); pTool->On_Before_Execution();
196 
197  if( SG_TOOL_PARAMETER_SET("CONNECTIONS", &Connections) && pTool->Execute() ) // CGet_Connections
198  {
199  for(int i=0; !bResult && i<Connections.Get_Count(); i++)
200  {
201  if( !Connection.Cmp(Connections[i].asString(0)) )
202  {
203  bResult = true;
204  }
205  }
206  }
207 
209 
210  //---------------------------------------------
211  if( bResult && (bResult = (pTool = SG_Get_Tool_Library_Manager().Create_Tool("db_pgsql", 12, true)) != NULL) == true ) // CPGIS_Table_Load
212  {
213  pTool->Set_Manager(NULL); pTool->On_Before_Execution();
214 
215  bResult = SG_TOOL_PARAMETER_SET("CONNECTION", Connection)
216  && SG_TOOL_PARAMETER_SET("DB_TABLE" , Table )
217  && SG_TOOL_PARAMETER_SET("TABLE" , this )
218  && pTool->Execute();
219 
221  }
222 
224  }
225  }
226 
227  //-----------------------------------------------------
228  if( bResult )
229  {
230  Set_Modified(false);
231  Set_Update_Flag();
232 
233  SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
234 
235  return( true );
236  }
237 
238  Destroy();
239 
240  SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
241 
242  return( false );
243 }
244 
245 //---------------------------------------------------------
246 CSG_Table::CSG_Table(const char *File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding) : CSG_Table(CSG_String(File), Format, Separator, Encoding) {}
247 CSG_Table::CSG_Table(const wchar_t *File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding) : CSG_Table(CSG_String(File), Format, Separator, Encoding) {}
248 CSG_Table::CSG_Table(const CSG_String &File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding)
249  : CSG_Data_Object()
250 {
251  _On_Construction(); Create(File, Format, Separator, Encoding);
252 }
253 
254 bool CSG_Table::Create(const char *File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding) { return( Create(CSG_String(File), Format, Separator, Encoding) ); }
255 bool CSG_Table::Create(const wchar_t *File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding) { return( Create(CSG_String(File), Format, Separator, Encoding) ); }
256 bool CSG_Table::Create(const CSG_String &File, TSG_Table_File_Type Format, const SG_Char Separator, int Encoding)
257 {
258  return( Load(File, (int)Format, Separator, Encoding) );
259 }
260 
261 //---------------------------------------------------------
263  : CSG_Data_Object()
264 {
265  _On_Construction(); Create(pTemplate);
266 }
267 
268 bool CSG_Table::Create(const CSG_Table *pTemplate)
269 {
270  if( !pTemplate || pTemplate->Get_Field_Count() < 1 )
271  {
272  return( false );
273  }
274 
275  Destroy();
276 
277  Set_Name (pTemplate->Get_Name ());
278  Set_Description (pTemplate->Get_Description());
279  Set_NoData_Value_Range(pTemplate->Get_NoData_Value(), pTemplate->Get_NoData_Value(true));
280 
281  m_Encoding = pTemplate->m_Encoding;
282 
283  for(int i=0; i<pTemplate->Get_Field_Count(); i++)
284  {
285  Add_Field(pTemplate->Get_Field_Name(i), pTemplate->Get_Field_Type(i));
286  }
287 
288  return( true );
289 }
290 
291 
293 // //
295 
296 //---------------------------------------------------------
298 {
299  m_nFields = 0;
300  m_Field_Name = NULL;
301  m_Field_Type = NULL;
302  m_Field_Stats = NULL;
303 
304  m_Records = NULL;
305  m_nRecords = 0;
306  m_nBuffer = 0;
307 
309 
310  m_Selection.Create(sizeof(sLong), 0, TSG_Array_Growth::SG_ARRAY_GROWTH_3);
311 
312  Set_Update_Flag();
313 }
314 
315 
317 // //
319 
320 //---------------------------------------------------------
322 {
323  Destroy();
324 }
325 
326 //---------------------------------------------------------
328 {
329  _Destroy_Selection();
330 
331  Del_Records();
332 
333  if( m_nFields > 0 )
334  {
335  for(int i=0; i<m_nFields; i++)
336  {
337  delete(m_Field_Name [i]);
338  delete(m_Field_Stats[i]);
339  }
340 
344 
345  m_nFields = 0;
346  m_Field_Name = NULL;
347  m_Field_Type = NULL;
348  m_Field_Stats = NULL;
349  }
350 
352 
353  return( true );
354 }
355 
356 
358 // //
359 // Assign //
360 // //
362 
363 //---------------------------------------------------------
365 {
366  Create(Table);
367 
368  return( *this );
369 }
370 
371 //---------------------------------------------------------
373 {
374  if( !pObject || !pObject->is_Valid()
375  || ( pObject->Get_ObjectType() != SG_DATAOBJECT_TYPE_Table
377  && pObject->Get_ObjectType() != SG_DATAOBJECT_TYPE_PointCloud ) )
378  {
379  return( false );
380  }
381 
382  CSG_Table *pTable = (CSG_Table *)pObject;
383 
384  if( !Create(pTable) )
385  {
386  return( false );
387  }
388 
389  for(sLong i=0; i<pTable->Get_Count(); i++)
390  {
391  Add_Record(pTable->Get_Record(i));
392  }
393 
394  Get_MetaData() = pTable->Get_MetaData();
395 // Get_History () = pTable->Get_History ();
396 
397  return( true );
398 }
399 
400 //---------------------------------------------------------
402 {
403  if( is_Compatible(Table) && Set_Count(Table.Get_Count()) )
404  {
405  for(sLong i=0; i<Table.Get_Count(); i++)
406  {
407  Get_Record(i)->Assign(Table.Get_Record(i));
408  }
409 
410  return( true );
411  }
412 
413  return( false );
414 }
415 
416 //---------------------------------------------------------
418 {
419  return( pTable && Assign_Values(*pTable) );
420 }
421 
422 //---------------------------------------------------------
423 bool CSG_Table::Assign_Values(const SG_Char *FileName)
424 {
425  CSG_Table Table; return( Table.Create(FileName) && Assign_Values(&Table) );
426 }
427 
428 
430 // //
431 // Checks //
432 // //
434 
435 //---------------------------------------------------------
436 bool CSG_Table::is_Compatible(const CSG_Table &Table, bool bExactMatch) const
437 {
438  if( Get_Field_Count() == Table.Get_Field_Count() )
439  {
440  for(int i=0; i<Get_Field_Count(); i++)
441  {
442  if( bExactMatch )
443  {
444  if( Get_Field_Type(i) != Table.Get_Field_Type(i) )
445  {
446  return( false );
447  }
448  }
449  else switch( Get_Field_Type(i) )
450  {
451  case SG_DATATYPE_String:
452  // if( Table.Get_Field_Type(i) != SG_DATATYPE_String )
453  // {
454  // return( false );
455  // }
456  break;
457 
458  default:
459  if( Table.Get_Field_Type(i) == SG_DATATYPE_String )
460  {
461  return( false );
462  }
463  break;
464  }
465  }
466 
467  return( true );
468  }
469 
470  return( false );
471 }
472 
473 //---------------------------------------------------------
474 bool CSG_Table::is_Compatible(CSG_Table *pTable, bool bExactMatch) const
475 {
476  return( pTable && is_Compatible(*pTable, bExactMatch) );
477 }
478 
479 
481 // //
482 // Fields //
483 // //
485 
486 //---------------------------------------------------------
487 bool CSG_Table::Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Position)
488 {
489  if( Position < 0 || Position > m_nFields )
490  {
491  Position = m_nFields;
492  }
493 
494  //-----------------------------------------------------
495  m_nFields++;
496 
500 
501  //-----------------------------------------------------
502  for(int i=m_nFields-1; i>Position; i--)
503  {
504  m_Field_Name [i] = m_Field_Name [i - 1];
505  m_Field_Type [i] = m_Field_Type [i - 1];
506  m_Field_Stats[i] = m_Field_Stats[i - 1];
507  }
508 
509  //-----------------------------------------------------
510  m_Field_Name [Position] = new CSG_String(!Name.is_Empty() ? Name : CSG_String::Format("FIELD_%d", m_nFields));
511  m_Field_Type [Position] = Type;
512  m_Field_Stats[Position] = new CSG_Simple_Statistics();
513 
514  //-----------------------------------------------------
515  for(sLong i=0; i<m_nRecords; i++)
516  {
517  m_Records[i]->_Add_Field(Position);
518  }
519 
520  Set_Modified();
521 
522  return( true );
523 }
524 
525 //---------------------------------------------------------
526 bool CSG_Table::Del_Field(int del_Field)
527 {
528  if( del_Field < 0 || del_Field >= m_nFields )
529  {
530  return( false );
531  }
532 
533  //-----------------------------------------------------
534  delete(m_Field_Name [del_Field]);
535  delete(m_Field_Stats[del_Field]);
536 
537  //-------------------------------------------------
538  m_nFields--;
539 
540  for(int i=del_Field; i<m_nFields; i++)
541  {
542  m_Field_Name [i] = m_Field_Name [i + 1];
543  m_Field_Type [i] = m_Field_Type [i + 1];
544  m_Field_Stats[i] = m_Field_Stats[i + 1];
545  }
546 
547  //-------------------------------------------------
551 
552  //-------------------------------------------------
553  for(sLong i=0; i<m_nRecords; i++)
554  {
555  m_Records[i]->_Del_Field(del_Field);
556  }
557 
558  Set_Modified();
559 
560  return( true );
561 }
562 
563 //---------------------------------------------------------
564 bool CSG_Table::Mov_Field(int iField, int Position)
565 {
566  if( Position < 0 )
567  {
568  Position = 0;
569  }
570  else if( Position >= m_nFields - 1 )
571  {
572  Position = m_nFields - 1;
573  }
574 
575  if( iField < 0 || iField >= m_nFields || iField == Position )
576  {
577  return( false );
578  }
579 
580  //-----------------------------------------------------
581  if( Position > iField )
582  {
583  Position++;
584  }
585 
586  if( !Add_Field(Get_Field_Name(iField), Get_Field_Type(iField), Position) )
587  {
588  return( false );
589  }
590 
591  if( Position < iField )
592  {
593  iField++;
594  }
595 
596  #pragma omp parallel for
597  for(sLong i=0; i<m_nRecords; i++)
598  {
599  *m_Records[i]->Get_Value(Position) = *m_Records[i]->Get_Value(iField);
600  }
601 
602  if( !Del_Field(iField) )
603  {
604  return( false );
605  }
606 
607  //-----------------------------------------------------
608  return( true );
609 }
610 
611 
613 // //
615 
616 //---------------------------------------------------------
617 bool CSG_Table::Set_Field_Name(int iField, const SG_Char *Name)
618 {
619  if( iField >= 0 && iField < m_nFields && Name && *Name )
620  {
621  *(m_Field_Name[iField]) = Name;
622 
623  Set_Modified();
624 
625  return( true );
626  }
627 
628  return( false );
629 }
630 
631 //---------------------------------------------------------
633 {
634  if( iField < 0 || iField >= m_nFields )
635  {
636  return( false );
637  }
638 
639  if( m_Field_Type[iField] == Type )
640  {
641  return( true );
642  }
643 
644  m_Field_Type[iField] = Type;
645 
646  for(sLong i=0; i<m_nRecords; i++)
647  {
648  CSG_Table_Record *pRecord = m_Records[i];
649 
651 
652  (*pValue) = *pRecord->m_Values[iField];
653 
654  delete(pRecord->m_Values[iField]);
655 
656  pRecord->m_Values[iField] = pValue;
657 
658  pRecord->Set_Modified();
659  }
660 
661  return( true );
662 }
663 
664 //---------------------------------------------------------
665 int CSG_Table::Get_Field_Length(int iField, int Encoding) const
666 {
667  size_t Length = 0;
668 
669  if( iField >= 0 && iField < m_nFields && m_Field_Type[iField] == SG_DATATYPE_String )
670  {
671  for(sLong i=0; i<m_nRecords; i++)
672  {
673  CSG_String s(m_Records[i]->asString(iField));
674 
675  size_t nBytes;
676 
677  switch( Encoding )
678  {
679  default :
680  case SG_FILE_ENCODING_UTF7 : nBytes = s.Length() ; break;
681  case SG_FILE_ENCODING_UTF8 : nBytes = s.to_UTF8().Get_Size(); break;
683  case SG_FILE_ENCODING_UTF16BE: nBytes = s.Length() * 2 ; break;
685  case SG_FILE_ENCODING_UTF32BE: nBytes = s.Length() * 4 ; break;
686  }
687 
688  if( Length < nBytes )
689  {
690  Length = nBytes;
691  }
692  }
693  }
694 
695  return( (int)Length );
696 }
697 
698 //---------------------------------------------------------
699 int CSG_Table::Get_Field(const CSG_String &Name) const
700 {
701  for(int iField=0; iField<Get_Field_Count(); iField++)
702  {
703  if( !Name.Cmp(Get_Field_Name(iField)) )
704  {
705  return( iField );
706  }
707  }
708 
709  return( -1 );
710 }
711 
712 //---------------------------------------------------------
717 int CSG_Table::Find_Field(const CSG_String &Name) const
718 {
719  for(int i=0; i<Get_Field_Count(); i++)
720  {
721  if( !Name.Cmp(Get_Field_Name(i)) )
722  {
723  return( i );
724  }
725  }
726 
727  return( -1 );
728 }
729 
730 //---------------------------------------------------------
735 bool CSG_Table::Find_Field(const CSG_String &Name, int &Index) const
736 {
737  return( (Index = Find_Field(Name)) >= 0 );
738 }
739 
740 
742 // //
743 // Records //
744 // //
746 
747 //---------------------------------------------------------
748 #define GET_GROW_SIZE(n) (n < 256 ? 1 : (n < 8192 ? 128 : 1024))
749 
750 //---------------------------------------------------------
751 bool CSG_Table::_Inc_Array(void)
752 {
753  if( m_nRecords < m_nBuffer )
754  {
755  return( true );
756  }
757 
758  CSG_Table_Record **pRecords = (CSG_Table_Record **)SG_Realloc(m_Records, (m_nBuffer + GET_GROW_SIZE(m_nBuffer)) * sizeof(CSG_Table_Record *));
759 
760  if( pRecords == NULL )
761  {
762  return( false );
763  }
764 
765  m_Records = pRecords;
767 
768  return( true );
769 }
770 
771 //---------------------------------------------------------
772 bool CSG_Table::_Dec_Array(void)
773 {
774  if( m_nRecords < 0 || m_nRecords >= m_nBuffer - GET_GROW_SIZE(m_nBuffer) )
775  {
776  return( true );
777  }
778 
779  CSG_Table_Record **pRecords = (CSG_Table_Record **)SG_Realloc(m_Records, (m_nBuffer - GET_GROW_SIZE(m_nBuffer)) * sizeof(CSG_Table_Record *));
780 
781  if( pRecords == NULL )
782  {
783  return( false );
784  }
785 
786  m_Records = pRecords;
788 
789  return( true );
790 }
791 
792 //---------------------------------------------------------
794 {
795  return( new CSG_Table_Record(this, Index) );
796 }
797 
798 //---------------------------------------------------------
800 {
801  return( Ins_Record(m_nRecords, pCopy) );
802 }
803 
804 //---------------------------------------------------------
806 {
807  if( iRecord < 0 ) { iRecord = 0; } else if( iRecord > m_nRecords ) { iRecord = m_nRecords; }
808 
809  CSG_Table_Record *pRecord = _Inc_Array() ? _Get_New_Record(m_nRecords) : NULL;
810 
811  if( pRecord )
812  {
813  if( pCopy )
814  {
815  pRecord->Assign(pCopy);
816  }
817 
818  //-------------------------------------------------
819  if( iRecord < m_nRecords )
820  {
821  if( Get_Selection_Count() > 0 ) // update selection index
822  {
823  sLong *Selection = (sLong *)m_Selection.Get_Array();
824 
825  for(sLong i=0; i<m_Selection.Get_Size(); i++)
826  {
827  if( Selection[i] > iRecord )
828  {
829  Selection[i]++;
830  }
831  }
832  }
833 
834  for(sLong i=m_nRecords; i>iRecord; i--)
835  {
836  m_Records[i] = m_Records[i - 1]; m_Records[i]->m_Index = i;
837  }
838 
839  pRecord->m_Index = iRecord;
840  }
841 
842  m_Records[iRecord] = pRecord;
843  m_nRecords++;
844 
845  //-------------------------------------------------
846  if( m_Index.is_Okay() )
847  {
848  m_Index.Add_Entry(iRecord);
849  }
850 
851  Set_Modified();
852 
853  Set_Update_Flag();
854 
856  }
857 
858  return( pRecord );
859 }
860 
861 //---------------------------------------------------------
863 {
864  if( iRecord >= 0 && iRecord < m_nRecords && pCopy )
865  {
866  return( m_Records[iRecord]->Assign(pCopy) );
867  }
868 
869  return( false );
870 }
871 
872 //---------------------------------------------------------
874 {
875  if( iRecord >= 0 && iRecord < m_nRecords )
876  {
877  if( m_Records[iRecord]->is_Selected() )
878  {
879  _Del_Selection(iRecord);
880  }
881 
882  delete(m_Records[iRecord]);
883 
884  m_nRecords--;
885 
886  for(sLong i=iRecord; i<m_nRecords; i++)
887  {
888  m_Records[i] = m_Records[i + 1]; m_Records[i]->m_Index = i;
889  }
890 
891  _Dec_Array();
892 
893  //-------------------------------------------------
894  if( m_Index.is_Okay() )
895  {
896  m_Index.Del_Entry(iRecord);
897  }
898 
899  Set_Modified();
900 
901  Set_Update_Flag();
902 
904 
905  return( true );
906  }
907 
908  return( false );
909 }
910 
911 //---------------------------------------------------------
913 {
914  Del_Index();
915 
916  for(sLong iRecord=0; iRecord<m_nRecords; iRecord++)
917  {
918  delete(m_Records[iRecord]);
919  }
920 
921  SG_FREE_SAFE(m_Records);
922 
923  m_nRecords = 0;
924  m_nBuffer = 0;
925 
926  return( true );
927 }
928 
929 //---------------------------------------------------------
931 {
932  if( m_nRecords < nRecords )
933  {
934  while( m_nRecords < nRecords && Add_Record() != NULL ) {}
935  }
936  else if( nRecords >= 0 && m_nRecords > nRecords )
937  {
938  while( m_nRecords > nRecords && Del_Record(m_nRecords - 1) ) {}
939  }
940 
941  return( m_nRecords == nRecords );
942 }
943 
944 
946 // //
948 
949 //---------------------------------------------------------
950 bool CSG_Table::Find_Record(sLong &iRecord, int iField, const CSG_String &Value, bool bCreateIndex)
951 {
952  if( iField < 0 || iField >= m_nFields || m_nRecords < 1 )
953  {
954  return( false );
955  }
956 
957  if( m_nRecords == 1 )
958  {
959  return( Value.Cmp(m_Records[iRecord = 0]->asString(iField)) == 0 );
960  }
961 
962  if( bCreateIndex && iField != Get_Index_Field(0) )
963  {
965  }
966 
967  //-----------------------------------------------------
968  if( iField != Get_Index_Field(0) )
969  {
970  for(iRecord=0; iRecord<m_nRecords; iRecord++)
971  {
972  if( Value.Cmp(m_Records[iRecord]->asString(iField)) == 0 )
973  {
974  return( true );
975  }
976  }
977  }
978 
979  //-----------------------------------------------------
980  else // indexed search
981  {
982  #define GET_RECORD(i) Get_Record_byIndex(bAscending ? (iRecord = i) : m_nRecords - 1 - (iRecord = i))
983 
984  double d; bool bAscending = Get_Index_Order(0) == TABLE_INDEX_Ascending;
985 
986  if( (d = Value.Cmp(GET_RECORD(0 )->asString(iField))) < 0 ) { return( false ); } else if( d == 0 ) { return( true ); }
987  if( (d = Value.Cmp(GET_RECORD(m_nRecords - 1)->asString(iField))) > 0 ) { return( false ); } else if( d == 0 ) { return( true ); }
988 
989  for(sLong a=0, b=m_nRecords-1; b-a > 1; )
990  {
991  d = Value.Cmp(GET_RECORD(a + (b - a) / 2)->asString(iField));
992 
993  if( d > 0. )
994  {
995  a = iRecord;
996  }
997  else if( d < 0. )
998  {
999  b = iRecord;
1000  }
1001  else
1002  {
1003  iRecord = Get_Record_byIndex(bAscending ? iRecord : m_nRecords - 1 - iRecord)->Get_Index();
1004 
1005  return( true );
1006  }
1007  }
1008 
1009  iRecord = Get_Record_byIndex(bAscending ? iRecord : m_nRecords - 1 - iRecord)->Get_Index();
1010  }
1011 
1012  //-----------------------------------------------------
1013  return( false );
1014 }
1015 
1016 //---------------------------------------------------------
1017 CSG_Table_Record * CSG_Table::Find_Record(int iField, const CSG_String &Value, bool bCreateIndex)
1018 {
1019  sLong iRecord;
1020 
1021  if( Find_Record(iRecord, iField, Value, bCreateIndex) )
1022  {
1023  return( Get_Record(iRecord) );
1024  }
1025 
1026  return( NULL );
1027 }
1028 
1029 //---------------------------------------------------------
1030 bool CSG_Table::Find_Record(sLong &iRecord, int iField, double Value, bool bCreateIndex)
1031 {
1032  if( iField < 0 || iField >= m_nFields || m_nRecords < 1 )
1033  {
1034  return( false );
1035  }
1036 
1037  if( m_nRecords == 1 )
1038  {
1039  return( Value == m_Records[iRecord = 0]->asDouble(iField) );
1040  }
1041 
1042  if( bCreateIndex && iField != Get_Index_Field(0) )
1043  {
1045  }
1046 
1047  //-----------------------------------------------------
1048  if( iField != Get_Index_Field(0) )
1049  {
1050  for(iRecord=0; iRecord<m_nRecords; iRecord++)
1051  {
1052  if( Value == m_Records[iRecord]->asDouble(iField) )
1053  {
1054  return( true );
1055  }
1056  }
1057  }
1058 
1059  //-----------------------------------------------------
1060  else // indexed search
1061  {
1062  #define GET_RECORD(i) Get_Record_byIndex(bAscending ? (iRecord = i) : m_nRecords - 1 - (iRecord = i))
1063 
1064  double d; bool bAscending = Get_Index_Order(0) == TABLE_INDEX_Ascending;
1065 
1066  if( (d = Value - GET_RECORD(0 )->asDouble(iField)) < 0. ) { return( false ); } else if( d == 0. ) { return( true ); }
1067  if( (d = Value - GET_RECORD(m_nRecords - 1)->asDouble(iField)) > 0. ) { return( false ); } else if( d == 0. ) { return( true ); }
1068 
1069  for(sLong a=0, b=m_nRecords-1; b-a > 1; )
1070  {
1071  d = Value - GET_RECORD(a + (b - a) / 2)->asDouble(iField);
1072 
1073  if( d > 0. )
1074  {
1075  a = iRecord;
1076  }
1077  else if( d < 0. )
1078  {
1079  b = iRecord;
1080  }
1081  else
1082  {
1083  iRecord = Get_Record_byIndex(bAscending ? iRecord : m_nRecords - 1 - iRecord)->Get_Index();
1084 
1085  return( true );
1086  }
1087  }
1088 
1089  iRecord = Get_Record_byIndex(bAscending ? iRecord : m_nRecords - 1 - iRecord)->Get_Index();
1090  }
1091 
1092  //-----------------------------------------------------
1093  return( false );
1094 }
1095 
1096 //---------------------------------------------------------
1097 CSG_Table_Record * CSG_Table::Find_Record(int iField, double Value, bool bCreateIndex)
1098 {
1099  sLong iRecord;
1100 
1101  if( Find_Record(iRecord, iField, Value, bCreateIndex) )
1102  {
1103  return( Get_Record(iRecord) );
1104  }
1105 
1106  return( NULL );
1107 }
1108 
1109 
1111 // //
1112 // Value Access //
1113 // //
1115 
1116 //---------------------------------------------------------
1117 void CSG_Table::Set_Modified(bool bModified)
1118 {
1119  if( bModified != is_Modified() )
1120  {
1121  CSG_Data_Object::Set_Modified(bModified);
1122 
1123  if( bModified == false )
1124  {
1125  #pragma omp parallel for
1126  for(sLong iRecord=0; iRecord<m_nRecords; iRecord++)
1127  {
1128  m_Records[iRecord]->Set_Modified(false);
1129  }
1130  }
1131  }
1132 }
1133 
1134 //---------------------------------------------------------
1135 bool CSG_Table::Set_Value(sLong iRecord, int iField, const SG_Char *Value)
1136 {
1137  if( iField >= 0 && iField < m_nFields )
1138  {
1139  CSG_Table_Record *pRecord = Get_Record(iRecord);
1140 
1141  return( pRecord && pRecord->Set_Value(iField, Value) );
1142  }
1143 
1144  return( false );
1145 }
1146 
1147 //---------------------------------------------------------
1148 bool CSG_Table::Set_Value(sLong iRecord, int iField, double Value)
1149 {
1150  if( iField >= 0 && iField < m_nFields )
1151  {
1152  CSG_Table_Record *pRecord = Get_Record(iRecord);
1153 
1154  return( pRecord && pRecord->Set_Value(iField, Value) );
1155  }
1156 
1157  return( false );
1158 }
1159 
1160 //---------------------------------------------------------
1161 bool CSG_Table::Get_Value(sLong iRecord, int iField, CSG_String &Value) const
1162 {
1163  if( iField >= 0 && iField < m_nFields )
1164  {
1165  CSG_Table_Record *pRecord = Get_Record(iRecord);
1166 
1167  if( pRecord )
1168  {
1169  Value = pRecord->asString(iField);
1170 
1171  return( true );
1172  }
1173  }
1174 
1175  return( false );
1176 }
1177 
1178 //---------------------------------------------------------
1179 bool CSG_Table::Get_Value(sLong iRecord, int iField, double &Value) const
1180 {
1181  if( iField >= 0 && iField < m_nFields )
1182  {
1183  CSG_Table_Record *pRecord = Get_Record(iRecord);
1184 
1185  if( pRecord )
1186  {
1187  Value = pRecord->asDouble(iField);
1188 
1189  return( true );
1190  }
1191  }
1192 
1193  return( false );
1194 }
1195 
1196 
1198 // //
1199 // Statistics //
1200 // //
1202 
1203 //---------------------------------------------------------
1205 {
1206  for(int iField=0; iField<m_nFields; iField++)
1207  {
1208  m_Field_Stats[iField]->Invalidate();
1209  }
1210 
1211  return( true );
1212 }
1213 
1214 //---------------------------------------------------------
1215 bool CSG_Table::_Stats_Invalidate(int iField) const
1216 {
1217  if( iField >= 0 && iField < m_nFields )
1218  {
1219  m_Field_Stats[iField]->Invalidate();
1220 
1221  return( true );
1222  }
1223 
1224  return( false );
1225 }
1226 
1227 //---------------------------------------------------------
1228 bool CSG_Table::_Stats_Update(int iField) const
1229 {
1230  if( iField < 0 || iField >= m_nFields || Get_Count() < 1 )
1231  {
1232  return( false );
1233  }
1234 
1235  CSG_Simple_Statistics &Statistics = *m_Field_Stats[iField];
1236 
1237  if( Statistics.is_Evaluated() )
1238  {
1239  return( true );
1240  }
1241 
1242  if( Get_Max_Samples() > 0 && Get_Max_Samples() < Get_Count() )
1243  {
1244  double d = (double)Get_Count() / (double)Get_Max_Samples();
1245 
1246  for(double i=0; i<(double)Get_Count(); i+=d)
1247  {
1248  CSG_Table_Record *pRecord = m_Records[(sLong)i];
1249 
1250  if( !pRecord->is_NoData(iField) )
1251  {
1252  Statistics += pRecord->asDouble(iField);
1253  }
1254  }
1255 
1256  Statistics.Set_Count(Statistics.Get_Count() >= Get_Max_Samples() ? Get_Count() // any no-data cells ?
1257  : (sLong)(Get_Count() * (double)Statistics.Get_Count() / (double)Get_Max_Samples())
1258  );
1259  }
1260  else
1261  {
1262  for(sLong i=0; i<Get_Count(); i++)
1263  {
1264  CSG_Table_Record *pRecord = m_Records[i];
1265 
1266  if( !pRecord->is_NoData(iField) )
1267  {
1268  Statistics += pRecord->asDouble(iField);
1269  }
1270  }
1271  }
1272 
1273  return( Statistics.Evaluate() ); // evaluate! prevent values to be added more than once!
1274 }
1275 
1276 
1278 // //
1279 // //
1280 // //
1282 
1283 //---------------------------------------------------------
1285 {
1287 
1289 }
1290 
1291 //---------------------------------------------------------
1293 {
1295 
1296  if( m_Index.is_Okay() )
1297  {
1298  _Index_Update();
1299  }
1300 
1301  return( CSG_Data_Object::On_Update() );
1302 }
1303 
1304 
1306 // //
1307 // Index //
1308 // //
1310 
1311 //---------------------------------------------------------
1312 bool CSG_Table::Set_Index(int Field_1, TSG_Table_Index_Order Order_1, int Field_2, TSG_Table_Index_Order Order_2, int Field_3, TSG_Table_Index_Order Order_3)
1313 {
1314  m_Index_Fields.Destroy();
1315 
1316  if( Field_1 >= 0 && Field_1 < m_nFields && Order_1 != TABLE_INDEX_None )
1317  {
1318  Field_1++; m_Index_Fields += Order_1 == TABLE_INDEX_Ascending ? Field_1 : -Field_1;
1319 
1320  if( Field_2 >= 0 && Field_2 < m_nFields && Order_2 != TABLE_INDEX_None )
1321  {
1322  Field_2++; m_Index_Fields += Order_2 == TABLE_INDEX_Ascending ? Field_2 : -Field_2;
1323 
1324  if( Field_3 >= 0 && Field_3 < m_nFields && Order_3 != TABLE_INDEX_None )
1325  {
1326  Field_3++; m_Index_Fields += Order_3 == TABLE_INDEX_Ascending ? Field_3 : -Field_3;
1327  }
1328  }
1329 
1330  _Index_Update();
1331  }
1332  else
1333  {
1334  Del_Index();
1335  }
1336 
1337  return( is_Indexed() );
1338 }
1339 
1340 //---------------------------------------------------------
1342 {
1343  m_Index.Destroy();
1344 
1345  m_Index_Fields.Destroy();
1346 
1347  return( true );
1348 }
1349 
1350 //---------------------------------------------------------
1351 bool CSG_Table::Toggle_Index(int iField)
1352 {
1353  if( iField < 0 || iField >= m_nFields )
1354  {
1355  return( false );
1356  }
1357 
1358  if( iField != Get_Index_Field(0) )
1359  {
1360  return( Set_Index(iField, TABLE_INDEX_Ascending) );
1361  }
1362 
1364  {
1365  return( Set_Index(iField, TABLE_INDEX_Descending) );
1366  }
1367 
1368  return( Del_Index() );
1369 }
1370 
1371 
1373 // //
1375 
1376 //---------------------------------------------------------
1377 class CSG_Table_Record_Compare_Field : public CSG_Index::CSG_Index_Compare
1378 {
1379 public:
1380  CSG_Table_Record_Compare_Field(const CSG_Table *pTable, int Field, bool Ascending)
1381  {
1382  m_pTable = pTable;
1383  m_Field = Field;
1384  m_Ascending = Ascending;
1385 
1386  if( !m_pTable || m_Field < 0 || m_Field >= m_pTable->Get_Field_Count() )
1387  {
1388  m_pTable = NULL;
1389  }
1390  }
1391 
1392  bool is_Okay (void) const { return( m_pTable != NULL ); }
1393 
1394  virtual int Compare (const sLong _a, const sLong _b)
1395  {
1396  sLong a = m_Ascending ? _a : _b;
1397  sLong b = m_Ascending ? _b : _a;
1398 
1399  switch( m_pTable->Get_Field_Type(m_Field) )
1400  {
1401  default: {
1402  double d =
1403  m_pTable->Get_Record(a)->asDouble(m_Field) -
1404  m_pTable->Get_Record(b)->asDouble(m_Field);
1405 
1406  return( d < 0. ? -1 : d > 0. ? 1 : 0 );
1407  }
1408 
1409  case SG_DATATYPE_String:
1410  case SG_DATATYPE_Date :
1411  return( SG_STR_CMP(
1412  m_pTable->Get_Record(a)->asString(m_Field),
1413  m_pTable->Get_Record(b)->asString(m_Field))
1414  );
1415  }
1416  }
1417 
1418 
1419 private:
1420 
1421  bool m_Ascending;
1422 
1423  int m_Field;
1424 
1425  const CSG_Table *m_pTable;
1426 
1427 };
1428 
1429 //---------------------------------------------------------
1430 bool CSG_Table::Set_Index(CSG_Index &Index, int Field, bool bAscending) const
1431 {
1432  CSG_Table_Record_Compare_Field Compare(this, Field, bAscending);
1433 
1434  return( Compare.is_Okay() && Index.Create(Get_Count(), &Compare) );
1435 }
1436 
1437 
1439 // //
1441 
1442 //---------------------------------------------------------
1443 class CSG_Table_Record_Compare_Fields : public CSG_Index::CSG_Index_Compare
1444 {
1445 public:
1446  CSG_Table_Record_Compare_Fields(const CSG_Table *pTable, int Fields[], int nFields, bool Ascending)
1447  : m_pTable(pTable), m_Fields(Fields), m_nFields(nFields)
1448  {
1449  m_Ascending.Create(nFields);
1450 
1451  for(int i=0; m_pTable && i<m_nFields; i++)
1452  {
1453  if( m_Fields[i] >= m_pTable->Get_Field_Count() )
1454  {
1455  m_pTable = NULL;
1456  }
1457 
1458  m_Ascending[i] = Ascending ? 1 : 0;
1459  }
1460  }
1461 
1462  CSG_Table_Record_Compare_Fields(const CSG_Table *pTable, int Fields[], int nFields, int Ascending[])
1463  : m_pTable(pTable), m_Fields(Fields), m_nFields(nFields)
1464  {
1465  m_Ascending.Create(nFields);
1466 
1467  for(int i=0; m_pTable && i<m_nFields; i++)
1468  {
1469  if( m_Fields[i] >= m_pTable->Get_Field_Count() )
1470  {
1471  m_pTable = NULL;
1472  }
1473 
1474  m_Ascending[i] = Ascending[i] > 0 ? 1 : 0;
1475  }
1476  }
1477 
1478  bool is_Okay (void) const { return( m_pTable != NULL ); }
1479 
1480  virtual int Compare (const sLong _a, const sLong _b)
1481  {
1482  int Difference = 0;
1483 
1484  for(int i=0; !Difference && i<m_nFields; i++)
1485  {
1486  int Field = m_Fields[i];
1487 
1488  sLong a = m_Ascending[i] ? _a : _b;
1489  sLong b = m_Ascending[i] ? _b : _a;
1490 
1491  switch( m_pTable->Get_Field_Type(Field) )
1492  {
1493  default: {
1494  double d = m_pTable->Get_Record(a)->asDouble(Field);
1495  d -= m_pTable->Get_Record(b)->asDouble(Field);
1496  Difference = d < 0. ? -1 : d > 0. ? 1 : 0;
1497  } break;
1498 
1499  case SG_DATATYPE_String:
1500  case SG_DATATYPE_Date :
1501  CSG_String s (m_pTable->Get_Record(a)->asString(Field));
1502  Difference = s.Cmp(m_pTable->Get_Record(b)->asString(Field));
1503  break;
1504  }
1505  }
1506 
1507  return( Difference );
1508  }
1509 
1510 
1511 private:
1512 
1513  int *m_Fields, m_nFields;
1514 
1515  CSG_Array_Int m_Ascending;
1516 
1517  const CSG_Table *m_pTable;
1518 
1519 };
1520 
1521 //---------------------------------------------------------
1522 bool CSG_Table::Set_Index(CSG_Index &Index, int Fields[], int nFields, bool bAscending) const
1523 {
1524  CSG_Table_Record_Compare_Fields Compare(this, Fields, nFields, bAscending);
1525 
1526  return( Compare.is_Okay() && Index.Create(Get_Count(), &Compare) );
1527 }
1528 
1529 //---------------------------------------------------------
1530 bool CSG_Table::Set_Index(CSG_Index &Index, const CSG_Array_Int &Fields, bool bAscending) const
1531 {
1532  return( Set_Index(Index, Fields.Get_Array(), (int)Fields.Get_Size(), bAscending) );
1533 }
1534 
1535 //---------------------------------------------------------
1536 void CSG_Table::_Index_Update(void)
1537 {
1538  if( m_Index_Fields.Get_Size() < 1 )
1539  {
1540  Del_Index();
1541  }
1542 
1543  CSG_Array_Int Fields, Ascending;
1544 
1545  for(sLong i=0; i<m_Index_Fields.Get_Size(); i++)
1546  {
1547  Fields += abs(m_Index_Fields[i]) - 1;
1548  Ascending += m_Index_Fields[i] > 0 ? 1 : 0;
1549  }
1550 
1551  CSG_Table_Record_Compare_Fields Compare(this, Fields.Get_Array(), (int)Fields.Get_Size(), Ascending.Get_Array());
1552 
1553  if( !Compare.is_Okay() || !m_Index.Create(Get_Count(), &Compare) )
1554  {
1555  Del_Index();
1556  }
1557 }
1558 
1559 
1561 // //
1562 // //
1563 // //
1565 
1566 //---------------------------------------------------------
CSG_Index
Definition: mat_tools.h:185
CSG_Table::CSG_Table_Record
friend class CSG_Table_Record
Definition: table.h:284
CSG_String::BeforeFirst
CSG_String BeforeFirst(char Character) const
Definition: api_string.cpp:666
CSG_Table::Find_Record
virtual bool Find_Record(sLong &Index, int iField, const CSG_String &Value, bool bCreateIndex=false)
Definition: table.cpp:950
CSG_Table_Record::asDouble
double asDouble(int Field) const
Definition: table_record.cpp:527
CSG_Index::is_Okay
bool is_Okay(void) const
Definition: mat_tools.h:223
CSG_Table::Assign
virtual bool Assign(CSG_Data_Object *pTable)
Definition: table.cpp:372
CSG_Data_Object::Get_Max_Samples
sLong Get_Max_Samples(void) const
Definition: dataobject.h:254
SG_FREE_SAFE
#define SG_FREE_SAFE(PTR)
Definition: api_core.h:205
SG_Create_Table
CSG_Table * SG_Create_Table(void)
Definition: table.cpp:65
CSG_Table::Set_Count
virtual bool Set_Count(sLong nRecords)
Definition: table.cpp:930
SG_DATATYPE_String
@ SG_DATATYPE_String
Definition: api_core.h:997
_TL
#define _TL(s)
Definition: api_core.h:1480
CSG_Table::Del_Records
virtual bool Del_Records(void)
Definition: table.cpp:912
CSG_Array::Get_Size
sLong Get_Size(void) const
Definition: api_core.h:327
CSG_Data_Object::Set_File_Name
void Set_File_Name(const CSG_String &FileName)
Definition: dataobject.cpp:307
CSG_String::Length
size_t Length(void) const
Definition: api_string.cpp:172
TABLE_INDEX_None
@ TABLE_INDEX_None
Definition: table.h:104
CSG_Data_Object::Get_Description
const SG_Char * Get_Description(void) const
Definition: dataobject.cpp:301
CSG_Table_Record
Definition: table.h:130
CSG_Table::_Stats_Update
virtual bool _Stats_Update(int iField) const
Definition: table.cpp:1228
CSG_Data_Object::Get_NoData_Value
double Get_NoData_Value(bool bUpper=false) const
Definition: dataobject.h:244
CSG_Table::Get_ObjectType
virtual TSG_Data_Object_Type Get_ObjectType(void) const
Returns the object type as defined by TSG_Data_Object_Type. Used for run time type checking.
Definition: table.h:315
CSG_Table::Get_Value
virtual bool Get_Value(sLong Index, int iField, CSG_String &Value) const
Definition: table.cpp:1161
SG_UI_MSG_STYLE_SUCCESS
@ SG_UI_MSG_STYLE_SUCCESS
Definition: api_core.h:1496
CSG_Index::CSG_Index_Compare
Definition: mat_tools.h:188
CSG_Table::m_Selection
CSG_Array m_Selection
Definition: table.h:452
CSG_Table::is_Selected
virtual bool is_Selected(sLong Index) const
Definition: table.h:417
CSG_Table::Del_Field
virtual bool Del_Field(int iField)
Definition: table.cpp:526
CSG_Table::Get_Record
virtual CSG_Table_Record * Get_Record(sLong Index) const
Definition: table.h:387
GET_GROW_SIZE
#define GET_GROW_SIZE(n)
Definition: table.cpp:748
CSG_Array_Int::Get_Size
sLong Get_Size(void) const
Definition: api_core.h:434
CSG_Table::m_Field_Name
CSG_String ** m_Field_Name
Definition: table.h:448
CSG_Table::operator=
CSG_Table & operator=(const CSG_Table &Table)
Definition: table.cpp:364
CSG_Table_Record::Assign
virtual bool Assign(CSG_Table_Record *pRecord)
Definition: table_record.cpp:543
CSG_Table::~CSG_Table
virtual ~CSG_Table(void)
Definition: table.cpp:321
CSG_Tool
Definition: tool.h:149
CSG_Index::CSG_Index_Compare::Compare
virtual int Compare(const sLong a, const sLong b)=0
CSG_Table::Destroy
virtual bool Destroy(void)
Definition: table.cpp:327
CSG_Data_Object::Get_Name
const SG_Char * Get_Name(void) const
Definition: dataobject.cpp:290
CSG_Tool::Execute
bool Execute(bool bAddHistory=false)
Definition: tool.cpp:246
SG_FILE_ENCODING_UTF32BE
@ SG_FILE_ENCODING_UTF32BE
Definition: api_core.h:550
CSG_Table::CSG_Table
CSG_Table(void)
Definition: table.cpp:133
CSG_Table::Get_Index_Order
TSG_Table_Index_Order Get_Index_Order(int i) const
Definition: table.h:435
CSG_Table::Get_Field_Count
int Get_Field_Count(void) const
Definition: table.h:355
CSG_Array_Int::Get_Array
int * Get_Array(void) const
Definition: api_core.h:437
CSG_Simple_Statistics::Evaluate
bool Evaluate(void)
Definition: mat_tools.cpp:473
SG_Free
SAGA_API_DLL_EXPORT void SG_Free(void *memblock)
Definition: api_memory.cpp:83
CSG_Data_Object::Get_ObjectType
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.
SG_STR_CMP
#define SG_STR_CMP(s1, s2)
Definition: api_core.h:538
CSG_Table::Get_Field_Length
int Get_Field_Length(int iField, int Encoding=SG_FILE_ENCODING_UNDEFINED) const
Definition: table.cpp:665
CSG_Table_Record::m_Values
class CSG_Table_Value ** m_Values
Definition: table.h:256
CSG_Table::Set_Record
virtual bool Set_Record(sLong Index, CSG_Table_Record *pCopy)
Definition: table.cpp:862
CSG_Table_Value
Definition: table_value.h:111
CSG_Table_Record::m_Index
sLong m_Index
Definition: table.h:254
CSG_Tool_Library_Manager::Delete_Tool
bool Delete_Tool(CSG_Tool *pTool) const
Definition: tool_library.cpp:726
CSG_Data_Object::Set_Update_Flag
void Set_Update_Flag(bool bOn=true)
Definition: dataobject.h:273
CSG_Table_Record::is_NoData
bool is_NoData(int Field) const
Definition: table_record.cpp:416
CSG_Table::Set_Modified
virtual void Set_Modified(bool bModified=true)
Definition: table.cpp:1117
CSG_String::Cmp
int Cmp(const CSG_String &String) const
Definition: api_string.cpp:515
SG_FILE_ENCODING_UTF7
@ SG_FILE_ENCODING_UTF7
Definition: api_core.h:545
CSG_Table::_Stats_Invalidate
bool _Stats_Invalidate(void) const
Definition: table.cpp:1204
CSG_Table::m_Field_Type
TSG_Data_Type * m_Field_Type
Definition: table.h:446
CSG_Table::Find_Field
int Find_Field(const CSG_String &Name) const
Definition: table.cpp:717
SG_UI_MSG_STYLE_FAILURE
@ SG_UI_MSG_STYLE_FAILURE
Definition: api_core.h:1497
CSG_Table::is_Compatible
bool is_Compatible(const CSG_Table &Table, bool bExactMatch=false) const
Definition: table.cpp:436
SG_File_Exists
SAGA_API_DLL_EXPORT bool SG_File_Exists(const CSG_String &FileName)
Definition: api_file.cpp:834
SG_TOOL_PARAMETER_SET
#define SG_TOOL_PARAMETER_SET(IDENTIFIER, VALUE)
Definition: tool_library.h:351
CSG_Table::m_Field_Stats
CSG_Simple_Statistics ** m_Field_Stats
Definition: table.h:450
CSG_Table_Record::asString
const SG_Char * asString(int Field, int Decimals=-99) const
Definition: table_record.cpp:461
CSG_Data_Object
Definition: dataobject.h:180
CSG_Data_Object::On_NoData_Changed
virtual bool On_NoData_Changed(void)
Definition: dataobject.cpp:542
CSG_Table::Get_Field_Name
const SG_Char * Get_Field_Name(int iField) const
Definition: table.h:356
CSG_Simple_Statistics::Get_Count
sLong Get_Count(void) const
Definition: mat_tools.h:728
CSG_Table::Get_Selection_Count
sLong Get_Selection_Count(void) const
Definition: table.h:413
CSG_Index::Create
bool Create(sLong nValues, CSG_Index_Compare &Compare)
Definition: mat_indexing.cpp:110
CSG_Tool_Library_Manager::Create_Tool
CSG_Tool * Create_Tool(const CSG_String &Library, int Index, bool bWithGUI=false) const
Definition: tool_library.cpp:697
TSG_Table_Index_Order
TSG_Table_Index_Order
Definition: table.h:103
sLong
signed long long sLong
Definition: api_core.h:158
SG_Get_Tool_Library_Manager
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)
Definition: tool_library.cpp:286
CSG_Data_Object::On_Update
virtual bool On_Update(void)
Definition: dataobject.h:275
CSG_Table::is_Indexed
bool is_Indexed(void) const
Definition: table.h:430
CSG_Table::On_NoData_Changed
virtual bool On_NoData_Changed(void)
Definition: table.cpp:1284
SG_FILE_ENCODING_UTF32LE
@ SG_FILE_ENCODING_UTF32LE
Definition: api_core.h:549
CSG_Table::Mov_Field
virtual bool Mov_Field(int iField, int Position)
Definition: table.cpp:564
CSG_Table::Get_Count
sLong Get_Count(void) const
Definition: table.h:385
CSG_Table_Record::_Create_Value
static CSG_Table_Value * _Create_Value(TSG_Data_Type Type)
Definition: table_record.cpp:110
CSG_Table::On_Update
virtual bool On_Update(void)
Definition: table.cpp:1292
CSG_Data_Object::is_Modified
virtual bool is_Modified(void) const
Definition: dataobject.h:219
CSG_Simple_Statistics::Invalidate
void Invalidate(void)
Definition: mat_tools.cpp:447
CSG_Table::Assign_Values
bool Assign_Values(const CSG_Table &Table)
Definition: table.cpp:401
CSG_Array_Int
Definition: api_core.h:421
CSG_Simple_Statistics::is_Evaluated
int is_Evaluated(void) const
Definition: mat_tools.h:724
CSG_Table::Get_Index_Field
int Get_Index_Field(int i) const
Definition: table.h:434
CSG_Table::Del_Index
bool Del_Index(void)
Definition: table.cpp:1341
CSG_Table::m_nBuffer
sLong m_nBuffer
Definition: table.h:444
CSG_Data_Object::Set_Modified
virtual void Set_Modified(bool bOn=true)
Definition: dataobject.h:218
CSG_Array::Create
void * Create(const CSG_Array &Array)
Definition: api_memory.cpp:250
CSG_Table::Set_Value
virtual bool Set_Value(sLong Index, int iField, const SG_Char *Value)
Definition: table.cpp:1135
CSG_Array::Get_Array
void * Get_Array(void) const
Definition: api_core.h:336
CSG_Table::Get_Record_byIndex
CSG_Table_Record * Get_Record_byIndex(sLong Index) const
Definition: table.h:392
SG_DATATYPE_Date
@ SG_DATATYPE_Date
Definition: api_core.h:998
CSG_Table_Record::_Add_Field
bool _Add_Field(int add_Field)
Definition: table_record.cpp:143
CSG_Data_Object::Set_Name
void Set_Name(const CSG_String &Name)
Definition: dataobject.cpp:235
CSG_Table::m_Encoding
int m_Encoding
Definition: table.h:442
CSG_Table_Record::Set_Modified
void Set_Modified(bool bOn=true)
Definition: table_record.cpp:220
CSG_Index::Add_Entry
bool Add_Entry(sLong Position=-1)
Definition: mat_indexing.cpp:268
CSG_Simple_Statistics::Set_Count
bool Set_Count(sLong Count)
Definition: mat_tools.cpp:424
CSG_String::Format
static CSG_String Format(const char *Format,...)
Definition: api_string.cpp:270
CSG_Table::_Del_Selection
bool _Del_Selection(sLong Index)
Definition: table_selection.cpp:87
SG_FILE_ENCODING_UTF16LE
@ SG_FILE_ENCODING_UTF16LE
Definition: api_core.h:547
CSG_Table::Set_Field_Name
bool Set_Field_Name(int iField, const SG_Char *Name)
Definition: table.cpp:617
CSG_Table::Add_Field
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Position=-1)
Definition: table.cpp:487
CSG_Table
Definition: table.h:283
CSG_String::to_UTF8
size_t to_UTF8(char **pString) const
Definition: api_string.cpp:813
SG_DATAOBJECT_TYPE_Shapes
@ SG_DATAOBJECT_TYPE_Shapes
Definition: dataobject.h:121
TABLE_INDEX_Descending
@ TABLE_INDEX_Descending
Definition: table.h:106
CSG_String::AfterFirst
CSG_String AfterFirst(char Character) const
Definition: api_string.cpp:644
CSG_Table::Del_Record
virtual bool Del_Record(sLong Index)
Definition: table.cpp:873
SG_Char
#define SG_Char
Definition: api_core.h:530
CSG_Table::Load
bool Load(const CSG_String &File, int Format, SG_Char Separator, int Encoding=SG_FILE_ENCODING_UNDEFINED)
Definition: table_io.cpp:99
CSG_Table::Create
bool Create(const CSG_Table &Table)
Definition: table.cpp:146
shapes.h
CSG_String
Definition: api_core.h:557
CSG_Tool::Set_Manager
bool Set_Manager(class CSG_Data_Manager *pManager)
Definition: tool.cpp:549
SG_DATAOBJECT_TYPE_Table
@ SG_DATAOBJECT_TYPE_Table
Definition: dataobject.h:120
CSG_Data_Object::Set_Description
void Set_Description(const CSG_String &Description)
Definition: dataobject.cpp:296
CSG_String::is_Empty
bool is_Empty(void) const
Definition: api_string.cpp:178
SG_FILE_ENCODING_UTF16BE
@ SG_FILE_ENCODING_UTF16BE
Definition: api_core.h:548
CSG_Data_Object::Get_MetaData
CSG_MetaData & Get_MetaData(void) const
Definition: dataobject.h:225
TSG_Table_File_Type
TSG_Table_File_Type
Definition: table.h:93
CSG_Table_Record::Set_Value
bool Set_Value(int Field, const CSG_String &Value)
Definition: table_record.cpp:270
CSG_Table::m_nFields
int m_nFields
Definition: table.h:442
GET_RECORD
#define GET_RECORD(i)
CSG_Table::Ins_Record
virtual CSG_Table_Record * Ins_Record(sLong Index, CSG_Table_Record *pCopy=NULL)
Definition: table.cpp:805
CSG_Table_Record::Get_Index
sLong Get_Index(void) const
Definition: table.h:136
TABLE_INDEX_Ascending
@ TABLE_INDEX_Ascending
Definition: table.h:105
CSG_Tool::On_Before_Execution
virtual bool On_Before_Execution(void)
Definition: tool.h:239
CSG_Shapes
Definition: shapes.h:773
SG_UI_ProgressAndMsg_Lock
void SG_UI_ProgressAndMsg_Lock(bool bOn)
Definition: api_callback.cpp:577
CSG_String::c_str
const SG_Char * c_str(void) const
Definition: api_string.cpp:236
tool_library.h
CSG_Table_Record::Get_Value
CSG_Table_Value * Get_Value(int Field)
Definition: table.h:237
TSG_Data_Type
TSG_Data_Type
Definition: api_core.h:985
SG_Realloc
SAGA_API_DLL_EXPORT void * SG_Realloc(void *memblock, size_t size)
Definition: api_memory.cpp:77
CSG_Table::Set_Index
bool Set_Index(CSG_Index &Index, int Field, bool bAscending=true) const
Definition: table.cpp:1430
CSG_Table::Get_Field_Type
TSG_Data_Type Get_Field_Type(int iField) const
Definition: table.h:357
CSG_Table::Add_Record
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
Definition: table.cpp:799
CSG_Index::Del_Entry
bool Del_Entry(sLong Position=-1)
Definition: mat_indexing.cpp:289
CSG_Table::Get_Field
int Get_Field(const CSG_String &Name) const
Definition: table.cpp:699
CSG_Array_Int::Destroy
void Destroy(void)
Definition: api_core.h:429
SG_FILE_ENCODING_UTF8
@ SG_FILE_ENCODING_UTF8
Definition: api_core.h:546
CSG_Simple_Statistics
Definition: mat_tools.h:708
CSG_Data_Object::Set_NoData_Value_Range
virtual bool Set_NoData_Value_Range(double Lower, double Upper)
Definition: dataobject.cpp:519
CSG_Table::Set_Field_Type
virtual bool Set_Field_Type(int iField, TSG_Data_Type Type)
Definition: table.cpp:632
table.h
CSG_Index::Destroy
bool Destroy(void)
Definition: mat_indexing.cpp:83
CSG_Data_Object::Destroy
virtual bool Destroy(void)
Definition: dataobject.cpp:218
CSG_Table::Toggle_Index
bool Toggle_Index(int iField)
Definition: table.cpp:1351
CSG_Table::_Get_New_Record
virtual CSG_Table_Record * _Get_New_Record(sLong Index)
Definition: table.cpp:793
SG_DATAOBJECT_TYPE_PointCloud
@ SG_DATAOBJECT_TYPE_PointCloud
Definition: dataobject.h:123
CSG_Table::m_nRecords
sLong m_nRecords
Definition: table.h:444
CSG_Data_Object::is_Valid
virtual bool is_Valid(void) const =0
SG_UI_Msg_Add
void SG_UI_Msg_Add(const char *Message, bool bNewLine, TSG_UI_MSG_STYLE Style)
Definition: api_callback.cpp:490
CSG_Table_Record::_Del_Field
bool _Del_Field(int del_Field)
Definition: table_record.cpp:167
CSG_Table::_On_Construction
virtual void _On_Construction(void)
Definition: table.cpp:297
SG_Create_Shapes
CSG_Shapes * SG_Create_Shapes(void)
Definition: shapes.cpp:85