SAGA API v9.10
Loading...
Searching...
No Matches
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//---------------------------------------------------------
88CSG_PointCloud * SG_Create_PointCloud(const char *File) { return( SG_Create_PointCloud(CSG_String(File)) ); }
89CSG_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//---------------------------------------------------------
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{
135 _On_Construction(); Create(PointCloud);
136}
137
139{
140 return( Assign((CSG_Data_Object *)&PointCloud) );
141}
142
143//---------------------------------------------------------
151
152bool CSG_PointCloud::Create(const char *File) { return( Create(CSG_String(File)) ); }
153bool 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
192
193 m_Shapes.Create(SHAPE_TYPE_Point, NULL, NULL, SG_VERTEX_TYPE_XYZ);
194 m_Shapes.Set_Count(SG_OMP_Get_Max_Num_Procs());
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//---------------------------------------------------------
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//---------------------------------------------------------
241bool 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
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//---------------------------------------------------------
313bool 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
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 //-----------------------------------------------------
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
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//---------------------------------------------------------
440bool 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//---------------------------------------------------------
519bool 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
545 {
546 Stream.Write(m_Points[i] + 1, nPointBytes);
547 }
548
549 return( true );
550}
551
552//---------------------------------------------------------
553CSG_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//---------------------------------------------------------
594bool 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
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//---------------------------------------------------------
652bool 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//---------------------------------------------------------
662bool 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 ));
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//---------------------------------------------------------
777bool 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//---------------------------------------------------------
837int 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//---------------------------------------------------------
882bool 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//---------------------------------------------------------
921double 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//---------------------------------------------------------
949bool 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 :
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//---------------------------------------------------------
974bool 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 :
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//---------------------------------------------------------
1080bool 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();
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();
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
1151 m_Selection.Set_Array(0);
1152
1153 Set_Modified();
1156
1157 return( true );
1158}
1159
1160
1162// //
1163// //
1164// //
1166
1167//---------------------------------------------------------
1168bool 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//---------------------------------------------------------
1181bool 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//---------------------------------------------------------
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//---------------------------------------------------------
1282CSG_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//---------------------------------------------------------
1341void 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//---------------------------------------------------------
1368sLong 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//---------------------------------------------------------
1394CSG_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//---------------------------------------------------------
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//---------------------------------------------------------
1447bool 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 {
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//---------------------------------------------------------
1485bool CSG_PointCloud::Select(CSG_Table_Record *pShape, bool bInvert)
1486{
1487 return( CSG_Table::Select(pShape, bInvert) );
1488}
1489
1490//---------------------------------------------------------
1491bool 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//---------------------------------------------------------
1516bool 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
1562 m_Extent_Selected.Assign(r);
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 {
1584 m_Selection.Set_Array(0);
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();
1610 }
1611
1612 return( n );
1613}
1614
1615//---------------------------------------------------------
1617{
1618 if( m_Selection.Set_Array(m_nRecords - Get_Selection_Count()) )
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//---------------------------------------------------------
void SG_UI_Msg_Add(const char *Message, bool bNewLine, TSG_UI_MSG_STYLE Style)
bool SG_UI_Process_Set_Ready(void)
bool SG_UI_Process_Set_Progress(int Position, int Range)
int SG_UI_Progress_Lock(bool bOn)
int SG_OMP_Get_Max_Num_Procs(void)
Definition api_core.cpp:111
int SG_OMP_Get_Thread_Num(void)
Definition api_core.cpp:112
bool SG_Data_Type_is_Numeric(TSG_Data_Type Type)
Definition api_core.cpp:198
@ SG_UI_MSG_STYLE_FAILURE
Definition api_core.h:1585
@ SG_UI_MSG_STYLE_SUCCESS
Definition api_core.h:1584
unsigned long long uLong
Definition api_core.h:159
SAGA_API_DLL_EXPORT bool SG_File_Cmp_Extension(const CSG_String &File, const CSG_String &Extension)
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
signed long long sLong
Definition api_core.h:158
#define SG_T(s)
Definition api_core.h:537
SAGA_API_DLL_EXPORT void SG_Free(void *memblock)
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
SAGA_API_DLL_EXPORT bool SG_File_Delete(const CSG_String &FileName)
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
SAGA_API_DLL_EXPORT void * SG_Realloc(void *memblock, size_t size)
SAGA_API_DLL_EXPORT void * SG_Calloc(size_t num, size_t size)
const char gSG_Data_Type_Identifier[][32]
Definition api_core.h:1043
SAGA_API_DLL_EXPORT bool SG_File_Set_Extension(CSG_String &File, const CSG_String &Extension)
TSG_Data_Type
Definition api_core.h:997
@ SG_DATATYPE_Long
Definition api_core.h:1006
@ SG_DATATYPE_Byte
Definition api_core.h:999
@ SG_DATATYPE_Short
Definition api_core.h:1002
@ SG_DATATYPE_Word
Definition api_core.h:1001
@ SG_DATATYPE_ULong
Definition api_core.h:1005
@ SG_DATATYPE_Float
Definition api_core.h:1007
@ SG_DATATYPE_Undefined
Definition api_core.h:1013
@ SG_DATATYPE_Double
Definition api_core.h:1008
@ SG_DATATYPE_Color
Definition api_core.h:1011
@ SG_DATATYPE_Int
Definition api_core.h:1004
@ SG_DATATYPE_Char
Definition api_core.h:1000
@ SG_DATATYPE_String
Definition api_core.h:1009
@ SG_DATATYPE_DWord
Definition api_core.h:1003
@ SG_DATATYPE_Date
Definition api_core.h:1010
#define SG_Char
Definition api_core.h:536
#define _TL(s)
Definition api_core.h:1568
@ SG_FILE_W
Definition api_core.h:1115
@ SG_FILE_R
Definition api_core.h:1114
bool Add_File(const SG_Char *Name, bool bBinary=true)
Definition api_file.cpp:705
bool Get_File(const SG_Char *Name)
Definition api_file.cpp:765
bool Set_Array(sLong nValues, bool bShrink=true)
void Set_Update_Flag(bool bOn=true)
Definition dataobject.h:285
bool Save_MetaData(const CSG_String &FileName)
double Get_NoData_Value(bool bUpper=false) const
Definition dataobject.h:253
const SG_Char * Get_File_Name(bool bNative=true) const
bool Load_MetaData(const CSG_String &FileName)
virtual bool Destroy(void)
class CSG_PointCloud * asPointCloud(bool bPolymorph=false) const
virtual bool Set_NoData_Value(double Value)
virtual bool Assign(CSG_Data_Object *pObject, bool bProgress=false)
CSG_Projection & Get_Projection(void)
void Set_File_Name(const CSG_String &FileName)
sLong Length(void) const
Definition api_file.cpp:230
sLong Tell(void) const
Definition api_file.cpp:265
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:370
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:338
bool is_Writing(void) const
Definition api_core.h:1151
bool is_Reading(void) const
Definition api_core.h:1150
sLong Get_Count(void) const
Definition mat_tools.h:241
bool Save(const CSG_String &File, const SG_Char *Extension=NULL) const
Definition metadata.cpp:879
void Set_Name(const CSG_String &Name)
Definition metadata.h:130
CSG_MetaData * Add_Child(void)
Definition metadata.cpp:166
bool Load(const CSG_String &File, const SG_Char *Extension=NULL)
Definition metadata.cpp:786
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition metadata.cpp:559
bool Del_Point(sLong Index)
TSG_Point_3D Get_Point(void) const
bool Set_Cursor(sLong Index)
Definition pointcloud.h:165
virtual bool Set_Point(const TSG_Point_3D &Point)
virtual bool Destroy(void)
bool Add_Point(double x, double y, double z)
virtual CSG_Shape * Add_Shape(CSG_Table_Record *pCopy=NULL, TSG_ADD_Shape_Copy_Mode mCopy=SHAPE_COPY)
virtual bool Save(const CSG_String &File, int Format=0)
virtual bool Del_Field(int Field)
virtual const CSG_Rect & Get_Selection_Extent(void)
virtual CSG_Table_Record * Get_Record(sLong Index) const
virtual CSG_Table_Record * Ins_Record(sLong Index, CSG_Table_Record *pCopy=NULL)
virtual void Set_Modified(bool bModified=true)
Definition pointcloud.h:204
virtual CSG_Shape * Get_Shape(const CSG_Point &Point, double Epsilon=0.)
virtual bool Assign(CSG_Data_Object *pSource, bool bProgress=false)
bool is_Compatible(CSG_PointCloud *pPointCloud) const
virtual double Get_Value(int Field) const
Definition pointcloud.h:167
virtual bool On_Update(void)
virtual bool Sort(const CSG_Index &Index)
virtual bool Mov_Field(int Field, int Position)
virtual sLong Inv_Selection(void)
virtual bool On_Delete(void)
virtual ~CSG_PointCloud(void)
static bool Get_Header_Content(const CSG_String &FileName, CSG_MetaData &Header)
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
virtual void _On_Construction(void)
virtual bool is_Selected(sLong Index) const
bool Del_Points(void)
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Field=-1)
virtual bool On_Reload(void)
virtual CSG_Table_Record * Get_Selection(sLong Index=0) const
virtual int Get_Field_Length(int Field, int Encoding=SG_FILE_ENCODING_UNDEFINED) const
virtual bool Set_Value(int Field, double Value)
Definition pointcloud.h:166
double Get_X(void) const
Definition pointcloud.h:168
virtual bool Set_Field_Type(int Field, TSG_Data_Type Type)
virtual sLong Del_Selection(void)
virtual bool _Stats_Update(int Field) const
virtual bool Select(sLong Index, bool bInvert=false)
bool Create(void)
double Get_Y(void) const
Definition pointcloud.h:169
bool Save(const CSG_String &File, ESG_CRS_Format Format=ESG_CRS_Format::WKT) const
bool Create(const CSG_Projection &Projection)
bool Load(const CSG_String &File)
bool Contains(double x, double y) const
TSG_Intersection Intersects(const CSG_Rect &Rect) const
virtual TSG_Point Get_Point(int iPoint=0) const =0
virtual int Set_Point(double x, double y, int iPoint=0, int iPart=0)=0
virtual double Get_Z(int iPoint=0, int iPart=0, bool bAscending=true) const
Definition shapes.h:192
virtual const CSG_Rect & Get_Extent(void)
Definition shapes.h:810
CSG_Shapes(void)
Definition shapes.cpp:156
virtual CSG_Shape * Get_Shape(const CSG_Point &Point, double Epsilon=0.)
Definition shapes.cpp:483
double m_ZMax
Definition shapes.h:841
TSG_Shape_Type m_Type
Definition shapes.h:843
double m_ZMin
Definition shapes.h:841
TSG_Vertex_Type m_Vertex_Type
Definition shapes.h:845
friend class CSG_Shape
Definition shapes.h:773
CSG_Rect m_Extent_Selected
Definition shapes.h:847
int is_Evaluated(void) const
Definition mat_tools.h:741
static CSG_String Format(const char *Format,...)
const SG_Char * c_str(void) const
int Printf(const char *Format,...)
bool is_Empty(void) const
TSG_Data_Type m_Type
Definition table.h:474
void Set_Modified(bool bOn=true)
sLong m_Index
Definition table.h:256
bool Set_Value(int Field, const CSG_String &Value)
bool is_Modified(void) const
Definition table.h:245
void Set_Selected(bool bOn=true)
double asDouble(int Field) const
class CSG_Table * Get_Table(void)
Definition table.h:135
const SG_Char * asString(int Field, int Decimals=-99) const
const SG_Char * Get_Field_Name(int Field) const
Definition table.h:362
virtual bool _Stats_Update(int Field) const
Definition table.cpp:1252
sLong Get_Count(void) const
Definition table.h:400
bool _Set_Selection(sLong Index, sLong Selected)
double Get_Minimum(int Field) const
Definition table.h:381
sLong m_nRecords
Definition table.h:489
bool _Stats_Invalidate(void) const
Definition table.cpp:1228
virtual bool Select(sLong Index, bool bInvert=false)
CSG_Field_Info ** m_Field_Info
Definition table.h:485
friend class CSG_Table_Record
Definition table.h:286
CSG_Array m_Selection
Definition table.h:491
int Get_Field_Count(void) const
Definition table.h:361
bool _Add_Selection(sLong Index)
sLong m_nBuffer
Definition table.h:489
int m_nFields
Definition table.h:487
CSG_Rect m_Extent
Definition table.h:493
sLong Get_Selection_Index(sLong Index=0) const
Definition table.h:429
sLong Get_Selection_Count(void) const
Definition table.h:428
bool Del_Index(void)
Definition table.cpp:1419
bool _Del_Selection(sLong Index)
TSG_Data_Type Get_Field_Type(int Field) const
Definition table.h:363
double Get_Maximum(int Field) const
Definition table.h:382
double SG_Get_Distance(double ax, double ay, double bx, double by, bool bPolar)
struct SSG_Point TSG_Point
struct SSG_Point_3D TSG_Point_3D
@ INTERSECTION_None
Definition geo_tools.h:102
struct SSG_Rect TSG_Rect
#define PC_SIZE_TYPE(type)
#define PC_SIZE_STRING
CSG_PointCloud * SG_Create_PointCloud(void)
#define PC_FILE_VERSION
#define PC_SIZE_FIELD(field)
@ POINTCLOUD_FILE_FORMAT_Compressed
Definition pointcloud.h:92
@ POINTCLOUD_FILE_FORMAT_Undefined
Definition pointcloud.h:90
@ POINTCLOUD_FILE_FORMAT_Normal
Definition pointcloud.h:91
@ SG_VERTEX_TYPE_XYZ
Definition shapes.h:93
TSG_ADD_Shape_Copy_Mode
Definition shapes.h:124
@ SHAPE_COPY
Definition shapes.h:128
@ SHAPE_COPY_ATTR
Definition shapes.h:127
@ SHAPE_TYPE_Point
Definition shapes.h:102
double x
Definition geo_tools.h:129
double y
Definition geo_tools.h:129
double xMin
Definition geo_tools.h:468
double xMax
Definition geo_tools.h:468
double yMin
Definition geo_tools.h:468
double yMax
Definition geo_tools.h:468
#define SG_TABLE_REC_FLAG_Selected
Definition table.h:119