SAGA API  v9.5
shapes_io.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 // shapes_io.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 // //
51 
52 //---------------------------------------------------------
53 #include "shapes.h"
54 #include "table_dbase.h"
55 #include "tool_library.h"
56 #include "data_manager.h"
57 
58 
60 // //
61 // //
62 // //
64 
65 //---------------------------------------------------------
67 {
68  return( Create(Get_File_Name(false)) );
69 }
70 
71 //---------------------------------------------------------
73 {
74  CSG_String File_Name = Get_File_Name(true);
75 
76  SG_File_Delete(File_Name);
77 
78  SG_File_Set_Extension(File_Name, "shp"); SG_File_Delete(File_Name); // shapes
79  SG_File_Set_Extension(File_Name, "shx"); SG_File_Delete(File_Name); // shape index
80  SG_File_Set_Extension(File_Name, "dbf"); SG_File_Delete(File_Name); // attributes
81  SG_File_Set_Extension(File_Name, "prj"); SG_File_Delete(File_Name); // projection
82  SG_File_Set_Extension(File_Name, "sbn"); SG_File_Delete(File_Name); // spatial index
83  SG_File_Set_Extension(File_Name, "sbx"); SG_File_Delete(File_Name); // spatial index
84  SG_File_Set_Extension(File_Name, "atx"); SG_File_Delete(File_Name); // attribute index
85  SG_File_Set_Extension(File_Name, "xml"); SG_File_Delete(File_Name); // metadata
86  SG_File_Set_Extension(File_Name, "cpg"); SG_File_Delete(File_Name); // code page
87  SG_File_Set_Extension(File_Name, "qix"); SG_File_Delete(File_Name); // quadtree spatial index
88 
89  return( true );
90 }
91 
92 
94 // //
95 // //
96 // //
98 
99 //---------------------------------------------------------
101 
102 //---------------------------------------------------------
104 {
105  switch( Format )
106  {
111  return( true );
112  }
113 
114  return( false );
115 }
116 
117 //---------------------------------------------------------
119 {
121 }
122 
123 //---------------------------------------------------------
125 {
127  {
128  default:
129  case SHAPE_FILE_FORMAT_ESRI : return( "shp" );
130  case SHAPE_FILE_FORMAT_GeoPackage: return( "gpkg" );
131  case SHAPE_FILE_FORMAT_GeoJSON : return( "geojson" );
132  }
133 }
134 
135 
137 // //
139 
140 //---------------------------------------------------------
141 bool CSG_Shapes::Save(const CSG_String &File, int Format)
142 {
143  if( Format == SHAPE_FILE_FORMAT_Undefined )
144  {
146 
147  if( SG_File_Cmp_Extension(File, "shp" ) ) { Format = SHAPE_FILE_FORMAT_ESRI ; }
148  if( SG_File_Cmp_Extension(File, "gpkg" ) ) { Format = SHAPE_FILE_FORMAT_GeoPackage; }
149  if( SG_File_Cmp_Extension(File, "geojson") ) { Format = SHAPE_FILE_FORMAT_GeoJSON ; }
150 
151  if( SG_File_Cmp_Extension(File, "txt" ) ) { return( _Save_Text (File, true, '\t') ); }
152  if( SG_File_Cmp_Extension(File, "csv" ) ) { return( _Save_Text (File, true, ',') ); }
153  if( SG_File_Cmp_Extension(File, "dbf" ) ) { return( _Save_DBase(File) ); }
154  }
155 
156  //-----------------------------------------------------
157  bool bResult = false;
158 
159  SG_UI_Msg_Add(CSG_String::Format("%s %s: %s...", _TL("Saving"), _TL("shapes"), File.c_str()), true);
160 
161  switch( Format )
162  {
163  case SHAPE_FILE_FORMAT_ESRI : bResult = _Save_ESRI(File ); break;
164  case SHAPE_FILE_FORMAT_GeoPackage: bResult = _Save_GDAL(File, "GPKG" ); break;
165  case SHAPE_FILE_FORMAT_GeoJSON : bResult = _Save_GDAL(File, "GeoJSON"); break;
166  }
167 
168  //-----------------------------------------------------
169  if( bResult )
170  {
171  Set_Modified(false);
172 
173  Set_File_Name(File, true);
174 
176  SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
177 
178  return( true );
179  }
180 
182  SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
183 
184  return( false );
185 }
186 
187 
189 // //
190 // //
191 // //
193 
194 //---------------------------------------------------------
195 bool CSG_Shapes::_Load_GDAL(const CSG_String &File_Name)
196 {
197  CSG_Data_Manager Manager;
198 
199  CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("io_gdal", 3); // Import Shapes
200 
201  if( pTool )
202  {
203  if( pTool->Settings_Push(&Manager) && pTool->Set_Parameter("FILES", File_Name, PARAMETER_TYPE_FilePath) )
204  {
205  SG_UI_Msg_Lock(true);
206  pTool->Execute();
207  SG_UI_Msg_Lock(false);
208  }
209 
211  }
212 
213  //-----------------------------------------------------
214  CSG_Shapes *pShapes = Manager.Shapes().Count() ? Manager.Shapes()[0].asShapes() : NULL;
215 
216  if( !pShapes || !Create(*pShapes) )
217  {
218  return( false );
219  }
220 
221  Get_MetaData () = pShapes->Get_MetaData ();
222  Get_Projection() = pShapes->Get_Projection();
223 
224  //-----------------------------------------------------
225  if( SG_File_Cmp_Extension(File_Name, "gpkg" )
226  || SG_File_Cmp_Extension(File_Name, "GeoJSON") )
227  {
228  Set_File_Name(File_Name, true);
229  }
230  else
231  {
232  Set_File_Name(File_Name, false);
233  }
234 
235  return( true );
236 }
237 
238 //---------------------------------------------------------
239 bool CSG_Shapes::_Save_GDAL(const CSG_String &File_Name, const CSG_String &Driver)
240 {
241  bool bResult;
242 
243  SG_UI_Msg_Lock(true);
244 
245  SG_RUN_TOOL(bResult, "io_gdal", 4, // Export Shapes
246  SG_TOOL_PARAMETER_SET("SHAPES", this)
247  && SG_TOOL_PARAMETER_SET("FORMAT", Driver)
248  && SG_TOOL_PARAMETER_SET("FILE" , File_Name)
249  );
250 
251  SG_UI_Msg_Lock(false);
252 
253  return( bResult );
254 }
255 
256 
258 // //
259 // //
260 // //
262 
263 //---------------------------------------------------------
264 bool CSG_Shapes::_Load_ESRI(const CSG_String &File_Name)
265 {
266  int Type, iField, iPart, nParts, *Parts, iPoint, nPoints, iOffset;
267  double *pZ = NULL, *pM = NULL;
268  TSG_Point *pPoint;
269  CSG_Buffer File_Header(100), Record_Header(8), Content;
270  CSG_File fSHP;
271 
272  //-----------------------------------------------------
273  // Open DBase File...
274 
276 
277  if( fSHP.Open(SG_File_Make_Path("", File_Name, "cpg")) )
278  {
279  CSG_String sLine;
280 
281  if( fSHP.Read_Line(sLine) && sLine.Find("UTF-8") >= 0 )
282  {
284  }
285 
286  fSHP.Close();
287  }
288 
290 
291  if( !fDBF.Open_Read(SG_File_Make_Path("", File_Name, "dbf"), this, false) )
292  {
293  SG_UI_Msg_Add_Error(_TL("DBase file could not be opened."));
294 
295  return( false );
296  }
297 
298  fDBF.Move_First();
299 
300  if( fDBF.Get_Field_Count() < 1 )
301  {
302  SG_UI_Msg_Add_Error(_TL("DBase file does not contain any attribute fields."));
303 
304  return( false );
305  }
306 
307  //-----------------------------------------------------
308  // Open Shapes File...
309 
310  if( !fSHP.Open(SG_File_Make_Path("", File_Name, "shp"), SG_FILE_R, true) )
311  {
312  SG_UI_Msg_Add_Error(_TL("Shape file could not be opened."));
313 
314  return( false );
315  }
316 
317  //-----------------------------------------------------
318  // Read File Header (100 Bytes)...
319 
320  if( fSHP.Read(File_Header.Get_Data(), sizeof(char), 100) != 100 )
321  {
322  SG_UI_Msg_Add_Error(_TL("corrupted file header"));
323 
324  return( false );
325  }
326 
327  if( File_Header.asInt( 0, true) != 9994 ) // Byte 00 -> File Code 9994 (Integer Big)...
328  {
329  SG_UI_Msg_Add_Error(_TL("invalid file code"));
330 
331  return( false );
332  }
333 
334  if( File_Header.asInt(28, false) != 1000 ) // Byte 28 -> Version 1000 (Integer Little)...
335  {
336  SG_UI_Msg_Add_Error(_TL("unsupported file version"));
337 
338  return( false );
339  }
340 
341  switch( Type = File_Header.asInt(32) ) // Byte 32 -> Shape Type (Integer Little)...
342  {
343  case 1: m_Type = SHAPE_TYPE_Point; m_Vertex_Type = SG_VERTEX_TYPE_XY; break; // Point
344  case 8: m_Type = SHAPE_TYPE_Points; m_Vertex_Type = SG_VERTEX_TYPE_XY; break; // MultiPoint
345  case 3: m_Type = SHAPE_TYPE_Line; m_Vertex_Type = SG_VERTEX_TYPE_XY; break; // PolyLine
346  case 5: m_Type = SHAPE_TYPE_Polygon; m_Vertex_Type = SG_VERTEX_TYPE_XY; break; // Polygon
347 
348  case 11: m_Type = SHAPE_TYPE_Point; m_Vertex_Type = SG_VERTEX_TYPE_XYZM; break; // PointZ
349  case 18: m_Type = SHAPE_TYPE_Points; m_Vertex_Type = SG_VERTEX_TYPE_XYZM; break; // MultiPointZ
350  case 13: m_Type = SHAPE_TYPE_Line; m_Vertex_Type = SG_VERTEX_TYPE_XYZM; break; // PolyLineZ
351  case 15: m_Type = SHAPE_TYPE_Polygon; m_Vertex_Type = SG_VERTEX_TYPE_XYZM; break; // PolygonZ
352 
353  case 21: m_Type = SHAPE_TYPE_Point; m_Vertex_Type = SG_VERTEX_TYPE_XYZ; break; // PointM
354  case 28: m_Type = SHAPE_TYPE_Points; m_Vertex_Type = SG_VERTEX_TYPE_XYZ; break; // MultiPointM
355  case 23: m_Type = SHAPE_TYPE_Line; m_Vertex_Type = SG_VERTEX_TYPE_XYZ; break; // PolyLineM
356  case 25: m_Type = SHAPE_TYPE_Polygon; m_Vertex_Type = SG_VERTEX_TYPE_XYZ; break; // PolygonM
357 
358  default: // unsupported...
359  case 31: // unsupported: MultiPatch...
360  SG_UI_Msg_Add_Error(_TL("unsupported shape type."));
361 
362  return( false );
363  }
364 
365  //-----------------------------------------------------
366  // Load Shapes...
367 
368  for(int iShape=0; iShape<fDBF.Get_Count() && SG_UI_Process_Set_Progress(iShape, fDBF.Get_Count()); iShape++)
369  {
370  if( fSHP.Read(Record_Header.Get_Data(0), sizeof(int), 2) != 2 ) // read record header
371  {
372  SG_UI_Msg_Add_Error(_TL("corrupted record header"));
373 
374  return( false );
375  }
376 
377  if( Record_Header.asInt(0, true) != iShape + 1 ) // record number
378  {
379  SG_UI_Msg_Add_Error(CSG_String::Format("%s (%d != %d)", _TL("corrupted shapefile."), Record_Header.asInt(0, true), iShape + 1));
380 
381  return( false );
382  }
383 
384  size_t Length = 2 * Record_Header.asInt(4, true); // content length as 16-bit words !!!
385 
386  if( !Content.Set_Size(Length, false) )
387  {
388  SG_UI_Msg_Add_Error(_TL("memory allocation error."));
389 
390  return( false );
391  }
392 
393  if( fSHP.Read(Content.Get_Data(), sizeof(char), Length) != Length )
394  {
395  SG_UI_Msg_Add_Error(_TL("corrupted shapefile."));
396 
397  return( false );
398  }
399 
400  if( fDBF.isDeleted() )
401  {
402  continue; // nop
403  }
404 
405  if( Content.asInt(0) != Type )
406  {
407  if( Content.asInt(0) == 0 )
408  {
409  // null shape is allowed !!!
410  }
411  else
412  {
413  SG_UI_Msg_Add_Error(_TL("corrupted shapefile."));
414 
415  return( false );
416  }
417  }
418 
419  //-------------------------------------------------
420  else
421  {
422  CSG_Shape *pShape = Add_Shape();
423 
424  switch( m_Type )
425  {
426  default: break;
427 
428  //---------------------------------------------
429  case SHAPE_TYPE_Point:
430 
431  pPoint = (TSG_Point *)Content.Get_Data(4);
432 
433  pShape->Add_Point(pPoint->x, pPoint->y);
434 
435  switch( m_Vertex_Type ) // read Z + M
436  {
437  default: break;
438  case SG_VERTEX_TYPE_XYZM: pShape->Set_M(Content.asDouble(28), 0);
439  case SG_VERTEX_TYPE_XYZ : pShape->Set_Z(Content.asDouble(20), 0);
440  }
441 
442  break;
443 
444  //---------------------------------------------
445  case SHAPE_TYPE_Points:
446 
447  nPoints = Content.asInt(36);
448  pPoint = (TSG_Point *)Content.Get_Data(40);
449 
450  switch( m_Vertex_Type ) // read Z + M
451  {
452  default:
453  break;
454 
455  case SG_VERTEX_TYPE_XYZ:
456  pZ = 56 + nPoints * 24 <= (int)Length ? (double *)Content.Get_Data(56 + nPoints * 16) : NULL; // [40 + nPoints * 16 + 2 * 8] + [nPoints * 8]
457  break;
458 
459  case SG_VERTEX_TYPE_XYZM:
460  pZ = 56 + nPoints * 24 <= (int)Length ? (double *)Content.Get_Data(56 + nPoints * 16) : NULL; // [40 + nPoints * 16 + 2 * 8] + [nPoints * 8]
461  pM = 72 + nPoints * 32 <= (int)Length ? (double *)Content.Get_Data(72 + nPoints * 24) : NULL; // [40 + nPoints * 16 + 2 * 8] + [nPoints * 8 + 2 * 8] + [nPoints * 8]
462  break;
463  }
464 
465  //-----------------------------------------
466  for(iPoint=0; iPoint<nPoints; iPoint++, pPoint++)
467  {
468  pShape->Add_Point(pPoint->x, pPoint->y);
469 
470  if( pZ ) { pShape->Set_Z(*(pZ++), iPoint); }
471  if( pM ) { pShape->Set_M(*(pM++), iPoint); }
472  }
473 
474  break;
475 
476  //---------------------------------------------
477  case SHAPE_TYPE_Line :
478  case SHAPE_TYPE_Polygon:
479 
480  nParts = Content.asInt(36);
481  nPoints = Content.asInt(40);
482  Parts = (int *)Content.Get_Data(44);
483  pPoint = (TSG_Point *)Content.Get_Data(44 + 4 * nParts);
484 
485  switch( m_Vertex_Type ) // read Z + M
486  {
487  default:
488  break;
489 
490  case SG_VERTEX_TYPE_XYZ:
491  pZ = 60 + nParts * 4 + nPoints * 24 <= (int)Length ? (double *)Content.Get_Data(60 + nParts * 4 + nPoints * 16) : NULL; // [44 + nParts * 4 + nPoints * 16 + 2 * 8] + [nPoints * 8]
492  break;
493 
494  case SG_VERTEX_TYPE_XYZM:
495  pZ = 60 + nParts * 4 + nPoints * 24 <= (int)Length ? (double *)Content.Get_Data(60 + nParts * 4 + nPoints * 16) : NULL; // [44 + nParts * 4 + nPoints * 16 + 2 * 8] + [nPoints * 8]
496  pM = 76 + nParts * 4 + nPoints * 32 <= (int)Length ? (double *)Content.Get_Data(76 + nParts * 4 + nPoints * 24) : NULL; // [44 + nParts * 4 + nPoints * 16 + 2 * 8] + [nPoints * 8 + 2 * 8] + [nPoints * 8]
497  break;
498  }
499 
500  //-----------------------------------------
501  iOffset = 0;
502 
503  for(iPoint=0, iPart=0; iPoint<nPoints; iPoint++, pPoint++)
504  {
505  if( iPart < nParts - 1 && iPoint >= Parts[iPart + 1] )
506  {
507  iPart++;
508  iOffset = 0;
509  }
510 
511  pShape->Add_Point(pPoint->x, pPoint->y, iPart);
512 
513  if( pZ ) { pShape->Set_Z(*(pZ++), iOffset, iPart); }
514  if( pM ) { pShape->Set_M(*(pM++), iOffset, iPart); }
515 
516  iOffset++;
517  }
518 
519  break;
520  }
521 
522  //---------------------------------------------
523  for(iField=0; iField<Get_Field_Count(); iField++)
524  {
525  switch( fDBF.Get_Field_Type(iField) )
526  {
527  default:
528  pShape->Set_Value(iField, fDBF.asString(iField));
529  break;
530 
531  case DBF_FT_FLOAT:
532  case DBF_FT_NUMERIC:
533  {
534  double Value;
535 
536  if( fDBF.asDouble(iField, Value) )
537  {
538  pShape->Set_Value(iField, Value);
539  }
540  else
541  {
542  pShape->Set_NoData(iField);
543  }
544  }
545  break;
546  }
547  }
548  }
549 
550  fDBF.Move_Next();
551  }
552 
553  //-----------------------------------------------------
554  Get_Projection().Load(SG_File_Make_Path("", File_Name, "prj"));
555 
556  //-----------------------------------------------------
557  Load_MetaData(File_Name);
558 
559  CSG_MetaData *pFields = Get_MetaData_DB().Get_Child("FIELDS");
560 
561  if( pFields && pFields->Get_Children_Count() == Get_Field_Count() )
562  {
563  for(iField=0; iField<Get_Field_Count(); iField++)
564  {
565  Set_Field_Name(iField, pFields->Get_Content(iField));
566  }
567  }
568 
569  Set_File_Name(File_Name, true);
570 
571  //-----------------------------------------------------
572  return( true );
573 }
574 
575 
577 // //
578 // //
579 // //
581 
582 //---------------------------------------------------------
583 #define Set_Content_Length(n) Record_Header.Set_Value(4, (int)(n), true);\
584  fSHP.Write(Record_Header.Get_Data(), sizeof(int), 2);\
585  fSHX.Write_Int(fSHP_Size, true);\
586  fSHX.Write_Int((n) , true);\
587  fSHP_Size += 4 + (n);\
588  fSHX_Size += 4;
589 
590 //---------------------------------------------------------
591 bool CSG_Shapes::_Save_ESRI(const CSG_String &File_Name)
592 {
593  int Type, fSHP_Size, fSHX_Size, iField, iPart, iPoint, nPoints;
594  TSG_Point Point;
595  CSG_Buffer File_Header(100), Record_Header(8), Content;
596  CSG_File fSHP, fSHX;
597 
598  //-----------------------------------------------------
599  // Determine Shape Type...
600 
601  switch( m_Type )
602  {
603  case SHAPE_TYPE_Point : Type = 1; break;
604  case SHAPE_TYPE_Points : Type = 8; break;
605  case SHAPE_TYPE_Line : Type = 3; break;
606  case SHAPE_TYPE_Polygon : Type = 5; break;
607  default: return( false );
608  }
609 
611 
612  switch( Vertex_Type )
613  {
614  case SG_VERTEX_TYPE_XY : break;
615  case SG_VERTEX_TYPE_XYZ : Type += 20; break; // M
616  case SG_VERTEX_TYPE_XYZM: Type += 10; break; // Z (+M)
617  default: return( false );
618  }
619 
620  //-----------------------------------------------------
621  // DBase File Access...
622 
623  SG_File_Delete(SG_File_Make_Path("", File_Name, "cpg"));
624 
626  {
627  if( fSHP.Open(SG_File_Make_Path("", File_Name, "cpg"), SG_FILE_W, false) )
628  {
629  fSHP.Printf("UTF-8\n");
630 
631  fSHP.Close();
632  }
633  }
634 
636 
637  if( !fDBF.Open_Write(SG_File_Make_Path("", File_Name, "dbf"), this, false) )
638  {
639  return( false );
640  }
641 
642  //-----------------------------------------------------
643  // Shape File Access...
644 
645  if( !fSHX.Open(SG_File_Make_Path("", File_Name, "shx"), SG_FILE_W, true) )
646  {
647  SG_UI_Msg_Add_Error(_TL("index file could not be opened"));
648 
649  return( false );
650  }
651 
652  if( !fSHP.Open(SG_File_Make_Path("", File_Name, "shp"), SG_FILE_W, true) )
653  {
654  SG_UI_Msg_Add_Error(_TL("shape file could not be opened."));
655 
656  return( false );
657  }
658 
659  //-----------------------------------------------------
660  // Save Header...
661 
662  Make_Clean(); // polygons: first == last point, inner rings > anti-clockwise...
663 
664  Update();
665 
666  File_Header.Set_Value( 0, 9994 , true ); // Byte 0 Integer Big File Code = 9994
667  File_Header.Set_Value( 4, 0 , true ); // Byte 4 Integer Big unused
668  File_Header.Set_Value( 8, 0 , true ); // Byte 8 Integer Big unused
669  File_Header.Set_Value(12, 0 , true ); // Byte 12 Integer Big unused
670  File_Header.Set_Value(16, 0 , true ); // Byte 16 Integer Big unused
671  File_Header.Set_Value(20, 0 , true ); // Byte 20 Integer Big unused
672  File_Header.Set_Value(24, 0 , true ); // Byte 24 Integer Big File Length
673  File_Header.Set_Value(28, 1000 , false); // Byte 28 Integer Little Version = 1000
674  File_Header.Set_Value(32, Type , false); // Byte 32 Integer Little Shape Type
675  File_Header.Set_Value(36, m_Extent.Get_XMin() , false); // Byte 36 Double Little Bounding Box Xmin
676  File_Header.Set_Value(44, m_Extent.Get_YMin() , false); // Byte 44 Double Little Bounding Box Ymin
677  File_Header.Set_Value(52, m_Extent.Get_XMax() , false); // Byte 52 Double Little Bounding Box Xmax
678  File_Header.Set_Value(60, m_Extent.Get_YMax() , false); // Byte 60 Double Little Bounding Box Ymax
679  File_Header.Set_Value(68, Get_ZMin() , false); // Byte 68 Double Little Bounding Box Zmin
680  File_Header.Set_Value(76, Get_ZMax() , false); // Byte 76 Double Little Bounding Box Zmax
681  File_Header.Set_Value(84, Get_MMin() , false); // Byte 84 Double Little Bounding Box Mmin
682  File_Header.Set_Value(92, Get_MMax() , false); // Byte 92 Double Little Bounding Box Mmax
683 
684  fSHP.Write(File_Header.Get_Data(), sizeof(char), 100);
685  fSHX.Write(File_Header.Get_Data(), sizeof(char), 100);
686 
687  fSHP_Size = 50; // file size measured in 16-bit words...
688  fSHX_Size = 50; // file size measured in 16-bit words...
689 
690  //-----------------------------------------------------
691  // Save Shapes...
692 
693  for(sLong iShape=0; iShape<Get_Count() && SG_UI_Process_Set_Progress(iShape, Get_Count()); iShape++)
694  {
695  CSG_Shape *pShape = Get_Shape(iShape);
696 
697  //-------------------------------------------------
698  // geometries...
699 
700  Record_Header.Set_Value(0, (int)iShape + 1, true); // record number
701 
702  for(iPart=0, nPoints=0; iPart<pShape->Get_Part_Count(); iPart++)
703  {
704  nPoints += pShape->Get_Point_Count(iPart); // total number of points in shape
705  }
706 
707  //-------------------------------------------------
708  switch( m_Type ) // write content header
709  {
710  default: break;
711 
712  //-------------------------------------------------
713  case SHAPE_TYPE_Point:
714 
715  switch( Vertex_Type )
716  {
717  case SG_VERTEX_TYPE_XY : Set_Content_Length(10); break;
718  case SG_VERTEX_TYPE_XYZ : Set_Content_Length(14); break;
719  case SG_VERTEX_TYPE_XYZM: Set_Content_Length(18); break;
720  }
721 
722  fSHP.Write_Int (Type);
723 
724  break;
725 
726  //-------------------------------------------------
727  case SHAPE_TYPE_Points:
728 
729  switch( Vertex_Type )
730  {
731  case SG_VERTEX_TYPE_XY : Set_Content_Length(20 + 8 * nPoints); break;
732  case SG_VERTEX_TYPE_XYZ : Set_Content_Length(28 + 12 * nPoints); break;
733  case SG_VERTEX_TYPE_XYZM: Set_Content_Length(36 + 16 * nPoints); break;
734  }
735 
736  fSHP.Write_Int (Type);
737  fSHP.Write_Double (pShape->Get_Extent().Get_XMin());
738  fSHP.Write_Double (pShape->Get_Extent().Get_YMin());
739  fSHP.Write_Double (pShape->Get_Extent().Get_XMax());
740  fSHP.Write_Double (pShape->Get_Extent().Get_YMax());
741  fSHP.Write_Int (nPoints);
742 
743  break;
744 
745  //-------------------------------------------------
746  case SHAPE_TYPE_Line:
747  case SHAPE_TYPE_Polygon:
748 
749  switch( Vertex_Type )
750  {
751  case SG_VERTEX_TYPE_XY: Set_Content_Length(22 + 2 * pShape->Get_Part_Count() + 8 * nPoints); break;
752  case SG_VERTEX_TYPE_XYZ: Set_Content_Length(30 + 2 * pShape->Get_Part_Count() + 12 * nPoints); break;
753  case SG_VERTEX_TYPE_XYZM: Set_Content_Length(38 + 2 * pShape->Get_Part_Count() + 16 * nPoints); break;
754  }
755 
756  fSHP.Write_Int (Type);
757  fSHP.Write_Double (pShape->Get_Extent().Get_XMin());
758  fSHP.Write_Double (pShape->Get_Extent().Get_YMin());
759  fSHP.Write_Double (pShape->Get_Extent().Get_XMax());
760  fSHP.Write_Double (pShape->Get_Extent().Get_YMax());
761  fSHP.Write_Int (pShape->Get_Part_Count());
762  fSHP.Write_Int (nPoints);
763 
764  for(iPart=0, iPoint=0; iPart<pShape->Get_Part_Count(); iPoint+=pShape->Get_Point_Count(iPart++))
765  {
766  fSHP.Write_Int(iPoint);
767  }
768 
769  break;
770  }
771 
772  //-------------------------------------------------
773  switch( m_Type ) // write point data
774  {
775  default: break;
776 
777  //-------------------------------------------------
778  case SHAPE_TYPE_Point:
779 
780  fSHP.Write(&(Point = pShape->Get_Point()), sizeof(TSG_Point));
781 
782  //---------------------------------------------
783  if( Vertex_Type != SG_VERTEX_TYPE_XY )
784  {
785  fSHP.Write_Double(pShape->Get_Z(0));
786 
787  if( Vertex_Type == SG_VERTEX_TYPE_XYZM )
788  {
789  fSHP.Write_Double(pShape->Get_M(0));
790  }
791  }
792 
793  break;
794 
795  //-------------------------------------------------
796  case SHAPE_TYPE_Points:
797  case SHAPE_TYPE_Line:
798  case SHAPE_TYPE_Polygon:
799 
800  for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
801  {
802  for(iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
803  {
804  fSHP.Write(&(Point = pShape->Get_Point(iPoint, iPart)), sizeof(TSG_Point));
805  }
806  }
807 
808  //---------------------------------------------
809  if( Vertex_Type != SG_VERTEX_TYPE_XY )
810  {
811  fSHP.Write_Double(pShape->Get_ZMin());
812  fSHP.Write_Double(pShape->Get_ZMax());
813 
814  for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
815  {
816  for(iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
817  {
818  fSHP.Write_Double(pShape->Get_Z(iPoint, iPart));
819  }
820  }
821 
822  if( Vertex_Type == SG_VERTEX_TYPE_XYZM )
823  {
824  fSHP.Write_Double(pShape->Get_MMin());
825  fSHP.Write_Double(pShape->Get_MMax());
826 
827  for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
828  {
829  for(iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
830  {
831  fSHP.Write_Double(pShape->Get_M(iPoint, iPart));
832  }
833  }
834  }
835  }
836  }
837 
838  //-------------------------------------------------
839  // attributes...
840 
841  fDBF.Add_Record();
842 
843  for(iField=0; iField<Get_Field_Count(); iField++)
844  {
845  if( pShape->is_NoData(iField) )
846  {
847  fDBF.Set_NoData(iField);
848  }
849  else switch( fDBF.Get_Field_Type(iField) )
850  {
851  default:
852  fDBF.Set_Value(iField, pShape->asString(iField));
853  break;
854 
855  case DBF_FT_FLOAT:
856  case DBF_FT_NUMERIC:
857  fDBF.Set_Value(iField, pShape->asDouble(iField));
858  break;
859  }
860  }
861 
862  fDBF.Flush_Record();
863  }
864 
865  //-----------------------------------------------------
866  // File Sizes...
867 
868  fSHP.Seek(24);
869  fSHP.Write_Int(fSHP_Size, true);
870 
871  fSHX.Seek(24);
872  fSHX.Write_Int(fSHX_Size, true);
873 
874  //-----------------------------------------------------
875  Get_Projection().Save(SG_File_Make_Path("", File_Name, "prj"));
876 
877  //-----------------------------------------------------
878  CSG_MetaData *pFields = Get_MetaData_DB().Get_Child("FIELDS");
879 
880  if( !pFields )
881  {
882  pFields = Get_MetaData_DB().Add_Child("FIELDS");
883  }
884 
885  pFields->Del_Children();
886 
887  for(iField=0; iField<Get_Field_Count(); iField++)
888  {
889  pFields->Add_Child("FIELD", Get_Field_Name(iField))->Add_Property("TYPE", gSG_Data_Type_Identifier[Get_Field_Type(iField)]);
890  }
891 
892  Get_MetaData().Del_Child("GDAL_DRIVER");
893 
894  Save_MetaData(File_Name);
895 
896  //-----------------------------------------------------
897  return( true );
898 }
899 
900 
902 // //
903 // //
904 // //
906 
907 //---------------------------------------------------------
CSG_Table_Record::asDouble
double asDouble(int Field) const
Definition: table_record.cpp:527
CSG_File::Open
virtual bool Open(const CSG_String &FileName, int Mode=SG_FILE_R, bool bBinary=true, int Encoding=SG_FILE_ENCODING_ANSI)
Definition: api_file.cpp:111
DBF_FT_FLOAT
#define DBF_FT_FLOAT
Definition: table_dbase.h:77
PARAMETER_TYPE_FilePath
@ PARAMETER_TYPE_FilePath
Definition: parameters.h:136
CSG_Shapes::On_Delete
virtual bool On_Delete(void)
Definition: shapes_io.cpp:72
CSG_Projection::Save
bool Save(const CSG_String &File, ESG_CRS_Format Format=ESG_CRS_Format::WKT) const
Definition: projections.cpp:229
CSG_MetaData::Del_Child
bool Del_Child(int Index)
Definition: metadata.cpp:321
_TL
#define _TL(s)
Definition: api_core.h:1489
CSG_Data_Object::Set_File_Name
void Set_File_Name(const CSG_String &FileName)
Definition: dataobject.cpp:366
CSG_Shapes::Get_Shape
virtual CSG_Shape * Get_Shape(const CSG_Point &Point, double Epsilon=0.)
Definition: shapes.cpp:499
CSG_Data_Object::Update
bool Update(bool bForce=false)
Definition: dataobject.cpp:773
CSG_MetaData::Get_Children_Count
int Get_Children_Count(void) const
Definition: metadata.h:147
CSG_Data_Collection::Count
size_t Count(void) const
Definition: data_manager.h:94
SG_Shapes_Get_File_Extension_Default
CSG_String SG_Shapes_Get_File_Extension_Default(void)
Definition: shapes_io.cpp:124
CSG_MetaData::Get_Content
const CSG_String & Get_Content(void) const
Definition: metadata.h:132
CSG_Shapes::On_Reload
virtual bool On_Reload(void)
Definition: shapes_io.cpp:66
CSG_Shape::Get_Z
virtual double Get_Z(int iPoint=0, int iPart=0, bool bAscending=true) const
Definition: shapes.h:195
data_manager.h
CSG_Rect::Get_XMax
double Get_XMax(void) const
Definition: geo_tools.h:503
SG_UI_MSG_STYLE_SUCCESS
@ SG_UI_MSG_STYLE_SUCCESS
Definition: api_core.h:1505
CSG_File::Seek
bool Seek(sLong Offset, int Origin=SG_FILE_START) const
Definition: api_file.cpp:238
SG_File_Cmp_Extension
SAGA_API_DLL_EXPORT bool SG_File_Cmp_Extension(const CSG_String &FileName, const CSG_String &Extension)
Definition: api_file.cpp:952
CSG_Shapes::Get_MMax
double Get_MMax(void)
Definition: shapes.h:818
SHAPE_TYPE_Polygon
@ SHAPE_TYPE_Polygon
Definition: shapes.h:105
CSG_Data_Object::Save_MetaData
bool Save_MetaData(const CSG_String &FileName)
Definition: dataobject.cpp:677
CSG_Shapes::Get_MMin
double Get_MMin(void)
Definition: shapes.h:817
CSG_Buffer::asDouble
double asDouble(int Offset, bool bBigEndian=false) const
Definition: api_core.h:271
CSG_Tool
Definition: tool.h:151
CSG_Tool::Execute
bool Execute(bool bAddHistory=false)
Definition: tool.cpp:258
SG_RUN_TOOL
#define SG_RUN_TOOL(bRetVal, LIBRARY, TOOL, CONDITION)
Definition: tool_library.h:257
CSG_Table_DBase::Open_Write
bool Open_Write(const SG_Char *FileName, class CSG_Table *pTable, bool bRecords_Save=true)
Definition: table_dbase.cpp:307
CSG_Table::Get_Field_Count
int Get_Field_Count(void) const
Definition: table.h:356
SG_File_Delete
SAGA_API_DLL_EXPORT bool SG_File_Delete(const CSG_String &FileName)
Definition: api_file.cpp:856
CSG_Shapes::m_Type
TSG_Shape_Type m_Type
Definition: shapes.h:847
CSG_Data_Manager::Shapes
CSG_Data_Collection & Shapes(void) const
Definition: data_manager.h:137
CSG_Table::m_Extent
CSG_Rect m_Extent
Definition: table.h:461
CSG_MetaData::Get_Child
CSG_MetaData * Get_Child(int Index) const
Definition: metadata.h:148
SG_FILE_R
@ SG_FILE_R
Definition: api_core.h:1109
SSG_Point
Definition: geo_tools.h:128
CSG_Buffer::Set_Size
bool Set_Size(size_t Size, bool bShrink=true)
Definition: api_memory.cpp:732
CSG_File::Read
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition: api_file.cpp:328
CSG_Tool_Library_Manager::Delete_Tool
bool Delete_Tool(CSG_Tool *pTool) const
Definition: tool_library.cpp:725
CSG_Shapes::Get_ZMin
double Get_ZMin(void)
Definition: shapes.h:815
gSG_Shape_File_Format_Default
static TSG_Shape_File_Format gSG_Shape_File_Format_Default
Definition: shapes_io.cpp:100
CSG_Table_Record::is_NoData
bool is_NoData(int Field) const
Definition: table_record.cpp:416
CSG_File
Definition: api_core.h:1124
CSG_Table::Set_Modified
virtual void Set_Modified(bool bModified=true)
Definition: table.cpp:1113
SG_Shapes_Set_File_Format_Default
bool SG_Shapes_Set_File_Format_Default(int Format)
Definition: shapes_io.cpp:103
Set_Content_Length
#define Set_Content_Length(n)
Definition: shapes_io.cpp:583
CSG_Shape::Get_Point
virtual TSG_Point Get_Point(int iPoint=0) const =0
CSG_Shapes::Add_Shape
virtual CSG_Shape * Add_Shape(CSG_Table_Record *pCopy=NULL, TSG_ADD_Shape_Copy_Mode mCopy=SHAPE_COPY)
Definition: shapes.cpp:418
SG_VERTEX_TYPE_XY
@ SG_VERTEX_TYPE_XY
Definition: shapes.h:92
CSG_Tool::Set_Parameter
bool Set_Parameter(const CSG_String &ID, CSG_Parameter *pValue)
Definition: tool.cpp:1140
SG_UI_MSG_STYLE_FAILURE
@ SG_UI_MSG_STYLE_FAILURE
Definition: api_core.h:1506
CSG_Shape::Get_Part_Count
virtual int Get_Part_Count(void) const =0
SG_TOOL_PARAMETER_SET
#define SG_TOOL_PARAMETER_SET(IDENTIFIER, VALUE)
Definition: tool_library.h:351
CSG_Table_DBase
Definition: table_dbase.h:91
CSG_Buffer
Definition: api_core.h:224
CSG_Table_Record::asString
const SG_Char * asString(int Field, int Decimals=-99) const
Definition: table_record.cpp:461
CSG_Buffer::asInt
int asInt(int Offset, bool bBigEndian=false) const
Definition: api_core.h:269
CSG_Table::Get_Field_Name
const SG_Char * Get_Field_Name(int iField) const
Definition: table.h:357
CSG_Rect::Get_YMin
double Get_YMin(void) const
Definition: geo_tools.h:504
SG_VERTEX_TYPE_XYZM
@ SG_VERTEX_TYPE_XYZM
Definition: shapes.h:94
CSG_Shapes::Save
virtual bool Save(const CSG_String &File, int Format=0)
Definition: shapes_io.cpp:141
CSG_MetaData::Del_Children
bool Del_Children(int Depth=0, const SG_Char *Name=NULL)
Definition: metadata.cpp:381
CSG_File::Read_Line
bool Read_Line(CSG_String &sLine) const
Definition: api_file.cpp:385
CSG_Tool_Library_Manager::Create_Tool
CSG_Tool * Create_Tool(const CSG_String &Library, int Index, bool bWithGUI=false) const
Definition: tool_library.cpp:696
SG_UI_Msg_Lock
int SG_UI_Msg_Lock(bool bOn)
Definition: api_callback.cpp:472
sLong
signed long long sLong
Definition: api_core.h:158
CSG_Table_DBase::Get_Field_Type
char Get_Field_Type(int iField)
Definition: table_dbase.h:109
SG_Get_Tool_Library_Manager
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)
Definition: tool_library.cpp:286
CSG_Shape::Get_ZMax
virtual double Get_ZMax(void)
Definition: shapes.h:197
SHAPE_FILE_FORMAT_GeoPackage
@ SHAPE_FILE_FORMAT_GeoPackage
Definition: shapes.h:117
CSG_Shape::Get_ZMin
virtual double Get_ZMin(void)
Definition: shapes.h:196
CSG_Table::Get_Count
sLong Get_Count(void) const
Definition: table.h:392
SG_Shapes_Get_File_Format_Default
TSG_Shape_File_Format SG_Shapes_Get_File_Format_Default(void)
Definition: shapes_io.cpp:118
CSG_Data_Object::Get_File_Name
const SG_Char * Get_File_Name(bool bNative=true) const
Definition: dataobject.cpp:390
CSG_Table_DBase::Add_Record
void Add_Record(void)
Definition: table_dbase.cpp:612
CSG_Shape::Get_M
virtual double Get_M(int iPoint=0, int iPart=0, bool bAscending=true) const
Definition: shapes.h:211
CSG_File::Close
virtual bool Close(void)
Definition: api_file.cpp:160
CSG_Shape::Add_Point
virtual int Add_Point(double x, double y, int iPart=0)=0
SG_FILE_W
@ SG_FILE_W
Definition: api_core.h:1110
CSG_Projection::Load
bool Load(const CSG_String &File)
Definition: projections.cpp:221
SHAPE_FILE_FORMAT_Undefined
@ SHAPE_FILE_FORMAT_Undefined
Definition: shapes.h:115
CSG_Shape::Get_MMin
virtual double Get_MMin(void)
Definition: shapes.h:212
CSG_Buffer::Get_Data
char * Get_Data(int Offset=0) const
Definition: api_core.h:244
CSG_Shapes::m_Vertex_Type
TSG_Vertex_Type m_Vertex_Type
Definition: shapes.h:849
CSG_Table::m_Encoding
int m_Encoding
Definition: table.h:449
CSG_String::Format
static CSG_String Format(const char *Format,...)
Definition: api_string.cpp:270
CSG_Table_DBase::Flush_Record
void Flush_Record(void)
Definition: table_dbase.cpp:630
CSG_String::Find
int Find(char Character, bool fromEnd=false) const
Definition: api_string.cpp:616
CSG_File::Write_Double
bool Write_Double(double Value, bool bBigEndian=false)
Definition: api_file.cpp:470
SHAPE_TYPE_Line
@ SHAPE_TYPE_Line
Definition: shapes.h:104
CSG_Table::Set_Field_Name
bool Set_Field_Name(int iField, const SG_Char *Name)
Definition: table.cpp:611
gSG_Data_Type_Identifier
const char gSG_Data_Type_Identifier[][32]
Definition: api_core.h:1039
TSG_Shape_File_Format
TSG_Shape_File_Format
Definition: shapes.h:114
table_dbase.h
SG_File_Set_Extension
SAGA_API_DLL_EXPORT bool SG_File_Set_Extension(CSG_String &FileName, const CSG_String &Extension)
Definition: api_file.cpp:958
CSG_Table::_Save_DBase
bool _Save_DBase(const CSG_String &File)
Definition: table_io.cpp:523
CSG_Shape::Get_Point_Count
virtual int Get_Point_Count(void) const =0
SHAPE_FILE_FORMAT_GeoJSON
@ SHAPE_FILE_FORMAT_GeoJSON
Definition: shapes.h:118
TSG_Vertex_Type
TSG_Vertex_Type
Definition: shapes.h:91
shapes.h
CSG_Table_DBase::Set_Value
bool Set_Value(int iField, double Value)
Definition: table_dbase.cpp:771
CSG_String
Definition: api_core.h:563
SHAPE_TYPE_Point
@ SHAPE_TYPE_Point
Definition: shapes.h:102
CSG_Data_Manager
Definition: data_manager.h:129
CSG_MetaData
Definition: metadata.h:88
CSG_Data_Object::Get_MetaData_DB
CSG_MetaData & Get_MetaData_DB(void) const
Definition: dataobject.h:235
CSG_Tool::Settings_Push
bool Settings_Push(class CSG_Data_Manager *pManager=NULL)
Definition: tool.cpp:621
CSG_File::Printf
int Printf(const char *Format,...)
Definition: api_file.cpp:277
CSG_Shape::Get_MMax
virtual double Get_MMax(void)
Definition: shapes.h:213
SG_UI_Process_Set_Progress
bool SG_UI_Process_Set_Progress(int Position, int Range)
Definition: api_callback.cpp:256
CSG_File::Write_Int
bool Write_Int(int Value, bool bBigEndian=false)
Definition: api_file.cpp:444
CSG_Data_Object::Get_MetaData
CSG_MetaData & Get_MetaData(void) const
Definition: dataobject.h:234
SSG_Point::x
double x
Definition: geo_tools.h:129
CSG_Table_Record::Set_Value
bool Set_Value(int Field, const CSG_String &Value)
Definition: table_record.cpp:270
CSG_Rect::Get_YMax
double Get_YMax(void) const
Definition: geo_tools.h:505
CSG_Data_Object::Load_MetaData
bool Load_MetaData(const CSG_String &FileName)
Definition: dataobject.cpp:654
CSG_Rect::Get_XMin
double Get_XMin(void) const
Definition: geo_tools.h:502
SHAPE_FILE_FORMAT_ESRI
@ SHAPE_FILE_FORMAT_ESRI
Definition: shapes.h:116
SSG_Point::y
double y
Definition: geo_tools.h:129
CSG_Table_DBase::Set_NoData
bool Set_NoData(int iField)
Definition: table_dbase.cpp:904
CSG_Shapes::Make_Clean
bool Make_Clean(void)
Definition: shapes.cpp:541
CSG_Shape::Get_Extent
virtual const CSG_Rect & Get_Extent(void)=0
CSG_Shape::Set_Z
virtual void Set_Z(double z, int iPoint=0, int iPart=0)
Definition: shapes.h:194
CSG_Table::Create
bool Create(void)
Definition: table.cpp:139
SG_File_Make_Path
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
Definition: api_file.cpp:919
CSG_Shapes
Definition: shapes.h:775
CSG_String::c_str
const SG_Char * c_str(void) const
Definition: api_string.cpp:236
tool_library.h
SHAPE_TYPE_Points
@ SHAPE_TYPE_Points
Definition: shapes.h:103
CSG_File::Write
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition: api_file.cpp:360
SG_UI_Process_Set_Ready
bool SG_UI_Process_Set_Ready(void)
Definition: api_callback.cpp:306
CSG_MetaData::Add_Child
CSG_MetaData * Add_Child(void)
Definition: metadata.cpp:166
SG_UI_Msg_Add_Error
void SG_UI_Msg_Add_Error(const char *Message)
Definition: api_callback.cpp:557
CSG_Table::Get_Field_Type
TSG_Data_Type Get_Field_Type(int iField) const
Definition: table.h:358
DBF_FT_NUMERIC
#define DBF_FT_NUMERIC
Definition: table_dbase.h:78
SG_FILE_ENCODING_ANSI
@ SG_FILE_ENCODING_ANSI
Definition: api_core.h:550
SG_FILE_ENCODING_UTF8
@ SG_FILE_ENCODING_UTF8
Definition: api_core.h:552
CSG_Shape::Set_M
virtual void Set_M(double m, int iPoint=0, int iPart=0)
Definition: shapes.h:210
CSG_Shape
Definition: shapes.h:141
CSG_Data_Object::Get_Projection
CSG_Projection & Get_Projection(void)
Definition: dataobject.cpp:637
CSG_Table_Record::Set_NoData
bool Set_NoData(int Field)
Definition: table_record.cpp:366
CSG_Table::_Save_Text
bool _Save_Text(const CSG_String &File, bool bHeadline, const SG_Char Separator)
Definition: table_io.cpp:453
SG_VERTEX_TYPE_XYZ
@ SG_VERTEX_TYPE_XYZ
Definition: shapes.h:93
CSG_Shapes::Get_ZMax
double Get_ZMax(void)
Definition: shapes.h:816
SG_UI_Msg_Add
void SG_UI_Msg_Add(const char *Message, bool bNewLine, TSG_UI_MSG_STYLE Style)
Definition: api_callback.cpp:503