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