SAGA API  v9.7
pointcloud.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 // pointcloud.cpp //
15 // //
16 // Copyright (C) 2009 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Hamburg //
44 // Germany //
45 // //
46 // e-mail: oconrad@saga-gis.org //
47 // //
49 
50 //---------------------------------------------------------
51 #include "pointcloud.h"
52 
53 
55 // //
56 // //
57 // //
59 
60 //---------------------------------------------------------
61 #define PC_FILE_VERSION "SGPC01"
62 
63 #define PC_STR_NBYTES 32
64 #define PC_DAT_NBYTES 32
65 
66 #define PC_GET_NBYTES(type) (type == SG_DATATYPE_String ? PC_STR_NBYTES : type == SG_DATATYPE_Date ? PC_DAT_NBYTES : (int)SG_Data_Type_Get_Size(type))
67 
68 
70 // //
71 // //
72 // //
74 
75 //---------------------------------------------------------
77 {
78  return( new CSG_PointCloud );
79 }
80 
81 //---------------------------------------------------------
83 {
84  return( new CSG_PointCloud(PointCloud) );
85 }
86 
87 //---------------------------------------------------------
88 CSG_PointCloud * SG_Create_PointCloud(const char *File) { return( SG_Create_PointCloud(CSG_String(File)) ); }
89 CSG_PointCloud * SG_Create_PointCloud(const wchar_t *File) { return( SG_Create_PointCloud(CSG_String(File)) ); }
91 {
92  CSG_PointCloud *pPoints = new CSG_PointCloud();
93 
94  if( pPoints->Create(File) )
95  {
96  return( pPoints );
97  }
98 
99  delete(pPoints); return( NULL );
100 }
101 
102 //---------------------------------------------------------
104 {
105  return( new CSG_PointCloud(pStructure) );
106 }
107 
108 
110 // //
111 // //
112 // //
114 
115 //---------------------------------------------------------
117  : CSG_Shapes()
118 {
120 
121  Create();
122 }
123 
125 {
126  Destroy();
127 
128  Add_Field("", SG_DATATYPE_Undefined); // add x, y, z fields
129 
130  return( true );
131 }
132 
133 //---------------------------------------------------------
135  : CSG_Shapes()
136 {
138 }
139 
141 {
142  return( Assign((CSG_Data_Object *)&PointCloud) );
143 }
144 
145 //---------------------------------------------------------
149  : CSG_Shapes()
150 {
151  _On_Construction(); Create(File);
152 }
153 
154 bool CSG_PointCloud::Create(const char *File) { return( Create(CSG_String(File)) ); }
155 bool CSG_PointCloud::Create(const wchar_t *File) { return( Create(CSG_String(File)) ); }
157 {
158  return( _Load(File) );
159 }
160 
161 //---------------------------------------------------------
163  : CSG_Shapes()
164 {
165  _On_Construction(); Create(pTemplate);
166 }
167 
169 {
170  Destroy();
171 
172  if( pTemplate && pTemplate->m_nFields > 0 )
173  {
174  for(int iField=0; iField<pTemplate->m_nFields; iField++)
175  {
176  _Add_Field(pTemplate->Get_Field_Name(iField), pTemplate->Get_Field_Type(iField));
177  }
178 
179  return( true );
180  }
181 
182  return( false );
183 }
184 
185 //---------------------------------------------------------
187 {
190 
191  m_nFields = 0;
192  m_Field_Name = NULL;
193  m_Field_Type = NULL;
194  m_Field_Stats = NULL;
195  m_Field_Offset = NULL;
196 
197  m_Points = NULL;
198  m_nRecords = 0;
199  m_nPointBytes = 0;
200 
201  m_Cursor = NULL;
202  m_bXYZPrecDbl = true;
203 
204  Set_NoData_Value(-999999);
205 
206  Set_Update_Flag();
207 
208  m_Shapes.Create(SHAPE_TYPE_Point, NULL, NULL, SG_VERTEX_TYPE_XYZ);
210  for(sLong i=0; i<m_Shapes.Get_Count(); i++)
211  {
212  m_Shapes[i].m_Index = -1;
213  }
214 
215  m_Array_Points.Create(sizeof(char *), 0, TSG_Array_Growth::SG_ARRAY_GROWTH_3);
216 }
217 
218 //---------------------------------------------------------
220 {
221  Destroy();
222 }
223 
225 {
226  Del_Points();
227 
228  if( m_nFields > 0 )
229  {
230  for(int iField=0; iField<m_nFields; iField++)
231  {
232  delete(m_Field_Name [iField]);
233  delete(m_Field_Stats[iField]);
234  }
235 
239  SG_Free(m_Field_Offset);
240 
242  }
243 
245 
246  return( true );
247 }
248 
249 
251 // //
252 // File //
253 // //
255 
256 //---------------------------------------------------------
257 bool CSG_PointCloud::_Load(const CSG_String &File)
258 {
259  SG_UI_Msg_Add(CSG_String::Format("%s %s: %s...", _TL("Loading"), _TL("point cloud"), File.c_str()), true);
260 
261  bool bResult = false;
262 
263  if( SG_File_Cmp_Extension(File, "sg-pts-z") ) // POINTCLOUD_FILE_FORMAT_Compressed
264  {
265  CSG_Archive Stream(File, SG_FILE_R);
266 
267  CSG_String _File(SG_File_Get_Name(File, false) + ".");
268 
269  if( (bResult = Stream.Get_File(_File + "sg-pts")) == false )
270  {
271  for(size_t i=0; i<Stream.Get_File_Count(); i++)
272  {
273  if( SG_File_Cmp_Extension(Stream.Get_File_Name(i), "sg-pts") )
274  {
275  _File = SG_File_Get_Name(Stream.Get_File_Name(i), false) + ".";
276 
277  break;
278  }
279  }
280 
281  bResult = Stream.Get_File(_File + "sg-pts");
282  }
283 
284  if( bResult && _Load(Stream) )
285  {
286  if( Stream.Get_File(_File + "sg-info") )
287  {
288  Load_MetaData(Stream);
289  }
290 
291  if( Stream.Get_File(_File + "sg-prj") )
292  {
293  Get_Projection().Load(Stream);
294  }
295  }
296  }
297  else // if( SG_File_Cmp_Extension(File, "sg-pts"/"spc") ) // POINTCLOUD_FILE_FORMAT_Normal
298  {
299  CSG_File Stream(File, SG_FILE_R, true);
300 
301  if( (bResult = _Load(Stream)) == true )
302  {
303  Load_MetaData(File);
304 
305  Get_Projection().Load(SG_File_Make_Path("", File, "sg-prj"));
306  }
307  }
308 
309  //-----------------------------------------------------
311 
312  if( bResult )
313  {
314  Set_Modified(false);
315 
316  Set_File_Name(File, true);
317 
318  SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
319 
320  return( true );
321  }
322 
323  SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
324 
325  return( false );
326 }
327 
328 //---------------------------------------------------------
329 bool CSG_PointCloud::Save(const CSG_String &_File, int Format)
330 {
331  if( Format == POINTCLOUD_FILE_FORMAT_Undefined )
332  {
333  Format = SG_File_Cmp_Extension(_File, "sg-pts-z")
336  }
337 
338  bool bResult = false;
339 
340  CSG_String File(_File);
341 
342  switch( Format )
343  {
344  //-----------------------------------------------------
345  case POINTCLOUD_FILE_FORMAT_Compressed: default:
346  {
347  SG_File_Set_Extension(File, "sg-pts-z");
348 
349  SG_UI_Msg_Add(CSG_String::Format("%s %s: %s...", _TL("Saving"), _TL("point cloud"), File.c_str()), true);
350 
351  CSG_Archive Stream(File, SG_FILE_W);
352 
353  CSG_String Name(SG_File_Get_Name(File, false) + ".");
354 
355  if( Stream.Add_File(Name + "sg-pts") && _Save(Stream) )
356  {
357  if( Stream.Add_File(Name + "sg-pts-hdr") )
358  {
359  CSG_MetaData Header = _Create_Header(); Header.Save(Stream);
360  }
361 
362  if( Stream.Add_File(Name + "sg-info") )
363  {
364  Save_MetaData(Stream);
365  }
366 
367  if( Get_Projection().is_Okay() && Stream.Add_File(Name + "sg-prj") )
368  {
369  Get_Projection().Save(Stream);
370  }
371 
372  bResult = true;
373  }
374  }
375  break;
376 
377  //-----------------------------------------------------
379  {
380  SG_File_Set_Extension(File, "sg-pts");
381 
382  SG_UI_Msg_Add(CSG_String::Format("%s %s: %s...", _TL("Saving"), _TL("point cloud"), File.c_str()), true);
383 
384  CSG_File Stream(File, SG_FILE_W, true);
385 
386  if( _Save(Stream) )
387  {
388  CSG_MetaData Header = _Create_Header(); Header.Save(SG_File_Make_Path("", File, "sg-pts-hdr"));
389 
390  Save_MetaData(File);
391 
392  if( Get_Projection().is_Okay() )
393  {
394  Get_Projection().Save(SG_File_Make_Path("", File, "sg-prj"));
395  }
396 
397  bResult = true;
398  }
399  }
400  break;
401  }
402 
403  //-----------------------------------------------------
405 
406  if( bResult )
407  {
408  Set_Modified(false);
409 
410  Set_File_Name(File, true);
411 
412  SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
413 
414  return( true );
415  }
416 
417  SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
418 
419  return( false );
420 }
421 
422 //---------------------------------------------------------
424 {
425  bool bResult = false;
426 
427  if( SG_File_Cmp_Extension(File, "sg-pts-z") ) // POINTCLOUD_FILE_FORMAT_Compressed
428  {
429  CSG_Archive Stream(File, SG_FILE_R);
430 
431  CSG_String _File(SG_File_Get_Name(File, false) + ".");
432 
433  if( Stream.Get_File(_File + "sg-pts-hdr") )
434  {
435  bResult = Header.Load(Stream);
436  }
437  }
438  else // if( SG_File_Cmp_Extension(File, "sg-pts"/"spc") ) // POINTCLOUD_FILE_FORMAT_Normal
439  {
440  bResult = Header.Load(File, SG_T("sg-pts-hdr"));
441  }
442 
443  return( bResult );
444 }
445 
447 // //
449 
450 //---------------------------------------------------------
451 bool CSG_PointCloud::_Load(CSG_File &Stream)
452 {
453  if( !Stream.is_Reading() )
454  {
455  return( false );
456  }
457 
458  //-----------------------------------------------------
459  char ID[6];
460 
461  if( !Stream.Read(ID, 6) || strncmp(ID, PC_FILE_VERSION, 5) != 0 )
462  {
463  return( false );
464  }
465 
466  int nPointBytes;
467 
468  if( !Stream.Read(&nPointBytes, sizeof(int)) || nPointBytes < (int)(3 * sizeof(float)) )
469  {
470  return( false );
471  }
472 
473  int nFields;
474 
475  if( !Stream.Read(&nFields, sizeof(int)) || nFields < 3 )
476  {
477  return( false );
478  }
479 
480  //-----------------------------------------------------
481  Destroy();
482 
483  for(int iField=0; iField<nFields; iField++)
484  {
485  TSG_Data_Type Type; int iBuffer; char Name[1024];
486 
487  if( !Stream.Read(&Type , sizeof(TSG_Data_Type))
488  || !Stream.Read(&iBuffer, sizeof(int)) || !(iBuffer > 0 && iBuffer < 1024)
489  || !Stream.Read(Name , iBuffer) )
490  {
491  return( false );
492  }
493 
494  if( ID[5] == '0' ) // Data Type Definition changed!!!
495  {
496  switch( Type )
497  {
498  default: Type = SG_DATATYPE_Undefined; break;
499  case 1: Type = SG_DATATYPE_Char ; break;
500  case 2: Type = SG_DATATYPE_Short ; break;
501  case 3: Type = SG_DATATYPE_Int ; break;
502  case 4: Type = SG_DATATYPE_Long ; break;
503  case 5: Type = SG_DATATYPE_Float ; break;
504  case 6: Type = SG_DATATYPE_Double ; break;
505  }
506  }
507 
508  Name[iBuffer] = '\0';
509 
510  if( !_Add_Field(CSG_String((const char *)Name), Type) )
511  {
512  return( false );
513  }
514  }
515 
516  //-----------------------------------------------------
517  sLong fLength = Stream.Length();
518 
519  while( _Inc_Array() && Stream.Read(m_Cursor + 1, nPointBytes) && SG_UI_Process_Set_Progress((double)Stream.Tell(), (double)fLength) )
520  {
521  // nop
522  }
523 
524  _Dec_Array();
525 
526  return( true );
527 }
528 
529 //---------------------------------------------------------
530 bool CSG_PointCloud::_Save(CSG_File &Stream)
531 {
532  if( !Stream.is_Writing() )
533  {
534  return( false );
535  }
536 
537  //-----------------------------------------------------
538  int iBuffer, nPointBytes = m_nPointBytes - 1;
539 
540  Stream.Write((void *)PC_FILE_VERSION, 6);
541  Stream.Write(&nPointBytes, sizeof(int));
542  Stream.Write(&m_nFields , sizeof(int));
543 
544  for(int iField=0; iField<m_nFields; iField++)
545  {
546  Stream.Write(&m_Field_Type[iField], sizeof(TSG_Data_Type));
547 
548  iBuffer = (int)m_Field_Name[iField]->Length(); if( iBuffer >= 1024 - 1 ) iBuffer = 1024 - 1;
549  Stream.Write(&iBuffer, sizeof(int));
550  Stream.Write((void *)m_Field_Name[iField]->b_str(), sizeof(char), iBuffer);
551  }
552 
553  _Shape_Flush();
554 
555  for(sLong i=0; i<m_nRecords && SG_UI_Process_Set_Progress(i, m_nRecords); i++)
556  {
557  Stream.Write(m_Points[i] + 1, nPointBytes);
558  }
559 
560  return( true );
561 }
562 
563 //---------------------------------------------------------
564 CSG_MetaData CSG_PointCloud::_Create_Header(void) const
565 {
566  CSG_MetaData Header;
567 
568  Header.Set_Name("PointCloudHeaderFile");
569  Header.Add_Property("Version", "1.0");
570 
571  CSG_MetaData *pPoints = Header.Add_Child("Points" );
572  CSG_MetaData *pBBox = Header.Add_Child("BBox" );
573  CSG_MetaData *pNoData = Header.Add_Child("NoData" );
574  CSG_MetaData *pAttr = Header.Add_Child("Attributes");
575 
576  pPoints->Add_Property("Value", Get_Count());
577  pBBox ->Add_Property("XMin" , Get_Minimum(0));
578  pBBox ->Add_Property("YMin" , Get_Minimum(1));
579  pBBox ->Add_Property("ZMin" , Get_Minimum(2));
580  pBBox ->Add_Property("XMax" , Get_Maximum(0));
581  pBBox ->Add_Property("YMax" , Get_Maximum(1));
582  pBBox ->Add_Property("ZMax" , Get_Maximum(2));
583  pNoData->Add_Property("Value", Get_NoData_Value());
584  pAttr ->Add_Property("Count", m_nFields);
585 
586  for(int iField=0; iField<m_nFields; iField++)
587  {
588  CSG_MetaData *pField = pAttr->Add_Child(CSG_String::Format("Field_%d", iField + 1));
589 
590  pField->Add_Property("Name", Get_Field_Name(iField));
591  pField->Add_Property("Type", gSG_Data_Type_Identifier[Get_Field_Type(iField)]);
592  }
593 
594  return( Header );
595 }
596 
597 
599 // //
600 // Assign //
601 // //
603 
604 //---------------------------------------------------------
606 {
607  if( CSG_Data_Object::Assign(pObject) && pObject->asPointCloud(true) )
608  {
609  CSG_PointCloud *pPoints = pObject->asPointCloud(true);
610 
611  Get_Projection().Create(pPoints->Get_Projection());
612 
613  for(int iField=0; iField<pPoints->m_nFields; iField++)
614  {
615  _Add_Field(pPoints->m_Field_Name[iField]->c_str(), pPoints->m_Field_Type[iField]);
616  }
617 
618  for(sLong i=0; i<pPoints->m_nRecords; i++)
619  {
620  if( _Inc_Array() )
621  {
622  memcpy(m_Points[i] + 1, pPoints->m_Points[i] + 1, m_nPointBytes - 1l);
623  }
624  }
625 
626  return( true );
627  }
628 
629  return( false );
630 }
631 
632 
634 // //
635 // Checks //
636 // //
638 
639 //---------------------------------------------------------
641 {
642  if( m_nFields == pPointCloud->m_nFields )
643  {
644  for(int iField=0; iField<m_nFields; iField++)
645  {
646  if( Get_Field_Type(iField) != pPointCloud->Get_Field_Type(iField) )
647  {
648  return( false );
649  }
650  }
651 
652  return( true );
653  }
654 
655  return( false );
656 }
657 
658 
660 // //
661 // Fields //
662 // //
664 
665 //---------------------------------------------------------
666 bool CSG_PointCloud::Add_Field(const CSG_String &Name, TSG_Data_Type Type, int iField)
667 {
668  if( m_nFields == 0 ) { _Add_Field(SG_T("X"), m_bXYZPrecDbl ? SG_DATATYPE_Double : SG_DATATYPE_Float); }
669  if( m_nFields == 1 ) { _Add_Field(SG_T("Y"), m_bXYZPrecDbl ? SG_DATATYPE_Double : SG_DATATYPE_Float); }
670  if( m_nFields == 2 ) { _Add_Field(SG_T("Z"), m_bXYZPrecDbl ? SG_DATATYPE_Double : SG_DATATYPE_Float); }
671 
672  return( m_nFields >= 3 && _Add_Field(Name, Type, iField) );
673 }
674 
675 //---------------------------------------------------------
676 bool CSG_PointCloud::_Add_Field(const SG_Char *Name, TSG_Data_Type Type, int Field)
677 {
678  #define m_Field_Size(FIELD) PC_GET_NBYTES(m_Field_Type[FIELD])
679 
680  //-----------------------------------------------------
681  if( !Name || PC_GET_NBYTES(Type) <= 0 )
682  {
683  return( false );
684  }
685 
686  if( Field < 0 || Field > m_nFields )
687  {
688  Field = m_nFields;
689  }
690 
691  if( Field < 3 && m_nFields >= 3 )
692  {
693  Field = 3; // (x, y, z) always have to stay in the first place
694  }
695 
696  //-----------------------------------------------------
697  int nFieldBytes = PC_GET_NBYTES(Type);
698 
699  if( m_nFields < 1 )
700  {
701  m_nPointBytes = 1;
702  }
703 
704  m_nFields++; m_nPointBytes += nFieldBytes;
705 
706  //-----------------------------------------------------
710  m_Field_Offset = (int *)SG_Realloc(m_Field_Offset, m_nFields * sizeof(int ));
711 
712  for(int iField=m_nFields-1; iField>Field; iField--)
713  {
714  m_Field_Name [iField] = m_Field_Name [iField - 1];
715  m_Field_Type [iField] = m_Field_Type [iField - 1];
716  m_Field_Stats[iField] = m_Field_Stats[iField - 1];
717  }
718 
719  m_Field_Name [Field] = new CSG_String(Name);
720  m_Field_Type [Field] = Type;
721  m_Field_Stats[Field] = new CSG_Simple_Statistics();
722 
723  for(int iField=0, Offset=1; iField<m_nFields; iField++)
724  {
725  m_Field_Offset[iField] = Offset; Offset+=m_Field_Size(iField);
726  }
727 
728  //-----------------------------------------------------
729  int Offset = m_Field_Offset[Field], nMoveBytes = Field < m_nFields - 1 ? m_nPointBytes - m_Field_Offset[Field + 1] : 0;
730 
731  #pragma omp parallel for
732  for(sLong i=0; i<m_nRecords; i++)
733  {
734  m_Points[i] = (char *)SG_Realloc(m_Points[i], m_nPointBytes * sizeof(char));
735 
736  if( nMoveBytes > 0 )
737  {
738  memmove(m_Points[i] + Offset + nFieldBytes, m_Points[i] + Offset, nMoveBytes);
739  }
740 
741  memset(m_Points[i] + Offset, 0, nFieldBytes);
742  }
743 
744  //-----------------------------------------------------
745  m_Shapes.Add_Field(Name, Type, Field);
746 
747  Set_Modified();
748 
749  return( true );
750 }
751 
752 //---------------------------------------------------------
754 {
755  #define m_Field_Size(FIELD) PC_GET_NBYTES(m_Field_Type[FIELD])
756 
757  //-----------------------------------------------------
758  if( Index < 3 || Index >= m_nFields )
759  {
760  return( false );
761  }
762 
763  //-----------------------------------------------------
764  int nFieldBytes = PC_GET_NBYTES(m_Field_Type[Index]);
765 
766  m_nFields--; m_nPointBytes -= nFieldBytes;
767 
768  //-----------------------------------------------------
769  int Offset = m_Field_Offset[Index], nMoveBytes = Index < m_nFields ? (m_nPointBytes + nFieldBytes) - m_Field_Offset[Index + 1] : 0;
770 
771  #pragma omp parallel for
772  for(sLong i=0; i<m_nRecords; i++)
773  {
774  if( nMoveBytes > 0 )
775  {
776  memmove(m_Points[i] + Offset, m_Points[i] + Offset + nFieldBytes, nMoveBytes);
777  }
778 
779  m_Points[i] = (char *)SG_Realloc(m_Points[i], m_nPointBytes * sizeof(char));
780  }
781 
782  //-----------------------------------------------------
783  delete(m_Field_Name [Index]);
784  delete(m_Field_Stats[Index]);
785 
786  for(int iField=Index, Offset=m_Field_Offset[Index]; iField<m_nFields; iField++)
787  {
788  m_Field_Name [iField] = m_Field_Name [iField + 1];
789  m_Field_Type [iField] = m_Field_Type [iField + 1];
790  m_Field_Stats [iField] = m_Field_Stats[iField + 1];
791  m_Field_Offset[iField] = Offset; Offset += m_Field_Size(iField);
792  }
793 
797  m_Field_Offset = (int *)SG_Realloc(m_Field_Offset, m_nFields * sizeof(int ));
798 
799  //-----------------------------------------------------
800  m_Shapes.Del_Field(Index);
801 
802  Set_Modified();
803 
804  return( true );
805 }
806 
807 //---------------------------------------------------------
808 bool CSG_PointCloud::Mov_Field(int Index, int Position)
809 {
810  if( Position < 0 )
811  {
812  Position = 0;
813  }
814  else if( Position >= m_nFields - 1 )
815  {
816  Position = m_nFields - 1;
817  }
818 
819  if( Index < 3 || Index >= m_nFields || Index == Position )
820  {
821  return( false );
822  }
823 
824  //-----------------------------------------------------
825  if( Position > Index )
826  {
827  Position++;
828  }
829 
830  if( !Add_Field(Get_Field_Name(Index), Get_Field_Type(Index), Position) )
831  {
832  return( false );
833  }
834 
835  if( Position < Index )
836  {
837  Index++;
838  }
839 
840  size_t Size = PC_GET_NBYTES(m_Field_Type[Index]);
841 
842  #pragma omp parallel for
843  for(sLong i=0; i<m_nRecords; i++)
844  {
845  memcpy(m_Points[i] + m_Field_Offset[Position], m_Points[i] + m_Field_Offset[Index], Size);
846  }
847 
848  if( !Del_Field(Index) )
849  {
850  return( false );
851  }
852 
853  //-----------------------------------------------------
854  return( true );
855 }
856 
857 
859 // //
861 
862 //---------------------------------------------------------
864 {
865  if( iField < 3 || iField >= m_nFields )
866  {
867  return( false );
868  }
869 
870  if( Type == m_Field_Type[iField] )
871  {
872  return( true );
873  }
874 
875  //-----------------------------------------------------
876  Add_Field(Get_Field_Name(iField), Type, iField);
877 
878  #pragma omp parallel for
879  for(sLong i=0; i<m_nRecords; i++)
880  {
881  Set_Value(i, iField, Get_Value(i, iField + 1));
882  }
883 
884  Del_Field(iField + 1);
885 
886  //-----------------------------------------------------
887  m_Shapes.Set_Field_Type(iField, Type);
888 
889  Set_Modified();
890 
891  return( true );
892 }
893 
894 //---------------------------------------------------------
895 bool CSG_PointCloud::_Set_Field_Value(char *pPoint, int iField, double Value)
896 {
897  if( pPoint && iField >= 0 && iField < m_nFields )
898  {
899  pPoint = ((char *)pPoint) + m_Field_Offset[iField];
900 
901  switch( m_Field_Type[iField] )
902  {
903  case SG_DATATYPE_Byte : *((BYTE *)pPoint) = (BYTE )Value ; break;
904  case SG_DATATYPE_Char : *((char *)pPoint) = (char )Value ; break;
905  case SG_DATATYPE_Word : *((WORD *)pPoint) = (WORD )Value ; break;
906  case SG_DATATYPE_Short : *((short *)pPoint) = (short )Value ; break;
907  case SG_DATATYPE_DWord : *((DWORD *)pPoint) = (DWORD )Value ; break;
908  case SG_DATATYPE_Int : *((int *)pPoint) = (int )Value ; break;
909  case SG_DATATYPE_Long : *((sLong *)pPoint) = (sLong )Value ; break;
910  case SG_DATATYPE_ULong : *((uLong *)pPoint) = (uLong )Value ; break;
911  case SG_DATATYPE_Float : *((float *)pPoint) = (float )Value ; break;
912  case SG_DATATYPE_Double: *((double *)pPoint) = (double)Value ; break;
913  case SG_DATATYPE_Color : *((DWORD *)pPoint) = (DWORD )Value ; break;
914  case SG_DATATYPE_String: sprintf( pPoint, "%f" , Value); break;
915  default : break;
916  }
917 
918  m_Field_Stats[iField]->Invalidate();
919 
920  Set_Modified();
921 
922  if( iField < 3 )
923  {
924  Set_Update_Flag(); // extent might have changed
925  }
926 
927  return( true );
928  }
929 
930  return( false );
931 }
932 
933 //---------------------------------------------------------
934 double CSG_PointCloud::_Get_Field_Value(char *pPoint, int iField) const
935 {
936  if( pPoint && iField >= 0 && iField < m_nFields )
937  {
938  pPoint += m_Field_Offset[iField];
939 
940  switch( m_Field_Type[iField] )
941  {
942  case SG_DATATYPE_Byte : return( (double)*((BYTE *)pPoint) );
943  case SG_DATATYPE_Char : return( (double)*((char *)pPoint) );
944  case SG_DATATYPE_Word : return( (double)*((WORD *)pPoint) );
945  case SG_DATATYPE_Short : return( (double)*((short *)pPoint) );
946  case SG_DATATYPE_DWord : return( (double)*((DWORD *)pPoint) );
947  case SG_DATATYPE_Int : return( (double)*((int *)pPoint) );
948  case SG_DATATYPE_Long : return( (double)*((sLong *)pPoint) );
949  case SG_DATATYPE_ULong : return( (double)*((uLong *)pPoint) );
950  case SG_DATATYPE_Float : return( (double)*((float *)pPoint) );
951  case SG_DATATYPE_Double: return( (double)*((double *)pPoint) );
952  case SG_DATATYPE_Color : return( (double)*((DWORD *)pPoint) );
953  case SG_DATATYPE_String: return( (double)atof( pPoint) );
954  default : break;
955  }
956  }
957 
958  return( 0. );
959 }
960 
961 //---------------------------------------------------------
962 bool CSG_PointCloud::_Set_Field_Value(char *pPoint, int iField, const SG_Char *Value)
963 {
964  if( pPoint && iField >= 0 && iField < m_nFields && Value )
965  {
966  CSG_String s(Value);
967 
968  switch( m_Field_Type[iField] )
969  {
970  default: { double d; return( s.asDouble(d) && _Set_Field_Value(pPoint, iField, d) ); }
971 
972  case SG_DATATYPE_Date :
973  case SG_DATATYPE_String:
974  pPoint += m_Field_Offset[iField];
975  memset(pPoint, 0, PC_STR_NBYTES);
976  memcpy(pPoint, s.b_str(), s.Length() > PC_STR_NBYTES ? PC_STR_NBYTES : s.Length());
977  break;
978  }
979 
980  return( true );
981  }
982 
983  return( false );
984 }
985 
986 //---------------------------------------------------------
987 bool CSG_PointCloud::_Get_Field_Value(char *pPoint, int iField, CSG_String &Value) const
988 {
989  if( pPoint && iField >= 0 && iField < m_nFields )
990  {
991  switch( m_Field_Type[iField] )
992  {
993  default:
994  Value.Printf("%f", _Get_Field_Value(pPoint, iField));
995  break;
996 
997  case SG_DATATYPE_Date:
998  case SG_DATATYPE_String:
999  {
1000  char s[PC_STR_NBYTES + 1];
1001 
1002  memcpy(s, pPoint + m_Field_Offset[iField], PC_STR_NBYTES);
1003 
1004  s[PC_STR_NBYTES] = '\0';
1005 
1006  Value = s;
1007  }
1008  break;
1009  }
1010 
1011  return( true );
1012  }
1013 
1014  return( false );
1015 }
1016 
1017 
1019 // //
1020 // //
1021 // //
1023 
1024 //---------------------------------------------------------
1026 {
1027  TSG_Point_3D p;
1028 
1029  if( m_Cursor )
1030  {
1031  p.x = _Get_Field_Value(m_Cursor, 0);
1032  p.y = _Get_Field_Value(m_Cursor, 1);
1033  p.z = _Get_Field_Value(m_Cursor, 2);
1034  }
1035  else
1036  {
1037  p.x = p.y = p.z = 0.;
1038  }
1039 
1040  return( p );
1041 }
1042 
1043 //---------------------------------------------------------
1045 {
1046  TSG_Point_3D p;
1047 
1048  if( Index >= 0 && Index < m_nRecords )
1049  {
1050  char *pPoint = m_Points[Index];
1051 
1052  p.x = _Get_Field_Value(pPoint, 0);
1053  p.y = _Get_Field_Value(pPoint, 1);
1054  p.z = _Get_Field_Value(pPoint, 2);
1055  }
1056  else
1057  {
1058  p.x = p.y = p.z = 0.;
1059  }
1060 
1061  return( p );
1062 }
1063 
1064 //---------------------------------------------------------
1066 {
1067  return( _Set_Field_Value(m_Cursor, 0, Point.x)
1068  && _Set_Field_Value(m_Cursor, 1, Point.y)
1069  && _Set_Field_Value(m_Cursor, 2, Point.z)
1070  );
1071 }
1072 
1073 //---------------------------------------------------------
1075 {
1076  if( Index >= 0 && Index < m_nRecords )
1077  {
1078  return( _Set_Field_Value(m_Points[Index], 0, Point.x)
1079  && _Set_Field_Value(m_Points[Index], 1, Point.y)
1080  && _Set_Field_Value(m_Points[Index], 2, Point.z)
1081  );
1082  }
1083 
1084  return( false );
1085 }
1086 
1087 
1089 // //
1090 // //
1091 // //
1093 
1094 //---------------------------------------------------------
1095 bool CSG_PointCloud::Add_Point(double x, double y, double z)
1096 {
1097  if( _Inc_Array() )
1098  {
1099  _Set_Field_Value(m_Cursor, 0, x);
1100  _Set_Field_Value(m_Cursor, 1, y);
1101  _Set_Field_Value(m_Cursor, 2, z);
1102 
1103  Set_Modified();
1104  Set_Update_Flag();
1106 
1107  return( true );
1108  }
1109 
1110  return( false );
1111 }
1112 
1113 //---------------------------------------------------------
1115 {
1116  return( Add_Point(Point.x, Point.y, Point.z) );
1117 }
1118 
1119 //---------------------------------------------------------
1121 {
1122  if( Index >= 0 && Index < m_nRecords )
1123  {
1124  if( is_Selected(Index) )
1125  {
1126  Select(Index, true);
1127  }
1128 
1129  m_Cursor = m_Points[Index];
1130 
1131  for(sLong i=Index, j=Index+1; j<m_nRecords; i++, j++)
1132  {
1133  m_Points[i] = m_Points[j];
1134  }
1135 
1136  m_Points[m_nRecords - 1] = m_Cursor;
1137 
1138  m_Cursor = NULL;
1139 
1140  _Dec_Array();
1141 
1142  Set_Modified();
1143  Set_Update_Flag();
1145 
1146  return( true );
1147  }
1148 
1149  return( false );
1150 }
1151 
1152 //---------------------------------------------------------
1154 {
1155  for(sLong i=0; i<m_nRecords; i++)
1156  {
1157  SG_Free(m_Points[i]);
1158  }
1159 
1160  m_Array_Points.Destroy();
1161 
1162  m_nRecords = 0;
1163  m_Points = NULL;
1164  m_Cursor = NULL;
1165 
1167 
1168  Set_Modified();
1169  Set_Update_Flag();
1171 
1172  return( true );
1173 }
1174 
1175 
1177 // //
1178 // //
1179 // //
1181 
1182 //---------------------------------------------------------
1183 bool CSG_PointCloud::_Inc_Array(void)
1184 {
1185  if( m_nFields > 0 && m_Array_Points.Set_Array(m_nRecords + 1, (void **)&m_Points) )
1186  {
1187  m_Points[m_nRecords++] = m_Cursor = (char *)SG_Calloc(m_nPointBytes, sizeof(char));
1188 
1189  return( true );
1190  }
1191 
1192  return( false );
1193 }
1194 
1195 //---------------------------------------------------------
1196 bool CSG_PointCloud::_Dec_Array(void)
1197 {
1198  if( m_nRecords > 0 )
1199  {
1200  m_nRecords --;
1201 
1202  m_Cursor = NULL;
1203 
1204  SG_Free(m_Points[m_nRecords]);
1205 
1206  m_Array_Points.Set_Array(m_nRecords, (void **)&m_Points);
1207  }
1208 
1209  return( true );
1210 }
1211 
1212 
1214 // //
1215 // Statistics //
1216 // //
1218 
1219 //---------------------------------------------------------
1221 {
1222  if( m_nFields >= 2 )
1223  {
1224  _Shape_Flush();
1225 
1226  _Stats_Update(0);
1227  _Stats_Update(1);
1228  _Stats_Update(2);
1229 
1230  m_Extent.Assign(
1233  );
1234 
1237 
1238  for(int iField=3; iField<m_nFields; iField++)
1239  {
1240  m_Field_Stats[iField]->Invalidate();
1241  }
1242  }
1243 
1244  return( true );
1245 }
1246 
1247 //---------------------------------------------------------
1248 bool CSG_PointCloud::_Stats_Update(int Field) const
1249 {
1250  if( Field < 0 || Field >= m_nFields || m_nRecords < 1 )
1251  {
1252  return( false );
1253  }
1254 
1255  CSG_Simple_Statistics &Statistics = *m_Field_Stats[Field];
1256 
1257  if( Statistics.is_Evaluated() )
1258  {
1259  return( true );
1260  }
1261 
1262  if( Field > 2 && Get_Max_Samples() > 0 && Get_Max_Samples() < m_nRecords )
1263  {
1264  double d = (double)m_nRecords / (double)Get_Max_Samples();
1265 
1266  for(double i=0; i<(double)m_nRecords; i+=d)
1267  {
1268  double Value = Get_Value((sLong)i, Field);
1269 
1270  if( Field < 3 || is_NoData_Value(Value) == false )
1271  {
1272  Statistics += Value;
1273  }
1274  }
1275 
1276  Statistics.Set_Count(Statistics.Get_Count() >= Get_Max_Samples() ? m_nRecords // any no-data cells ?
1277  : (sLong)(m_nRecords * (double)Statistics.Get_Count() / (double)Get_Max_Samples())
1278  );
1279  }
1280  else
1281  {
1282  char **pPoint = m_Points;
1283 
1284  for(sLong i=0; i<m_nRecords; i++, pPoint++)
1285  {
1286  double Value = _Get_Field_Value(*pPoint, Field);
1287 
1288  if( Field < 3 || is_NoData_Value(Value) == false )
1289  {
1290  Statistics += Value;
1291  }
1292  }
1293  }
1294 
1295  return( Statistics.Evaluate() ); // evaluate! prevent values to be added more than once!
1296 }
1297 
1298 
1300 // //
1301 // //
1302 // //
1304 
1305 //---------------------------------------------------------
1307 {
1308  return( Create(Get_File_Name(false)) );
1309 }
1310 
1311 //---------------------------------------------------------
1313 {
1314  return( SG_File_Delete(Get_File_Name(false)) );
1315 }
1316 
1317 
1319 // //
1320 // //
1321 // //
1323 
1324 //---------------------------------------------------------
1325 CSG_Shape * CSG_PointCloud::_Shape_Get(sLong Index)
1326 {
1327  SG_UI_Progress_Lock(true);
1328 
1329  CSG_Shape *pShape = m_Shapes.Get_Shape(SG_OMP_Get_Thread_Num());
1330 
1331  if( pShape->is_Modified() && pShape->m_Index >= 0 && pShape->m_Index < m_nRecords )
1332  {
1333  char *Point = m_Points[pShape->m_Index];
1334 
1335  for(int iField=0; iField<m_nFields; iField++)
1336  {
1337  switch( Get_Field_Type(iField) )
1338  {
1339  default : _Set_Field_Value(Point, iField, pShape->asDouble(iField)); break;
1340  case SG_DATATYPE_Date :
1341  case SG_DATATYPE_String: _Set_Field_Value(Point, iField, pShape->asString(iField)); break;
1342  }
1343  }
1344 
1345  Set_Value(0, pShape->Get_Point().x);
1346  Set_Value(1, pShape->Get_Point().y);
1347  Set_Value(2, pShape->Get_Z () );
1348  }
1349 
1350  if( Index >= 0 && Index < m_nRecords )
1351  {
1352  char *Point = m_Points[Index];
1353 
1354  for(int iField=0; iField<m_nFields; iField++)
1355  {
1356  switch( Get_Field_Type(iField) )
1357  {
1358  default: pShape->Set_Value(iField, _Get_Field_Value(Point, iField)); break;
1359 
1360  case SG_DATATYPE_Date :
1361  case SG_DATATYPE_String: {
1362  CSG_String s; _Get_Field_Value(Point, iField, s); pShape->Set_Value(iField, s);
1363  break; }
1364  }
1365  }
1366 
1367  pShape->Set_Point(Get_Point(Index));
1368  pShape->Set_Selected(is_Selected(Index));
1369  pShape->Set_Modified(false);
1370 
1371  pShape->m_Index = Index;
1372  }
1373  else
1374  {
1375  pShape->m_Index = -1;
1376  }
1377 
1378  SG_UI_Progress_Lock(false);
1379 
1380  return( pShape->m_Index >= 0 ? pShape : NULL );
1381 }
1382 
1383 //---------------------------------------------------------
1384 void CSG_PointCloud::_Shape_Flush(void)
1385 {
1386  for(sLong i=0; i<m_Shapes.Get_Count(); i++)
1387  {
1388  _Shape_Get(m_Shapes[i].m_Index); m_Shapes[i].m_Index = -1;
1389  }
1390 }
1391 
1392 //---------------------------------------------------------
1394 {
1395  return( ((CSG_PointCloud *)this)->_Shape_Get(Index) );
1396 }
1397 
1398 
1400 // //
1401 // //
1402 // //
1404 
1405 //---------------------------------------------------------
1406 CSG_Shape * CSG_PointCloud::Get_Shape(const CSG_Point &Point, double Epsilon)
1407 {
1408  CSG_Rect r(Point.x - Epsilon, Point.y - Epsilon, Point.x + Epsilon, Point.y + Epsilon);
1409 
1411  {
1412  sLong Index = -1; double Distance = -1.;
1413 
1414  for(sLong i=0; i<m_nRecords; i++)
1415  {
1416  Set_Cursor(i);
1417 
1418  if( r.Contains(Get_X(), Get_Y()) )
1419  {
1420  if( Index < 0 || Distance > SG_Get_Distance(Point.x, Point.y, Get_X(), Get_Y()) )
1421  {
1422  Index = i; Distance = SG_Get_Distance(Point.x, Point.y, Get_X(), Get_Y());
1423  }
1424  }
1425  }
1426 
1427  if( Index >= 0 )
1428  {
1429  return( CSG_Shapes::Get_Shape(Index) );
1430  }
1431  }
1432 
1433  return( NULL );
1434 }
1435 
1436 //---------------------------------------------------------
1438 {
1439  return( NULL );
1440 }
1441 
1442 //---------------------------------------------------------
1444 {
1445  return( Add_Shape(pCopy, SHAPE_COPY) );
1446 }
1447 
1448 //---------------------------------------------------------
1450 {
1451  Add_Point(0., 0., 0.);
1452 
1453  if( pCopy && (mCopy == SHAPE_COPY_ATTR || mCopy == SHAPE_COPY) )
1454  {
1455  for(int iField=0; iField<m_nFields && iField<pCopy->Get_Table()->Get_Field_Count(); iField++)
1456  {
1457  if( Get_Field_Type(iField) == pCopy->Get_Table()->Get_Field_Type(iField) )
1458  {
1460  {
1461  Set_Value(iField, pCopy->asDouble(iField));
1462  }
1463  else
1464  {
1465  Set_Value(iField, pCopy->asString(iField));
1466  }
1467  }
1468  }
1469  }
1470 
1471  return( _Shape_Get(m_nRecords - 1) );
1472 }
1473 
1474 
1476 // //
1477 // //
1478 // //
1480 
1481 //---------------------------------------------------------
1482 bool CSG_PointCloud::Select(sLong Index, bool bInvert)
1483 {
1484  if( !bInvert && Get_Selection_Count() > 0 )
1485  {
1486  for(sLong i=0; i<Get_Selection_Count(); i++)
1487  {
1488  m_Points[Get_Selection_Index(i)][0] &= ~SG_TABLE_REC_FLAG_Selected;
1489  }
1490 
1491  m_Selection.Destroy();
1492  }
1493 
1494  if( Set_Cursor(Index) )
1495  {
1496  if( (m_Cursor[0] & SG_TABLE_REC_FLAG_Selected) == 0 ) // select
1497  {
1498  if( _Add_Selection(Index) )
1499  {
1500  m_Cursor[0] |= SG_TABLE_REC_FLAG_Selected;
1501 
1502  return( true );
1503  }
1504  }
1505  else // deselect
1506  {
1507  if( _Del_Selection(Index) )
1508  {
1509  m_Cursor[0] &= ~SG_TABLE_REC_FLAG_Selected;
1510 
1511  return( true );
1512  }
1513  }
1514  }
1515 
1516  return( false );
1517 }
1518 
1519 //---------------------------------------------------------
1520 bool CSG_PointCloud::Select(CSG_Table_Record *pShape, bool bInvert)
1521 {
1522  return( CSG_Table::Select(pShape, bInvert) );
1523 }
1524 
1525 //---------------------------------------------------------
1526 bool CSG_PointCloud::Select(const TSG_Rect &Extent, bool bInvert)
1527 {
1528  if( !bInvert ) // clear selection
1529  {
1530  Select(-1, false);
1531  }
1532 
1533  if( Get_Extent().Intersects(Extent) != INTERSECTION_None )
1534  {
1535  for(sLong i=0; i<m_nRecords; i++)
1536  {
1537  Set_Cursor(i);
1538 
1539  if( Extent.xMin <= Get_X() && Get_X() <= Extent.xMax
1540  && Extent.yMin <= Get_Y() && Get_Y() <= Extent.yMax )
1541  {
1542  Select(i, true);
1543  }
1544  }
1545  }
1546 
1547  return( Get_Selection_Count() > 0 );
1548 }
1549 
1550 //---------------------------------------------------------
1551 bool CSG_PointCloud::Select(const TSG_Point &Point, bool bInvert)
1552 {
1553  return( Select(CSG_Rect(Point.x, Point.y, Point.x, Point.y), bInvert) );
1554 }
1555 
1556 
1558 // //
1560 
1561 //---------------------------------------------------------
1563 {
1564  return( Index >= 0 && Index < m_nRecords && (m_Points[Index][0] & SG_TABLE_REC_FLAG_Selected) != 0 );
1565 }
1566 
1567 
1569 // //
1571 
1572 //---------------------------------------------------------
1574 {
1575  return( Index < Get_Selection_Count() ? _Shape_Get(Get_Selection_Index(Index)) : NULL );
1576 }
1577 
1578 //---------------------------------------------------------
1580 {
1581  if( Get_Selection_Count() > 0 && Set_Cursor((int)Get_Selection_Index(0)) )
1582  {
1583  TSG_Rect r;
1584 
1585  r.xMin = r.xMax = Get_X();
1586  r.yMin = r.yMax = Get_Y();
1587 
1588  for(sLong i=1; i<Get_Selection_Count(); i++)
1589  {
1591  {
1592  if( Get_X() < r.xMin ) { r.xMin = Get_X(); } else if( Get_X() > r.xMax ) { r.xMax = Get_X(); }
1593  if( Get_Y() < r.yMin ) { r.yMin = Get_Y(); } else if( Get_Y() > r.yMax ) { r.yMax = Get_Y(); }
1594  }
1595  }
1596 
1598  }
1599  else
1600  {
1601  m_Extent_Selected.Assign(0., 0., 0., 0.);
1602  }
1603 
1604  return( m_Extent_Selected );
1605 }
1606 
1607 
1609 // //
1611 
1612 //---------------------------------------------------------
1614 {
1615  sLong n = 0;
1616 
1617  if( Get_Selection_Count() > 0 )
1618  {
1620 
1621  m_Cursor = NULL;
1622 
1623  for(sLong i=0; i<m_nRecords; i++)
1624  {
1625  if( (m_Points[i][0] & SG_TABLE_REC_FLAG_Selected) != 0 )
1626  {
1627  SG_Free(m_Points[i]);
1628  }
1629  else
1630  {
1631  if( n < i )
1632  {
1633  m_Points[n] = m_Points[i];
1634  }
1635 
1636  n++;
1637  }
1638  }
1639 
1640  m_Array_Points.Set_Array(m_nRecords = n, (void **)&m_Points);
1641 
1642  Set_Modified();
1643  Set_Update_Flag();
1645  }
1646 
1647  return( n );
1648 }
1649 
1650 //---------------------------------------------------------
1652 {
1654  {
1655  char **pPoint = m_Points;
1656 
1657  for(sLong i=0, n=0; i<m_nRecords && n<Get_Selection_Count(); i++, pPoint++)
1658  {
1659  if( ((*pPoint)[0] & SG_TABLE_REC_FLAG_Selected) != 0 )
1660  {
1661  (*pPoint)[0] &= ~SG_TABLE_REC_FLAG_Selected;
1662  }
1663  else
1664  {
1665  (*pPoint)[0] |= SG_TABLE_REC_FLAG_Selected;
1666 
1667  _Set_Selection(i, n++);
1668  }
1669  }
1670  }
1671 
1672  return( Get_Selection_Count() );
1673 }
1674 
1675 
1677 // //
1678 // //
1679 // //
1681 
1682 //---------------------------------------------------------
1684 {
1685  m_Points[m_nRecords++] = (char *)SG_Calloc(m_nPointBytes, sizeof(char));
1686 
1687  if( Get_Count() > 0 && Get_Count() == Index.Get_Count() )
1688  {
1689  char **Points = (char **)SG_Malloc(m_nBuffer * sizeof(char *)); memcpy(Points, m_Points, Get_Count());
1690 
1691  for(sLong i=0; i<Get_Count(); i++)
1692  {
1693  m_Points[i] = Points[Index[i]];
1694  }
1695 
1696  SG_Free(Points);
1697 
1698  Del_Index(); m_Cursor = NULL;
1699 
1700  return( true );
1701  }
1702 
1703  return( false );
1704 }
1705 
1706 
1708 // //
1709 // //
1710 // //
1712 
1713 //---------------------------------------------------------
CSG_Index
Definition: mat_tools.h:200
CSG_PointCloud::Add_Record
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
Definition: pointcloud.cpp:1443
CSG_Rect
Definition: geo_tools.h:474
SG_DATATYPE_Color
@ SG_DATATYPE_Color
Definition: api_core.h:1008
SG_DATATYPE_Int
@ SG_DATATYPE_Int
Definition: api_core.h:1001
CSG_Table_Record::asDouble
double asDouble(int Field) const
Definition: table_record.cpp:527
SHAPE_COPY_ATTR
@ SHAPE_COPY_ATTR
Definition: shapes.h:127
CSG_Array::Set_Array
bool Set_Array(sLong nValues, bool bShrink=true)
Definition: api_memory.cpp:310
CSG_Data_Object::Assign
virtual bool Assign(CSG_Data_Object *pObject)
Definition: dataobject.cpp:797
CSG_PointCloud::Get_Y
double Get_Y(void) const
Definition: pointcloud.h:167
CSG_PointCloud::Get_X
double Get_X(void) const
Definition: pointcloud.h:166
CSG_Rect::Assign
CSG_Rect & Assign(double xMin, double yMin, double xMax, double yMax)
Definition: geo_classes.cpp:727
CSG_Shapes::m_Extent_Selected
CSG_Rect m_Extent_Selected
Definition: shapes.h:849
CSG_Shapes::m_ZMin
double m_ZMin
Definition: shapes.h:843
SG_DATATYPE_Undefined
@ SG_DATATYPE_Undefined
Definition: api_core.h:1010
CSG_PointCloud::Destroy
virtual bool Destroy(void)
Definition: pointcloud.cpp:224
CSG_Data_Object::Get_Max_Samples
sLong Get_Max_Samples(void) const
Definition: dataobject.h:263
CSG_Projection::Save
bool Save(const CSG_String &File, ESG_CRS_Format Format=ESG_CRS_Format::WKT) const
Definition: projections.cpp:261
SG_T
#define SG_T(s)
Definition: api_core.h:537
CSG_String::Printf
int Printf(const char *Format,...)
Definition: api_string.cpp:308
CSG_Table::Set_Count
virtual bool Set_Count(sLong nRecords)
Definition: table.cpp:919
SG_DATATYPE_String
@ SG_DATATYPE_String
Definition: api_core.h:1006
_TL
#define _TL(s)
Definition: api_core.h:1507
SG_DATATYPE_DWord
@ SG_DATATYPE_DWord
Definition: api_core.h:1000
PC_STR_NBYTES
#define PC_STR_NBYTES
Definition: pointcloud.cpp:63
CSG_Data_Object::Set_File_Name
void Set_File_Name(const CSG_String &FileName)
Definition: dataobject.cpp:366
POINTCLOUD_FILE_FORMAT_Normal
@ POINTCLOUD_FILE_FORMAT_Normal
Definition: pointcloud.h:91
CSG_Shapes::Get_Shape
virtual CSG_Shape * Get_Shape(const CSG_Point &Point, double Epsilon=0.)
Definition: shapes.cpp:483
CSG_String::b_str
const char * b_str(void) const
Definition: api_string.cpp:242
CSG_PointCloud::Set_Point
virtual bool Set_Point(const TSG_Point_3D &Point)
Definition: pointcloud.cpp:1065
CSG_PointCloud::Set_Field_Type
virtual bool Set_Field_Type(int Field, TSG_Data_Type Type)
Definition: pointcloud.cpp:863
CSG_Table_Record
Definition: table.h:130
CSG_Shape::Get_Z
virtual double Get_Z(int iPoint=0, int iPart=0, bool bAscending=true) const
Definition: shapes.h:193
CSG_Table_Record::Set_Selected
void Set_Selected(bool bOn=true)
Definition: table_record.cpp:204
CSG_Data_Object::Get_NoData_Value
double Get_NoData_Value(bool bUpper=false) const
Definition: dataobject.h:253
TSG_ADD_Shape_Copy_Mode
TSG_ADD_Shape_Copy_Mode
Definition: shapes.h:124
SG_Create_PointCloud
CSG_PointCloud * SG_Create_PointCloud(void)
Definition: pointcloud.cpp:76
SG_UI_MSG_STYLE_SUCCESS
@ SG_UI_MSG_STYLE_SUCCESS
Definition: api_core.h:1523
CSG_Table::m_Selection
CSG_Array m_Selection
Definition: table.h:470
CSG_Table::Del_Field
virtual bool Del_Field(int iField)
Definition: table.cpp:513
SG_File_Cmp_Extension
SAGA_API_DLL_EXPORT bool SG_File_Cmp_Extension(const CSG_String &FileName, const CSG_String &Extension)
Definition: api_file.cpp:1091
CSG_Shapes::Create
bool Create(const CSG_Shapes &Shapes)
Definition: shapes.cpp:209
m_Field_Size
#define m_Field_Size(FIELD)
SG_Malloc
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
Definition: api_memory.cpp:65
SG_TABLE_REC_FLAG_Selected
#define SG_TABLE_REC_FLAG_Selected
Definition: table.h:119
CSG_Table::m_Field_Name
CSG_String ** m_Field_Name
Definition: table.h:466
CSG_Data_Object::Save_MetaData
bool Save_MetaData(const CSG_String &FileName)
Definition: dataobject.cpp:681
SSG_Point_3D
Definition: geo_tools.h:265
CSG_Data_Object::is_NoData_Value
bool is_NoData_Value(double Value) const
Definition: dataobject.h:255
SG_DATATYPE_Byte
@ SG_DATATYPE_Byte
Definition: api_core.h:996
CSG_Archive
Definition: api_core.h:1200
CSG_Rect::Intersects
TSG_Intersection Intersects(const CSG_Rect &Rect) const
Definition: geo_classes.cpp:881
CSG_PointCloud::Get_Selection_Extent
virtual const CSG_Rect & Get_Selection_Extent(void)
Definition: pointcloud.cpp:1579
CSG_Shapes::m_ZMax
double m_ZMax
Definition: shapes.h:843
SSG_Point_3D::x
double x
Definition: geo_tools.h:266
SSG_Rect::xMax
double xMax
Definition: geo_tools.h:468
CSG_PointCloud::Select
virtual bool Select(sLong Index, bool bInvert=false)
Definition: pointcloud.cpp:1482
CSG_PointCloud::On_Reload
virtual bool On_Reload(void)
Definition: pointcloud.cpp:1306
CSG_Table::Get_Field_Count
int Get_Field_Count(void) const
Definition: table.h:361
SG_File_Delete
SAGA_API_DLL_EXPORT bool SG_File_Delete(const CSG_String &FileName)
Definition: api_file.cpp:995
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_Shapes::m_Type
TSG_Shape_Type m_Type
Definition: shapes.h:845
SHAPE_COPY
@ SHAPE_COPY
Definition: shapes.h:128
CSG_MetaData::Save
bool Save(const CSG_String &File, const SG_Char *Extension=NULL) const
Definition: metadata.cpp:879
CSG_Table::m_Extent
CSG_Rect m_Extent
Definition: table.h:472
SG_FILE_R
@ SG_FILE_R
Definition: api_core.h:1111
CSG_PointCloud::Assign
virtual bool Assign(CSG_Data_Object *pSource)
Definition: pointcloud.cpp:605
SSG_Point
Definition: geo_tools.h:128
CSG_Table_Record::Get_Table
class CSG_Table * Get_Table(void)
Definition: table.h:135
CSG_PointCloud::Add_Field
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Field=-1)
Definition: pointcloud.cpp:666
CSG_Table_Record::m_Index
sLong m_Index
Definition: table.h:256
PC_GET_NBYTES
#define PC_GET_NBYTES(type)
Definition: pointcloud.cpp:66
CSG_File::Read
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition: api_file.cpp:337
CSG_Data_Object::Set_Update_Flag
void Set_Update_Flag(bool bOn=true)
Definition: dataobject.h:285
SG_Calloc
SAGA_API_DLL_EXPORT void * SG_Calloc(size_t num, size_t size)
Definition: api_memory.cpp:71
CSG_File
Definition: api_core.h:1126
CSG_Table::_Stats_Invalidate
bool _Stats_Invalidate(void) const
Definition: table.cpp:1193
SSG_Rect::xMin
double xMin
Definition: geo_tools.h:468
CSG_Rect::Contains
bool Contains(double x, double y) const
Definition: geo_classes.cpp:870
CSG_Table::m_Field_Type
TSG_Data_Type * m_Field_Type
Definition: table.h:464
SSG_Rect
Definition: geo_tools.h:467
CSG_Shape::Get_Point
virtual TSG_Point Get_Point(int iPoint=0) const =0
CSG_PointCloud::Set_Value
virtual bool Set_Value(int Field, double Value)
Definition: pointcloud.h:164
CSG_PointCloud::is_Compatible
bool is_Compatible(CSG_PointCloud *pPointCloud) const
Definition: pointcloud.cpp:640
CSG_PointCloud::Del_Selection
virtual sLong Del_Selection(void)
Definition: pointcloud.cpp:1613
SG_UI_MSG_STYLE_FAILURE
@ SG_UI_MSG_STYLE_FAILURE
Definition: api_core.h:1524
CSG_Simple_Statistics::Get_Maximum
double Get_Maximum(void)
Definition: mat_tools.h:747
CSG_PointCloud::~CSG_PointCloud
virtual ~CSG_PointCloud(void)
Definition: pointcloud.cpp:219
SG_File_Get_Name
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
Definition: api_file.cpp:1017
CSG_Table::m_Field_Stats
CSG_Simple_Statistics ** m_Field_Stats
Definition: table.h:468
SG_DATATYPE_Long
@ SG_DATATYPE_Long
Definition: api_core.h:1003
CSG_PointCloud::Sort
virtual bool Sort(const CSG_Index &Index)
Definition: pointcloud.cpp:1683
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_Point
Definition: geo_tools.h:135
CSG_Table::Get_Field_Name
const SG_Char * Get_Field_Name(int iField) const
Definition: table.h:362
CSG_PointCloud::Del_Points
bool Del_Points(void)
Definition: pointcloud.cpp:1153
CSG_PointCloud::Del_Point
bool Del_Point(sLong Index)
Definition: pointcloud.cpp:1120
CSG_Simple_Statistics::Get_Count
sLong Get_Count(void) const
Definition: mat_tools.h:743
CSG_Table::Get_Selection_Count
sLong Get_Selection_Count(void) const
Definition: table.h:425
CSG_Simple_Statistics::Get_Minimum
double Get_Minimum(void)
Definition: mat_tools.h:746
CSG_Array::Destroy
bool Destroy(void)
Definition: api_memory.cpp:291
CSG_PointCloud::Get_Record
virtual CSG_Table_Record * Get_Record(sLong Index) const
Definition: pointcloud.cpp:1393
INTERSECTION_None
@ INTERSECTION_None
Definition: geo_tools.h:102
CSG_Table::_Set_Selection
bool _Set_Selection(sLong Index, sLong Selected)
Definition: table_selection.cpp:74
CSG_PointCloud::Get_Value
virtual double Get_Value(int Field) const
Definition: pointcloud.h:165
CSG_File::is_Writing
bool is_Writing(void) const
Definition: api_core.h:1147
CSG_Point_3D
Definition: geo_tools.h:272
CSG_PointCloud::_Stats_Update
virtual bool _Stats_Update(int Field) const
Definition: pointcloud.cpp:1248
SG_Get_Distance
double SG_Get_Distance(double ax, double ay, double bx, double by, bool bPolar)
Definition: geo_functions.cpp:103
sLong
signed long long sLong
Definition: api_core.h:158
CSG_MetaData::Add_Property
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition: metadata.cpp:559
SG_Data_Type_is_Numeric
bool SG_Data_Type_is_Numeric(TSG_Data_Type Type)
Definition: api_core.cpp:198
CSG_Table::Get_Count
sLong Get_Count(void) const
Definition: table.h:397
SG_OMP_Get_Max_Num_Procs
int SG_OMP_Get_Max_Num_Procs(void)
Definition: api_core.cpp:111
SG_DATATYPE_Float
@ SG_DATATYPE_Float
Definition: api_core.h:1004
CSG_Simple_Statistics::Invalidate
void Invalidate(void)
Definition: mat_tools.cpp:447
CSG_PointCloud::Get_Shape
virtual CSG_Shape * Get_Shape(const CSG_Point &Point, double Epsilon=0.)
Definition: pointcloud.cpp:1406
CSG_PointCloud::Del_Field
virtual bool Del_Field(int Field)
Definition: pointcloud.cpp:753
CSG_Simple_Statistics::is_Evaluated
int is_Evaluated(void) const
Definition: mat_tools.h:739
SG_UI_Progress_Lock
int SG_UI_Progress_Lock(bool bOn)
Definition: api_callback.cpp:176
CSG_Table::Get_Maximum
double Get_Maximum(int iField) const
Definition: table.h:381
CSG_Data_Object::Get_File_Name
const SG_Char * Get_File_Name(bool bNative=true) const
Definition: dataobject.cpp:390
CSG_Table::Del_Index
bool Del_Index(void)
Definition: table.cpp:1368
CSG_PointCloud::Get_Header_Content
static bool Get_Header_Content(const CSG_String &FileName, CSG_MetaData &Header)
Definition: pointcloud.cpp:423
CSG_Archive::Get_File
bool Get_File(const SG_Char *Name)
Definition: api_file.cpp:760
CSG_Table::m_nBuffer
sLong m_nBuffer
Definition: table.h:462
CSG_PointCloud::Inv_Selection
virtual sLong Inv_Selection(void)
Definition: pointcloud.cpp:1651
pointcloud.h
CSG_Array::Create
void * Create(const CSG_Array &Array)
Definition: api_memory.cpp:250
CSG_PointCloud::Set_Modified
virtual void Set_Modified(bool bModified=true)
Definition: pointcloud.h:198
SG_FILE_W
@ SG_FILE_W
Definition: api_core.h:1112
SSG_Rect::yMax
double yMax
Definition: geo_tools.h:468
CSG_Projection::Load
bool Load(const CSG_String &File)
Definition: projections.cpp:253
SG_DATATYPE_Date
@ SG_DATATYPE_Date
Definition: api_core.h:1007
SG_DATATYPE_Word
@ SG_DATATYPE_Word
Definition: api_core.h:998
CSG_Shapes::Get_Extent
virtual const CSG_Rect & Get_Extent(void)
Definition: shapes.h:811
CSG_Shapes::m_Vertex_Type
TSG_Vertex_Type m_Vertex_Type
Definition: shapes.h:847
CSG_Table_Record::Set_Modified
void Set_Modified(bool bOn=true)
Definition: table_record.cpp:220
CSG_Simple_Statistics::Set_Count
bool Set_Count(sLong Count)
Definition: mat_tools.cpp:424
CSG_PointCloud::Set_Cursor
bool Set_Cursor(sLong Index)
Definition: pointcloud.h:163
CSG_PointCloud::is_Selected
virtual bool is_Selected(sLong Index) const
Definition: pointcloud.cpp:1562
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
CSG_Table::Add_Field
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Position=-1)
Definition: table.cpp:474
gSG_Data_Type_Identifier
const char gSG_Data_Type_Identifier[][32]
Definition: api_core.h:1040
SG_File_Set_Extension
SAGA_API_DLL_EXPORT bool SG_File_Set_Extension(CSG_String &FileName, const CSG_String &Extension)
Definition: api_file.cpp:1097
CSG_File::Length
sLong Length(void) const
Definition: api_file.cpp:229
CSG_Archive::Add_File
bool Add_File(const SG_Char *Name, bool bBinary=true)
Definition: api_file.cpp:700
CSG_Table::_Add_Selection
bool _Add_Selection(sLong Index)
Definition: table_selection.cpp:63
SG_Char
#define SG_Char
Definition: api_core.h:536
CSG_PointCloud::Mov_Field
virtual bool Mov_Field(int Field, int Position)
Definition: pointcloud.cpp:808
CSG_PointCloud::Create
bool Create(void)
Definition: pointcloud.cpp:124
CSG_PointCloud::On_Update
virtual bool On_Update(void)
Definition: pointcloud.cpp:1220
CSG_String
Definition: api_core.h:563
SHAPE_TYPE_Point
@ SHAPE_TYPE_Point
Definition: shapes.h:102
CSG_Shape::Set_Point
virtual int Set_Point(double x, double y, int iPoint=0, int iPart=0)=0
CSG_MetaData
Definition: metadata.h:88
POINTCLOUD_FILE_FORMAT_Compressed
@ POINTCLOUD_FILE_FORMAT_Compressed
Definition: pointcloud.h:92
CSG_Table::Get_Minimum
double Get_Minimum(int iField) const
Definition: table.h:380
SSG_Point_3D::y
double y
Definition: geo_tools.h:266
CSG_MetaData::Load
bool Load(const CSG_String &File, const SG_Char *Extension=NULL)
Definition: metadata.cpp:786
SG_UI_Process_Set_Progress
bool SG_UI_Process_Set_Progress(int Position, int Range)
Definition: api_callback.cpp:255
CSG_PointCloud::Get_Point
TSG_Point_3D Get_Point(void) const
Definition: pointcloud.cpp:1025
SSG_Point::x
double x
Definition: geo_tools.h:129
CSG_Table_Record::Set_Value
bool Set_Value(int Field, const CSG_String &Value)
Definition: table_record.cpp:270
POINTCLOUD_FILE_FORMAT_Undefined
@ POINTCLOUD_FILE_FORMAT_Undefined
Definition: pointcloud.h:90
SSG_Rect::yMin
double yMin
Definition: geo_tools.h:468
SG_DATATYPE_Short
@ SG_DATATYPE_Short
Definition: api_core.h:999
SG_OMP_Get_Thread_Num
int SG_OMP_Get_Thread_Num(void)
Definition: api_core.cpp:112
CSG_Data_Object::Load_MetaData
bool Load_MetaData(const CSG_String &FileName)
Definition: dataobject.cpp:654
CSG_Table::Get_Selection_Index
sLong Get_Selection_Index(sLong Index=0) const
Definition: table.h:426
CSG_Table::m_nFields
int m_nFields
Definition: table.h:460
CSG_PointCloud::CSG_PointCloud
CSG_PointCloud(void)
Definition: pointcloud.cpp:116
CSG_Data_Object::asPointCloud
class CSG_PointCloud * asPointCloud(bool bPolymorph=false) const
Definition: dataobject.cpp:539
CSG_Data_Manager::PointCloud
CSG_Data_Collection & PointCloud(void) const
Definition: data_manager.h:136
SSG_Point::y
double y
Definition: geo_tools.h:129
CSG_MetaData::Set_Name
void Set_Name(const CSG_String &Name)
Definition: metadata.h:129
CSG_Data_Object::Set_NoData_Value
virtual bool Set_NoData_Value(double Value)
Definition: dataobject.cpp:572
SSG_Point_3D::z
double z
Definition: geo_tools.h:266
CSG_PointCloud::_On_Construction
virtual void _On_Construction(void)
Definition: pointcloud.cpp:186
CSG_PointCloud::Get_Selection
virtual CSG_Shape * Get_Selection(sLong Index=0)
Definition: pointcloud.cpp:1573
SG_File_Make_Path
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
Definition: api_file.cpp:1058
CSG_Shapes
Definition: shapes.h:773
CSG_String::c_str
const SG_Char * c_str(void) const
Definition: api_string.cpp:236
CSG_File::Write
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition: api_file.cpp:369
CSG_PointCloud
Definition: pointcloud.h:105
SG_UI_Process_Set_Ready
bool SG_UI_Process_Set_Ready(void)
Definition: api_callback.cpp:305
TSG_Data_Type
TSG_Data_Type
Definition: api_core.h:994
CSG_Table::Select
virtual bool Select(sLong Index, bool bInvert=false)
Definition: table_selection.cpp:136
SG_Realloc
SAGA_API_DLL_EXPORT void * SG_Realloc(void *memblock, size_t size)
Definition: api_memory.cpp:77
CSG_MetaData::Add_Child
CSG_MetaData * Add_Child(void)
Definition: metadata.cpp:166
CSG_Table::Get_Field_Type
TSG_Data_Type Get_Field_Type(int iField) const
Definition: table.h:363
CSG_Index::Get_Count
sLong Get_Count(void) const
Definition: mat_tools.h:239
CSG_Projection::Create
bool Create(const CSG_Projection &Projection)
Definition: projections.cpp:96
CSG_PointCloud::On_Delete
virtual bool On_Delete(void)
Definition: pointcloud.cpp:1312
CSG_PointCloud::Add_Point
bool Add_Point(double x, double y, double z)
Definition: pointcloud.cpp:1095
CSG_Simple_Statistics
Definition: mat_tools.h:723
uLong
unsigned long long uLong
Definition: api_core.h:159
CSG_Shape
Definition: shapes.h:141
CSG_Table::Set_Field_Type
virtual bool Set_Field_Type(int iField, TSG_Data_Type Type)
Definition: table.cpp:619
SG_DATATYPE_Char
@ SG_DATATYPE_Char
Definition: api_core.h:997
CSG_Table_Record::is_Modified
bool is_Modified(void) const
Definition: table.h:245
CSG_Data_Object::Get_Projection
CSG_Projection & Get_Projection(void)
Definition: dataobject.cpp:637
CSG_PointCloud::Ins_Record
virtual CSG_Table_Record * Ins_Record(sLong Index, CSG_Table_Record *pCopy=NULL)
Definition: pointcloud.cpp:1437
CSG_Data_Object::Destroy
virtual bool Destroy(void)
Definition: dataobject.cpp:281
SG_VERTEX_TYPE_XYZ
@ SG_VERTEX_TYPE_XYZ
Definition: shapes.h:93
CSG_File::is_Reading
bool is_Reading(void) const
Definition: api_core.h:1146
CSG_PointCloud::Save
virtual bool Save(const CSG_String &File, int Format=0)
Definition: pointcloud.cpp:329
SG_DATATYPE_ULong
@ SG_DATATYPE_ULong
Definition: api_core.h:1002
CSG_Table::m_nRecords
sLong m_nRecords
Definition: table.h:462
CSG_File::Tell
sLong Tell(void) const
Definition: api_file.cpp:264
PC_FILE_VERSION
#define PC_FILE_VERSION
Definition: pointcloud.cpp:61
SG_UI_Msg_Add
void SG_UI_Msg_Add(const char *Message, bool bNewLine, TSG_UI_MSG_STYLE Style)
Definition: api_callback.cpp:502
CSG_PointCloud::Add_Shape
virtual CSG_Shape * Add_Shape(CSG_Table_Record *pCopy=NULL, TSG_ADD_Shape_Copy_Mode mCopy=SHAPE_COPY)
Definition: pointcloud.cpp:1449
SG_DATATYPE_Double
@ SG_DATATYPE_Double
Definition: api_core.h:1005