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