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