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