1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // dataobject.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 // e-mail: oconrad@saga-gis.org //
49 // //
50 ///////////////////////////////////////////////////////////
51
52 //---------------------------------------------------------
53
54
55 ///////////////////////////////////////////////////////////
56 // //
57 // class CData_Object //
58 // //
59 ///////////////////////////////////////////////////////////
60
61 //---------------------------------------------------------
62 #include "dataobject.h"
63
64 #include <wx/string.h>
65
66
67 ///////////////////////////////////////////////////////////
68 // //
69 // //
70 // //
71 ///////////////////////////////////////////////////////////
72
73 //---------------------------------------------------------
SG_Get_Create_Pointer(void)74 void * SG_Get_Create_Pointer(void)
75 {
76 return( DATAOBJECT_CREATE );
77 }
78
79 //---------------------------------------------------------
SG_Get_DataObject_Identifier(TSG_Data_Object_Type Type)80 CSG_String SG_Get_DataObject_Identifier(TSG_Data_Object_Type Type)
81 {
82 switch( Type )
83 {
84 default : return( "UNDEFINED" );
85 case SG_DATAOBJECT_TYPE_Grid : return( "GRID" );
86 case SG_DATAOBJECT_TYPE_Grids : return( "GRIDS" );
87 case SG_DATAOBJECT_TYPE_Table : return( "TABLE" );
88 case SG_DATAOBJECT_TYPE_Shapes : return( "SHAPES" );
89 case SG_DATAOBJECT_TYPE_TIN : return( "TIN" );
90 case SG_DATAOBJECT_TYPE_PointCloud: return( "POINTS" );
91 }
92 }
93
94 //---------------------------------------------------------
SG_Get_DataObject_Name(TSG_Data_Object_Type Type)95 CSG_String SG_Get_DataObject_Name(TSG_Data_Object_Type Type)
96 {
97 switch( Type )
98 {
99 default : return( _TL("Undefined" ) );
100 case SG_DATAOBJECT_TYPE_Grid : return( _TL("Grid" ) );
101 case SG_DATAOBJECT_TYPE_Grids : return( _TL("Grids" ) );
102 case SG_DATAOBJECT_TYPE_Table : return( _TL("Table" ) );
103 case SG_DATAOBJECT_TYPE_Shapes : return( _TL("Shapes" ) );
104 case SG_DATAOBJECT_TYPE_TIN : return( _TL("TIN" ) );
105 case SG_DATAOBJECT_TYPE_PointCloud: return( _TL("Point Cloud") );
106 }
107 }
108
109
110 ///////////////////////////////////////////////////////////
111 // //
112 // Data Object Statistics //
113 // //
114 ///////////////////////////////////////////////////////////
115
116 //---------------------------------------------------------
117 static sLong gSG_DataObject_Max_Samples = 0;
118
119 //---------------------------------------------------------
SG_DataObject_Set_Max_Samples(sLong Max_Samples)120 bool SG_DataObject_Set_Max_Samples (sLong Max_Samples)
121 {
122 if( Max_Samples >= 0 )
123 {
124 gSG_DataObject_Max_Samples = Max_Samples;
125
126 return( true );
127 }
128
129 return( false );
130 }
131
132 //---------------------------------------------------------
SG_DataObject_Get_Max_Samples(void)133 sLong SG_DataObject_Get_Max_Samples (void)
134 {
135 return( gSG_DataObject_Max_Samples );
136 }
137
138
139 ///////////////////////////////////////////////////////////
140 // //
141 // //
142 // //
143 ///////////////////////////////////////////////////////////
144
145 //---------------------------------------------------------
146 int g_History_Depth = -1;
147
SG_Set_History_Depth(int Depth)148 void SG_Set_History_Depth (int Depth)
149 {
150 g_History_Depth = Depth;
151 }
152
SG_Get_History_Depth(void)153 int SG_Get_History_Depth (void)
154 {
155 return( g_History_Depth );
156 }
157
158 //---------------------------------------------------------
159 int g_History_Ignore_Lists = true;
160
SG_Set_History_Ignore_Lists(int Ignore)161 void SG_Set_History_Ignore_Lists (int Ignore)
162 {
163 g_History_Ignore_Lists = Ignore != 0;
164 }
165
SG_Get_History_Ignore_Lists(void)166 int SG_Get_History_Ignore_Lists (void)
167 {
168 return( g_History_Ignore_Lists );
169 }
170
171
172 ///////////////////////////////////////////////////////////
173 // //
174 // //
175 // //
176 ///////////////////////////////////////////////////////////
177
178 //---------------------------------------------------------
CSG_Data_Object(void)179 CSG_Data_Object::CSG_Data_Object(void)
180 {
181 m_MetaData.Set_Name("SAGA_METADATA");
182
183 m_pMD_Database = m_MetaData.Add_Child(SG_META_DATABASE);
184 m_pMD_Source = m_MetaData.Add_Child(SG_META_SOURCE );
185 m_pMD_History = m_MetaData.Add_Child(SG_META_HISTORY );
186
187 //-----------------------------------------------------
188 m_File_bNative = false;
189 m_File_Type = 0;
190 m_bModified = true;
191
192 m_NoData_Value[0] = -99999.;
193 m_NoData_Value[1] = -99999.;
194
195 m_Max_Samples = gSG_DataObject_Max_Samples;
196
197 m_Name .Clear();
198 m_Description .Clear();
199
200 m_bUpdate = false;
201
202 m_pOwner = NULL;
203 }
204
205 //---------------------------------------------------------
~CSG_Data_Object(void)206 CSG_Data_Object::~CSG_Data_Object(void)
207 {
208 Destroy();
209 }
210
211 //---------------------------------------------------------
Destroy(void)212 bool CSG_Data_Object::Destroy(void)
213 {
214 m_Name.Clear(); m_Description.Clear();
215
216 m_pMD_Database->Destroy();
217 m_pMD_Source ->Destroy();
218 m_pMD_History ->Destroy();
219
220 return( true );
221 }
222
223
224 ///////////////////////////////////////////////////////////
225 // //
226 ///////////////////////////////////////////////////////////
227
228 //---------------------------------------------------------
Set_Name(const CSG_String & Name)229 void CSG_Data_Object::Set_Name(const CSG_String &Name)
230 {
231 if( Name.is_Empty() )
232 {
233 m_Name = _TL("Data");
234 }
235 else
236 {
237 m_Name = Name;
238 }
239 }
240
241 //---------------------------------------------------------
Fmt_Name(const char * Format,...)242 void CSG_Data_Object::Fmt_Name(const char *Format, ...)
243 {
244 wxString _s;
245
246 va_list argptr;
247
248 #ifdef _SAGA_LINUX
249 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
250 va_start(argptr, _Format); _s.PrintfV(_Format, argptr);
251 #else
252 va_start(argptr, Format); _s.PrintfV( Format, argptr);
253 #endif
254
255 va_end(argptr);
256
257 Set_Name(CSG_String(&_s));
258 }
259
260 //---------------------------------------------------------
Fmt_Name(const wchar_t * Format,...)261 void CSG_Data_Object::Fmt_Name(const wchar_t *Format, ...)
262 {
263 wxString _s;
264
265 va_list argptr;
266
267 #ifdef _SAGA_LINUX
268 // workaround as we only use wide characters
269 // since wx 2.9.4 so interpret strings as multibyte
270 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
271 va_start(argptr, _Format); _s.PrintfV(_Format, argptr);
272 #else
273 va_start(argptr, Format); _s.PrintfV( Format, argptr);
274 #endif
275
276 va_end(argptr);
277
278 CSG_String s(&_s);
279
280 Set_Name(CSG_String(&_s));
281 }
282
283 //---------------------------------------------------------
Get_Name(void) const284 const SG_Char * CSG_Data_Object::Get_Name(void) const
285 {
286 return( m_Name );
287 }
288
289 //---------------------------------------------------------
Set_Description(const CSG_String & Description)290 void CSG_Data_Object::Set_Description(const CSG_String &Description)
291 {
292 m_Description = Description;
293 }
294
Get_Description(void) const295 const SG_Char * CSG_Data_Object::Get_Description(void) const
296 {
297 return( m_pOwner ? m_pOwner->m_Description : m_Description );
298 }
299
300 //---------------------------------------------------------
Set_File_Name(const CSG_String & FileName)301 void CSG_Data_Object::Set_File_Name (const CSG_String &FileName)
302 {
303 Set_File_Name(FileName, false);
304 }
305
306 //---------------------------------------------------------
Set_File_Name(const CSG_String & FileName,bool bNative)307 void CSG_Data_Object::Set_File_Name(const CSG_String &FileName, bool bNative)
308 {
309 m_FileName = FileName;
310 m_File_bNative = bNative;
311
312 m_Name = SG_File_Get_Name(FileName, false);
313
314 m_bModified = false;
315 }
316
317 //---------------------------------------------------------
Get_File_Name(bool bNative) const318 const SG_Char * CSG_Data_Object::Get_File_Name(bool bNative) const
319 {
320 if( bNative && !m_File_bNative )
321 {
322 return( SG_T("") );
323 }
324
325 if( m_pOwner )
326 {
327 if( m_pOwner->Get_ObjectType() == SG_DATAOBJECT_TYPE_Grids )
328 {
329 return( m_pOwner->m_FileName.c_str() );
330 }
331 }
332
333 return( m_FileName.c_str() );
334 }
335
336 //---------------------------------------------------------
Get_File_Type(void) const337 int CSG_Data_Object::Get_File_Type(void) const
338 {
339 return( m_File_Type );
340 }
341
342
343 ///////////////////////////////////////////////////////////
344 // //
345 ///////////////////////////////////////////////////////////
346
347 //---------------------------------------------------------
Reload(void)348 bool CSG_Data_Object::Reload(void)
349 {
350 return( m_File_bNative && SG_File_Exists(m_FileName) && On_Reload() );
351 }
352
353 //---------------------------------------------------------
Delete(void)354 bool CSG_Data_Object::Delete(void)
355 {
356 if( m_File_bNative && SG_File_Exists(m_FileName) && On_Delete() )
357 {
358 CSG_String FileName = m_FileName;
359
360 switch( Get_ObjectType() )
361 {
362 case SG_DATAOBJECT_TYPE_Grid : SG_File_Set_Extension(FileName, "mgrd" ); break;
363 case SG_DATAOBJECT_TYPE_Grids : SG_File_Set_Extension(FileName, "sg-info"); break;
364 case SG_DATAOBJECT_TYPE_Table : SG_File_Set_Extension(FileName, "mtab" ); break;
365 case SG_DATAOBJECT_TYPE_Shapes : SG_File_Set_Extension(FileName, "mshp" ); break;
366 case SG_DATAOBJECT_TYPE_TIN : SG_File_Set_Extension(FileName, "sg-info"); break;
367 case SG_DATAOBJECT_TYPE_PointCloud: SG_File_Set_Extension(FileName, "sg-info"); break;
368 default : SG_File_Set_Extension(FileName, "sg-info"); break;
369 }
370
371 SG_File_Delete(FileName);
372
373 SG_File_Set_Extension(FileName, "prj"); SG_File_Delete(FileName);
374 SG_File_Set_Extension(FileName, "sg-prj"); SG_File_Delete(FileName);
375
376 //-------------------------------------------------
377 m_FileName = "";
378 m_File_bNative = false;
379 m_File_Type = 0;
380
381 m_bModified = true;
382
383 m_pMD_Database->Destroy();
384
385 return( true );
386 }
387
388 return( false );
389 }
390
391
392 ///////////////////////////////////////////////////////////
393 // //
394 ///////////////////////////////////////////////////////////
395
396 //---------------------------------------------------------
Set_NoData_Value(double Value)397 bool CSG_Data_Object::Set_NoData_Value(double Value)
398 {
399 return( Set_NoData_Value_Range(Value, Value) );
400 }
401
402 //---------------------------------------------------------
Set_NoData_Value_Range(double Lower,double Upper)403 bool CSG_Data_Object::Set_NoData_Value_Range(double Lower, double Upper)
404 {
405 if( Lower > Upper )
406 {
407 double d = Lower; Lower = Upper; Upper = d;
408 }
409
410 if( Lower != m_NoData_Value[0] || Upper != m_NoData_Value[1] )
411 {
412 m_NoData_Value[0] = Lower;
413 m_NoData_Value[1] = Upper;
414
415 Set_Modified();
416
417 On_NoData_Changed();
418
419 return( true );
420 }
421
422 return( false );
423 }
424
425 //---------------------------------------------------------
On_NoData_Changed(void)426 bool CSG_Data_Object::On_NoData_Changed(void)
427 {
428 if( !Get_Update_Flag() )
429 {
430 Set_Update_Flag();
431 }
432
433 return( true );
434 }
435
436
437 ///////////////////////////////////////////////////////////
438 // //
439 ///////////////////////////////////////////////////////////
440
441 //---------------------------------------------------------
Set_Max_Samples(sLong Max_Samples)442 bool CSG_Data_Object::Set_Max_Samples(sLong Max_Samples)
443 {
444 #define Min_Samples 100
445
446 if( m_Max_Samples != Max_Samples && Max_Samples >= Min_Samples )
447 {
448 m_Max_Samples = Max_Samples;
449
450 On_Update();
451 }
452
453 return( true );
454 }
455
456
457 ///////////////////////////////////////////////////////////
458 // //
459 ///////////////////////////////////////////////////////////
460
461 //---------------------------------------------------------
Get_Projection(void)462 CSG_Projection & CSG_Data_Object::Get_Projection(void)
463 {
464 return( m_pOwner ? m_pOwner->m_Projection : m_Projection );
465 }
466
467 //---------------------------------------------------------
Get_Projection(void) const468 const CSG_Projection & CSG_Data_Object::Get_Projection(void) const
469 {
470 return( m_pOwner ? m_pOwner->m_Projection : m_Projection );
471 }
472
473
474 ///////////////////////////////////////////////////////////
475 // //
476 ///////////////////////////////////////////////////////////
477
478 //---------------------------------------------------------
Load_MetaData(const CSG_String & _FileName)479 bool CSG_Data_Object::Load_MetaData(const CSG_String &_FileName)
480 {
481 CSG_String FileName(_FileName);
482
483 switch( Get_ObjectType() )
484 {
485 case SG_DATAOBJECT_TYPE_Grid : SG_File_Set_Extension(FileName, "mgrd" ); break;
486 case SG_DATAOBJECT_TYPE_Grids : SG_File_Set_Extension(FileName, "sg-info"); break;
487 case SG_DATAOBJECT_TYPE_Table : SG_File_Set_Extension(FileName, "mtab" ); break;
488 case SG_DATAOBJECT_TYPE_Shapes : SG_File_Set_Extension(FileName, "mshp" ); break;
489 case SG_DATAOBJECT_TYPE_TIN : SG_File_Set_Extension(FileName, "sg-info"); break;
490 case SG_DATAOBJECT_TYPE_PointCloud: SG_File_Set_Extension(FileName, "sg-info");
491 if( !SG_File_Get_Extension(_FileName).CmpNoCase("spc") ) SG_File_Set_Extension(FileName, "mpts"); break;
492
493 default: return( false );
494 }
495
496 CSG_File Stream(FileName, SG_FILE_R, false);
497
498 return( Load_MetaData(Stream) );
499 }
500
501 //---------------------------------------------------------
Save_MetaData(const CSG_String & _FileName)502 bool CSG_Data_Object::Save_MetaData(const CSG_String &_FileName)
503 {
504 CSG_String FileName(_FileName);
505
506 switch( Get_ObjectType() )
507 {
508 case SG_DATAOBJECT_TYPE_Grid : SG_File_Set_Extension(FileName, "mgrd" ); break;
509 case SG_DATAOBJECT_TYPE_Grids : SG_File_Set_Extension(FileName, "sg-info"); break;
510 case SG_DATAOBJECT_TYPE_Table : SG_File_Set_Extension(FileName, "mtab" ); break;
511 case SG_DATAOBJECT_TYPE_Shapes : SG_File_Set_Extension(FileName, "mshp" ); break;
512 case SG_DATAOBJECT_TYPE_TIN : SG_File_Set_Extension(FileName, "sg-info"); break;
513 case SG_DATAOBJECT_TYPE_PointCloud: SG_File_Set_Extension(FileName, "sg-info"); break;
514
515 default: return( false );
516 }
517
518 CSG_File Stream(FileName, SG_FILE_W, false);
519
520 return( Save_MetaData(Stream) );
521 }
522
523 //---------------------------------------------------------
Load_MetaData(CSG_File & Stream)524 bool CSG_Data_Object::Load_MetaData(CSG_File &Stream)
525 {
526 CSG_MetaData m;
527
528 if( !m.Load(Stream) )
529 {
530 return( false );
531 }
532
533 //-----------------------------------------------------
534 if( m("DESCRIPTION") && !m["DESCRIPTION"].Get_Content().is_Empty() )
535 {
536 Set_Description(m["DESCRIPTION"].Get_Content());
537 }
538
539 //-----------------------------------------------------
540 m_pMD_Source->Destroy();
541
542 if( m(SG_META_SOURCE) )
543 m_pMD_Source->Assign(m[SG_META_SOURCE]);
544
545 //-----------------------------------------------------
546 m_pMD_Database->Destroy();
547
548 if( m(SG_META_DATABASE) )
549 m_pMD_Database->Assign(m[SG_META_DATABASE]);
550
551 //-----------------------------------------------------
552 m_MetaData.Del_Child(SG_META_PROJECTION);
553
554 if( m(SG_META_PROJECTION) && m_Projection.Load(m[SG_META_PROJECTION]) )
555 m_MetaData.Add_Child(m[SG_META_PROJECTION]);
556 else if( m[SG_META_SOURCE](SG_META_PROJECTION) && m_Projection.Load(m[SG_META_SOURCE][SG_META_PROJECTION]) )
557 m_MetaData.Add_Child(m[SG_META_SOURCE][SG_META_PROJECTION]);
558
559 //-----------------------------------------------------
560 m_pMD_History->Destroy();
561
562 if( m(SG_META_HISTORY) )
563 m_pMD_History->Assign(m[SG_META_HISTORY]);
564 else
565 m_pMD_History->Add_Child(SG_META_FILEPATH, Get_File_Name());
566
567 return( true );
568 }
569
570 //---------------------------------------------------------
Save_MetaData(CSG_File & Stream)571 bool CSG_Data_Object::Save_MetaData(CSG_File &Stream)
572 {
573 //-----------------------------------------------------
574 if( m_MetaData(SG_META_FILEPATH) )
575 m_MetaData(SG_META_FILEPATH)->Set_Content(m_FileName);
576 else
577 m_MetaData.Add_Child(SG_META_FILEPATH, m_FileName);
578
579 //-----------------------------------------------------
580 if( m_MetaData("DESCRIPTION") )
581 m_MetaData("DESCRIPTION")->Set_Content(Get_Description());
582 else
583 m_MetaData.Add_Child("DESCRIPTION", Get_Description());
584
585 //-----------------------------------------------------
586 if( m_Projection.Get_Type() == SG_PROJ_TYPE_CS_Undefined )
587 m_MetaData.Del_Child(SG_META_PROJECTION);
588 else if( m_MetaData(SG_META_PROJECTION) )
589 m_Projection.Save(*m_MetaData(SG_META_PROJECTION));
590 else
591 m_Projection.Save(*m_MetaData.Add_Child(SG_META_PROJECTION));
592
593 //-----------------------------------------------------
594 return( m_MetaData.Save(Stream) );
595 }
596
597 //---------------------------------------------------------
Update(bool bForce)598 bool CSG_Data_Object::Update(bool bForce)
599 {
600 if( m_bUpdate || bForce )
601 {
602 m_bUpdate = false;
603
604 return( On_Update() );
605 }
606
607 return( true );
608 }
609
610
611 ///////////////////////////////////////////////////////////
612 // //
613 ///////////////////////////////////////////////////////////
614
615 //---------------------------------------------------------
Assign(CSG_Data_Object * pObject)616 bool CSG_Data_Object::Assign(CSG_Data_Object *pObject)
617 {
618 return( false );
619 }
620
621
622 ///////////////////////////////////////////////////////////
623 // //
624 ///////////////////////////////////////////////////////////
625
626 //---------------------------------------------------------
627 #include "tool_chain.h"
628
629 //---------------------------------------------------------
Save_History_to_Model(const CSG_String & File) const630 bool CSG_Data_Object::Save_History_to_Model(const CSG_String &File) const
631 {
632 return( CSG_Tool_Chain::Save_History_to_Model(Get_History(), File) );
633 }
634
635
636 ///////////////////////////////////////////////////////////
637 // //
638 // //
639 // //
640 ///////////////////////////////////////////////////////////
641
642 //---------------------------------------------------------
643