1 /**********************************************************
2 * Version $Id$
3 *********************************************************/
4
5 ///////////////////////////////////////////////////////////
6 // //
7 // SAGA //
8 // //
9 // System for Automated Geoscientific Analyses //
10 // //
11 // Application Programming Interface //
12 // //
13 // Library: SAGA_API //
14 // //
15 //-------------------------------------------------------//
16 // //
17 // shapes_ogis.cpp //
18 // //
19 // Copyright (C) 2010 by Olaf Conrad //
20 // //
21 //-------------------------------------------------------//
22 // //
23 // This file is part of 'SAGA - System for Automated //
24 // Geoscientific Analyses'. //
25 // //
26 // This library is free software; you can redistribute //
27 // it and/or modify it under the terms of the GNU Lesser //
28 // General Public License as published by the Free //
29 // Software Foundation, either version 2.1 of the //
30 // License, or (at your option) any later version. //
31 // //
32 // This library is distributed in the hope that it will //
33 // be useful, but WITHOUT ANY WARRANTY; without even the //
34 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
35 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
36 // License for more details. //
37 // //
38 // You should have received a copy of the GNU Lesser //
39 // General Public License along with this program; if //
40 // not, see <http://www.gnu.org/licenses/>. //
41 // //
42 //-------------------------------------------------------//
43 // //
44 // contact: Olaf Conrad //
45 // Institute of Geography //
46 // University of Hamburg //
47 // Germany //
48 // //
49 // e-mail: oconrad@saga-gis.org //
50 // //
51 ///////////////////////////////////////////////////////////
52
53 //---------------------------------------------------------
54
55
56 ///////////////////////////////////////////////////////////
57 // //
58 // //
59 // //
60 ///////////////////////////////////////////////////////////
61
62 //---------------------------------------------------------
63 #include "shapes.h"
64
65
66 ///////////////////////////////////////////////////////////
67 // //
68 // //
69 // //
70 ///////////////////////////////////////////////////////////
71
72 //---------------------------------------------------------
Type_asWKText(DWORD Type)73 CSG_String CSG_Shapes_OGIS_Converter::Type_asWKText (DWORD Type)
74 {
75 switch( Type )
76 {
77 case SG_OGIS_TYPE_Point : return( "Point" );
78 case SG_OGIS_TYPE_LineString : return( "LineString" );
79 case SG_OGIS_TYPE_Polygon : return( "Polygon" );
80 case SG_OGIS_TYPE_MultiPoint : return( "MultiPoint" );
81 case SG_OGIS_TYPE_MultiLineString : return( "MultiLineString" );
82 case SG_OGIS_TYPE_MultiPolygon : return( "MultiPolygon" );
83 case SG_OGIS_TYPE_GeometryCollection : return( "GeometryCollection" );
84 case SG_OGIS_TYPE_PolyhedralSurface : return( "PolyhedralSurface" );
85 case SG_OGIS_TYPE_TIN : return( "TIN" );
86 case SG_OGIS_TYPE_Triangle : return( "Triangle" );
87
88 case SG_OGIS_TYPE_PointZ : return( "PointZ" );
89 case SG_OGIS_TYPE_LineStringZ : return( "LineStringZ" );
90 case SG_OGIS_TYPE_PolygonZ : return( "PolygonZ" );
91 case SG_OGIS_TYPE_MultiPointZ : return( "MultiPointZ" );
92 case SG_OGIS_TYPE_MultiLineStringZ : return( "MultiLineStringZ" );
93 case SG_OGIS_TYPE_MultiPolygonZ : return( "MultiPolygonZ" );
94 case SG_OGIS_TYPE_GeometryCollectionZ : return( "GeometryCollectionZ" );
95 case SG_OGIS_TYPE_PolyhedralSurfaceZ : return( "PolyhedralSurfaceZ" );
96 case SG_OGIS_TYPE_TINZ : return( "TINZ" );
97 case SG_OGIS_TYPE_TriangleZ : return( "TriangleZ" );
98
99 case SG_OGIS_TYPE_PointM : return( "PointM" );
100 case SG_OGIS_TYPE_LineStringM : return( "LineStringM" );
101 case SG_OGIS_TYPE_PolygonM : return( "PolygonM" );
102 case SG_OGIS_TYPE_MultiPointM : return( "MultiPointM" );
103 case SG_OGIS_TYPE_MultiLineStringM : return( "MultiLineStringM" );
104 case SG_OGIS_TYPE_MultiPolygonM : return( "MultiPolygonM" );
105 case SG_OGIS_TYPE_GeometryCollectionM : return( "GeometryCollectionM" );
106 case SG_OGIS_TYPE_PolyhedralSurfaceM : return( "PolyhedralSurfaceM" );
107 case SG_OGIS_TYPE_TINM : return( "TINM" );
108 case SG_OGIS_TYPE_TriangleM : return( "TriangleM" );
109
110 case SG_OGIS_TYPE_PointZM : return( "PointZM" );
111 case SG_OGIS_TYPE_LineStringZM : return( "LineStringZM" );
112 case SG_OGIS_TYPE_PolygonZM : return( "PolygonZM" );
113 case SG_OGIS_TYPE_MultiPointZM : return( "MultiPointZM" );
114 case SG_OGIS_TYPE_MultiLineStringZM : return( "MultiLineStringZM" );
115 case SG_OGIS_TYPE_MultiPolygonZM : return( "MultiPolygonZM" );
116 case SG_OGIS_TYPE_GeometryCollectionZM : return( "GeometryCollectionZM" );
117 case SG_OGIS_TYPE_PolyhedralSurfaceZM : return( "PolyhedralSurfaceZM" );
118 case SG_OGIS_TYPE_TINZM : return( "TINZM" );
119 case SG_OGIS_TYPE_TriangleZM : return( "TriangleZM" );
120 }
121
122 return( "" );
123 }
124
125 //---------------------------------------------------------
Type_asWKBinary(const CSG_String & Type)126 DWORD CSG_Shapes_OGIS_Converter::Type_asWKBinary(const CSG_String &Type)
127 {
128 #define TYPE_AS_WKB(t) if( !Type.CmpNoCase(Type_asWKText(t)) ) return( t );
129
130 TYPE_AS_WKB(SG_OGIS_TYPE_Point );
131 TYPE_AS_WKB(SG_OGIS_TYPE_LineString );
132 TYPE_AS_WKB(SG_OGIS_TYPE_Polygon );
133 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPoint );
134 TYPE_AS_WKB(SG_OGIS_TYPE_MultiLineString );
135 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPolygon );
136 TYPE_AS_WKB(SG_OGIS_TYPE_GeometryCollection );
137 TYPE_AS_WKB(SG_OGIS_TYPE_PolyhedralSurface );
138 TYPE_AS_WKB(SG_OGIS_TYPE_TIN );
139 TYPE_AS_WKB(SG_OGIS_TYPE_Triangle );
140
141 TYPE_AS_WKB(SG_OGIS_TYPE_PointZ );
142 TYPE_AS_WKB(SG_OGIS_TYPE_LineStringZ );
143 TYPE_AS_WKB(SG_OGIS_TYPE_PolygonZ );
144 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPointZ );
145 TYPE_AS_WKB(SG_OGIS_TYPE_MultiLineStringZ );
146 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPolygonZ );
147 TYPE_AS_WKB(SG_OGIS_TYPE_GeometryCollectionZ );
148 TYPE_AS_WKB(SG_OGIS_TYPE_PolyhedralSurfaceZ );
149 TYPE_AS_WKB(SG_OGIS_TYPE_TINZ );
150 TYPE_AS_WKB(SG_OGIS_TYPE_TriangleZ );
151
152 TYPE_AS_WKB(SG_OGIS_TYPE_PointM );
153 TYPE_AS_WKB(SG_OGIS_TYPE_LineStringM );
154 TYPE_AS_WKB(SG_OGIS_TYPE_PolygonM );
155 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPointM );
156 TYPE_AS_WKB(SG_OGIS_TYPE_MultiLineStringM );
157 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPolygonM );
158 TYPE_AS_WKB(SG_OGIS_TYPE_GeometryCollectionM );
159 TYPE_AS_WKB(SG_OGIS_TYPE_PolyhedralSurfaceM );
160 TYPE_AS_WKB(SG_OGIS_TYPE_TINM );
161 TYPE_AS_WKB(SG_OGIS_TYPE_TriangleM );
162
163 TYPE_AS_WKB(SG_OGIS_TYPE_PointZM );
164 TYPE_AS_WKB(SG_OGIS_TYPE_LineStringZM );
165 TYPE_AS_WKB(SG_OGIS_TYPE_PolygonZM );
166 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPointZM );
167 TYPE_AS_WKB(SG_OGIS_TYPE_MultiLineStringZM );
168 TYPE_AS_WKB(SG_OGIS_TYPE_MultiPolygonZM );
169 TYPE_AS_WKB(SG_OGIS_TYPE_GeometryCollectionZM );
170 TYPE_AS_WKB(SG_OGIS_TYPE_PolyhedralSurfaceZM );
171 TYPE_AS_WKB(SG_OGIS_TYPE_TINZM );
172 TYPE_AS_WKB(SG_OGIS_TYPE_TriangleZM );
173
174 return( SG_OGIS_TYPE_Undefined );
175 }
176
177
178 ///////////////////////////////////////////////////////////
179 // //
180 // //
181 // //
182 ///////////////////////////////////////////////////////////
183
184 //---------------------------------------------------------
_WKT_Read_Point(const CSG_String & Text,CSG_Shape * pShape,int iPart)185 inline bool CSG_Shapes_OGIS_Converter::_WKT_Read_Point(const CSG_String &Text, CSG_Shape *pShape, int iPart)
186 {
187 double x, y, z, m;
188
189 switch( pShape->Get_Vertex_Type() )
190 {
191 case SG_VERTEX_TYPE_XY:
192 if( SG_SSCANF(Text.c_str(), SG_T("%lf %lf"), &x, &y) == 2 )
193 {
194 pShape->Add_Point(x, y, iPart);
195
196 return( true );
197 }
198 break;
199
200 case SG_VERTEX_TYPE_XYZ:
201 if( SG_SSCANF(Text.c_str(), SG_T("%lf %lf %lf"), &x, &y, &z) == 3 )
202 {
203 pShape->Add_Point(x, y, iPart);
204 pShape->Set_Z (z, pShape->Get_Point_Count(iPart) - 1, iPart);
205
206 return( true );
207 }
208 break;
209
210 case SG_VERTEX_TYPE_XYZM:
211 if( SG_SSCANF(Text.c_str(), SG_T("%lf %lf %lf %lf"), &x, &y, &z, &m) == 4 )
212 {
213 pShape->Add_Point(x, y, iPart);
214 pShape->Set_Z (z, pShape->Get_Point_Count(iPart) - 1, iPart);
215 pShape->Set_M (m, pShape->Get_Point_Count(iPart) - 1, iPart);
216
217 return( true );
218 }
219 break;
220 }
221
222 return( false );
223 }
224
225 //---------------------------------------------------------
_WKT_Read_Points(const CSG_String & Text,CSG_Shape * pShape)226 bool CSG_Shapes_OGIS_Converter::_WKT_Read_Points(const CSG_String &Text, CSG_Shape *pShape)
227 {
228 int iPart = pShape->Get_Part_Count();
229 CSG_String s(Text.AfterFirst('(').BeforeFirst(')'));
230
231 while( s.Length() > 0 )
232 {
233 if( !_WKT_Read_Point(s, pShape, iPart) )
234 {
235 return( false );
236 }
237
238 s = s.AfterFirst(',');
239 }
240
241 return( pShape->Get_Point_Count(iPart) > 0 );
242 }
243
244 //---------------------------------------------------------
_WKT_Read_Parts(const CSG_String & Text,CSG_Shape * pShape)245 bool CSG_Shapes_OGIS_Converter::_WKT_Read_Parts(const CSG_String &Text, CSG_Shape *pShape)
246 {
247 CSG_String s = Text.AfterFirst('(').BeforeLast(')');
248
249 while( s.Length() > 0 )
250 {
251 _WKT_Read_Points(s, pShape);
252
253 s = s.AfterFirst(',');
254 }
255
256 return( pShape->Get_Part_Count() > 0 );
257 }
258
259 //---------------------------------------------------------
_WKT_Read_Polygon(const CSG_String & Text,CSG_Shape * pShape)260 bool CSG_Shapes_OGIS_Converter::_WKT_Read_Polygon(const CSG_String &Text, CSG_Shape *pShape)
261 {
262 CSG_String Part;
263
264 for(int i=0, Level=-2; i<(int)Text.Length(); i++)
265 {
266 if( Text[i] == '(' )
267 {
268 Level++;
269 }
270 else if( Text[i] == ')' )
271 {
272 if( Level == 0 )
273 {
274 Part += Text[i];
275 _WKT_Read_Parts(Part, pShape);
276 Part.Clear();
277 }
278
279 Level--;
280 }
281
282 if( Level >= 0 )
283 {
284 Part += Text[i];
285 }
286 }
287
288 return( pShape->Get_Part_Count() > 0 );
289 }
290
291 //---------------------------------------------------------
from_WKText(const CSG_String & Text,CSG_Shape * pShape)292 bool CSG_Shapes_OGIS_Converter::from_WKText(const CSG_String &Text, CSG_Shape *pShape)
293 {
294 pShape->Del_Parts();
295
296 CSG_String Type(Text.BeforeFirst('('));
297
298 Type.Trim(true );
299 Type.Trim(false);
300
301 if( pShape->Get_Type() == to_ShapeType(Type) )
302 {
303 switch( Type_asWKBinary(Type) )
304 {
305 case SG_OGIS_TYPE_Point:
306 case SG_OGIS_TYPE_PointZ:
307 case SG_OGIS_TYPE_PointM:
308 case SG_OGIS_TYPE_PointZM:
309 return( _WKT_Read_Point(Text.AfterFirst('(').BeforeFirst(')'), pShape, 0) );
310
311 case SG_OGIS_TYPE_MultiPoint:
312 case SG_OGIS_TYPE_MultiPointZ:
313 case SG_OGIS_TYPE_MultiPointM:
314 case SG_OGIS_TYPE_MultiPointZM:
315 return( _WKT_Read_Parts (Text, pShape) );
316
317 case SG_OGIS_TYPE_LineString:
318 case SG_OGIS_TYPE_LineStringZ:
319 case SG_OGIS_TYPE_LineStringM:
320 case SG_OGIS_TYPE_LineStringZM:
321 return( _WKT_Read_Points (Text, pShape) );
322
323 case SG_OGIS_TYPE_MultiLineString:
324 case SG_OGIS_TYPE_MultiLineStringZ:
325 case SG_OGIS_TYPE_MultiLineStringM:
326 case SG_OGIS_TYPE_MultiLineStringZM:
327 return( _WKT_Read_Parts (Text, pShape) );
328
329 case SG_OGIS_TYPE_Polygon:
330 case SG_OGIS_TYPE_PolygonZ:
331 case SG_OGIS_TYPE_PolygonM:
332 case SG_OGIS_TYPE_PolygonZM:
333 return( _WKT_Read_Parts (Text, pShape) );
334
335 case SG_OGIS_TYPE_MultiPolygon:
336 case SG_OGIS_TYPE_MultiPolygonZ:
337 case SG_OGIS_TYPE_MultiPolygonM:
338 case SG_OGIS_TYPE_MultiPolygonZM:
339 return( _WKT_Read_Polygon(Text, pShape) );
340 }
341 }
342
343 return( false );
344 }
345
346
347 ///////////////////////////////////////////////////////////
348 // //
349 ///////////////////////////////////////////////////////////
350
351 //---------------------------------------------------------
_WKT_Write_Point(CSG_String & Text,CSG_Shape * pShape,int iPoint,int iPart)352 inline bool CSG_Shapes_OGIS_Converter::_WKT_Write_Point(CSG_String &Text, CSG_Shape *pShape, int iPoint, int iPart)
353 {
354 TSG_Point Point = pShape->Get_Point(iPoint, iPart);
355
356 switch( ((CSG_Shapes *)pShape->Get_Table())->Get_Vertex_Type() )
357 {
358 case SG_VERTEX_TYPE_XY:
359 Text += CSG_String::Format("%f %f" , Point.x, Point.y);
360 break;
361
362 case SG_VERTEX_TYPE_XYZ:
363 Text += CSG_String::Format("%f %f %f" , Point.x, Point.y, pShape->Get_Z(iPoint, iPart));
364 break;
365
366 case SG_VERTEX_TYPE_XYZM:
367 Text += CSG_String::Format("%f %f %f %f", Point.x, Point.y, pShape->Get_Z(iPoint, iPart), pShape->Get_M(iPoint, iPart));
368 break;
369 }
370
371 return( false );
372 }
373
374 //---------------------------------------------------------
_WKT_Write_Points(CSG_String & Text,CSG_Shape * pShape,int iPart)375 inline bool CSG_Shapes_OGIS_Converter::_WKT_Write_Points(CSG_String &Text, CSG_Shape *pShape, int iPart)
376 {
377 Text += SG_T("(");
378
379 for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
380 {
381 if( iPoint > 0 )
382 {
383 Text += SG_T(", ");
384 }
385
386 _WKT_Write_Point(Text, pShape, iPoint, iPart);
387 }
388
389 if( pShape->Get_Type() == SHAPE_TYPE_Polygon && CSG_Point(pShape->Get_Point(0, iPart)) != pShape->Get_Point(pShape->Get_Point_Count(iPart) -1, iPart) )
390 {
391 Text += SG_T(", ");
392
393 _WKT_Write_Point(Text, pShape, 0, iPart);
394 }
395
396 Text += SG_T(")");
397
398 return( true );
399 }
400
401 //---------------------------------------------------------
_WKT_Write_Parts(CSG_String & Text,CSG_Shape * pShape)402 inline bool CSG_Shapes_OGIS_Converter::_WKT_Write_Parts(CSG_String &Text, CSG_Shape *pShape)
403 {
404 Text += SG_T("(");
405
406 for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
407 {
408 if( iPart > 0 )
409 {
410 Text += SG_T(", ");
411 }
412
413 _WKT_Write_Points(Text, pShape, iPart);
414 }
415
416 Text += SG_T(")");
417
418 return( true );
419 }
420
421 //---------------------------------------------------------
_WKT_Write_Polygon(CSG_String & Text,CSG_Shape * pShape)422 inline bool CSG_Shapes_OGIS_Converter::_WKT_Write_Polygon(CSG_String &Text, CSG_Shape *pShape)
423 {
424 Text += SG_T("(");
425
426 for(int iPart=0, nIslands=0; iPart<pShape->Get_Part_Count(); iPart++)
427 {
428 if( ((CSG_Shape_Polygon *)pShape)->is_Lake(iPart) == false )
429 {
430 if( nIslands++ > 0 )
431 {
432 Text += SG_T(", ");
433 }
434
435 Text += SG_T("(");
436
437 _WKT_Write_Points(Text, pShape, iPart);
438
439 for(int jPart=0; jPart<pShape->Get_Part_Count(); jPart++)
440 {
441 if( ((CSG_Shape_Polygon *)pShape)->is_Lake(jPart) && ((CSG_Shape_Polygon *)pShape)->Contains(pShape->Get_Point(0, jPart), iPart) )
442 {
443 Text += SG_T(", ");
444
445 _WKT_Write_Points(Text, pShape, jPart);
446 }
447 }
448
449 Text += SG_T(")");
450 }
451 }
452
453 Text += SG_T(")");
454
455 return( true );
456 }
457
458 //---------------------------------------------------------
to_WKText(CSG_Shape * pShape,CSG_String & Text)459 bool CSG_Shapes_OGIS_Converter::to_WKText(CSG_Shape *pShape, CSG_String &Text)
460 {
461 switch( pShape->Get_Type() )
462 {
463 default:
464 return( false );
465
466 case SHAPE_TYPE_Point:
467 _WKT_Write_Points (Text = from_ShapeType(pShape->Get_Type(), pShape->Get_Vertex_Type()), pShape, 0);
468 break;
469
470 case SHAPE_TYPE_Points:
471 _WKT_Write_Parts (Text = from_ShapeType(pShape->Get_Type(), pShape->Get_Vertex_Type()), pShape);
472 break;
473
474 case SHAPE_TYPE_Line:
475 _WKT_Write_Parts (Text = from_ShapeType(pShape->Get_Type(), pShape->Get_Vertex_Type()), pShape);
476 break;
477
478 case SHAPE_TYPE_Polygon:
479 _WKT_Write_Polygon(Text = from_ShapeType(pShape->Get_Type(), pShape->Get_Vertex_Type()), pShape);
480 break;
481 }
482
483 return( true );
484 }
485
486
487 ///////////////////////////////////////////////////////////
488 // //
489 ///////////////////////////////////////////////////////////
490
491 //---------------------------------------------------------
_WKB_Read_Point(CSG_Bytes & Bytes,bool bSwapBytes,CSG_Shape * pShape,int iPart)492 inline bool CSG_Shapes_OGIS_Converter::_WKB_Read_Point(CSG_Bytes &Bytes, bool bSwapBytes, CSG_Shape *pShape, int iPart)
493 {
494 if( Bytes.is_EOF() )
495 {
496 return( false );
497 }
498
499 double x, y;
500
501 x = Bytes.Read_Double(bSwapBytes);
502 y = Bytes.Read_Double(bSwapBytes);
503
504 pShape->Add_Point(x, y, iPart);
505
506 switch( ((CSG_Shapes *)pShape->Get_Table())->Get_Vertex_Type() )
507 {
508 case SG_VERTEX_TYPE_XY:
509 break;
510
511 case SG_VERTEX_TYPE_XYZ:
512 pShape->Set_Z(Bytes.Read_Double(bSwapBytes), pShape->Get_Point_Count(iPart) - 1, iPart);
513 break;
514
515 case SG_VERTEX_TYPE_XYZM:
516 pShape->Set_Z(Bytes.Read_Double(bSwapBytes), pShape->Get_Point_Count(iPart) - 1, iPart);
517 pShape->Set_M(Bytes.Read_Double(bSwapBytes), pShape->Get_Point_Count(iPart) - 1, iPart);
518 break;
519 }
520
521 return( true );
522 }
523
524 //---------------------------------------------------------
_WKB_Read_Points(CSG_Bytes & Bytes,bool bSwapBytes,CSG_Shape * pShape)525 bool CSG_Shapes_OGIS_Converter::_WKB_Read_Points(CSG_Bytes &Bytes, bool bSwapBytes, CSG_Shape *pShape)
526 {
527 DWORD iPart = pShape->Get_Part_Count();
528 DWORD nPoints = Bytes.Read_DWord(bSwapBytes);
529
530 for(DWORD iPoint=0; iPoint<nPoints; iPoint++)
531 {
532 if( !_WKB_Read_Point(Bytes, bSwapBytes, pShape, iPart) )
533 {
534 return( false );
535 }
536 }
537
538 return( pShape->Get_Point_Count(iPart) > 0 );
539 }
540
541 //---------------------------------------------------------
_WKB_Read_Parts(CSG_Bytes & Bytes,bool bSwapBytes,CSG_Shape * pShape)542 bool CSG_Shapes_OGIS_Converter::_WKB_Read_Parts(CSG_Bytes &Bytes, bool bSwapBytes, CSG_Shape *pShape)
543 {
544 DWORD iPart, nParts = Bytes.Read_DWord(bSwapBytes);
545
546 for(iPart=0; iPart<nParts; iPart++)
547 {
548 if( !_WKB_Read_Points(Bytes, bSwapBytes, pShape) )
549 {
550 return( false );
551 }
552 }
553
554 return( pShape->Get_Part_Count() > 0 );
555 }
556
557 //---------------------------------------------------------
_WKB_Read_MultiLine(CSG_Bytes & Bytes,bool bSwapBytes,CSG_Shape * pShape)558 bool CSG_Shapes_OGIS_Converter::_WKB_Read_MultiLine(CSG_Bytes &Bytes, bool bSwapBytes, CSG_Shape *pShape)
559 {
560 DWORD nLines = Bytes.Read_DWord(bSwapBytes);
561
562 for(DWORD iLine=0; iLine<nLines; iLine++)
563 {
564 bSwapBytes = Bytes.Read_Byte() != SG_OGIS_BYTEORDER_NDR;
565
566 if( Bytes.Read_DWord(bSwapBytes) != SG_OGIS_TYPE_LineString || !_WKB_Read_Points(Bytes, bSwapBytes, pShape) )
567 {
568 return( false );
569 }
570 }
571
572 return( pShape->Get_Part_Count() > 0 );
573 }
574
575 //---------------------------------------------------------
_WKB_Read_MultiPolygon(CSG_Bytes & Bytes,bool bSwapBytes,CSG_Shape * pShape)576 bool CSG_Shapes_OGIS_Converter::_WKB_Read_MultiPolygon(CSG_Bytes &Bytes, bool bSwapBytes, CSG_Shape *pShape)
577 {
578 DWORD nPolygons = Bytes.Read_DWord(bSwapBytes);
579
580 for(DWORD iPolygon=0; iPolygon<nPolygons; iPolygon++)
581 {
582 bSwapBytes = Bytes.Read_Byte() != SG_OGIS_BYTEORDER_NDR;
583
584 if( Bytes.Read_DWord(bSwapBytes) != SG_OGIS_TYPE_Polygon || !_WKB_Read_Parts(Bytes, bSwapBytes, pShape) )
585 {
586 return( false );
587 }
588 }
589
590 return( pShape->Get_Part_Count() > 0 );
591 }
592
593 //---------------------------------------------------------
from_WKBinary(CSG_Bytes & Bytes,CSG_Shape * pShape)594 bool CSG_Shapes_OGIS_Converter::from_WKBinary(CSG_Bytes &Bytes, CSG_Shape *pShape)
595 {
596 pShape->Del_Parts();
597
598 if( Bytes.Get_Count() > 3 )
599 {
600 Bytes.Rewind();
601
602 bool bSwapBytes = Bytes.Read_Byte() != SG_OGIS_BYTEORDER_NDR;
603
604 DWORD Type = Bytes.Read_DWord();
605
606 if( pShape->Get_Type() == to_ShapeType(Type) )
607 {
608 switch( Type )
609 {
610 case SG_OGIS_TYPE_Point:
611 case SG_OGIS_TYPE_PointZ:
612 case SG_OGIS_TYPE_PointM:
613 case SG_OGIS_TYPE_PointZM:
614 return( _WKB_Read_Point (Bytes, bSwapBytes, pShape, 0) );
615
616 case SG_OGIS_TYPE_MultiPoint:
617 case SG_OGIS_TYPE_MultiPointZ:
618 case SG_OGIS_TYPE_MultiPointM:
619 case SG_OGIS_TYPE_MultiPointZM:
620 return( _WKB_Read_Parts (Bytes, bSwapBytes, pShape) );
621
622 case SG_OGIS_TYPE_LineString:
623 case SG_OGIS_TYPE_LineStringZ:
624 case SG_OGIS_TYPE_LineStringM:
625 case SG_OGIS_TYPE_LineStringZM:
626 return( _WKB_Read_Points (Bytes, bSwapBytes, pShape) );
627
628 case SG_OGIS_TYPE_MultiLineString:
629 case SG_OGIS_TYPE_MultiLineStringZ:
630 case SG_OGIS_TYPE_MultiLineStringM:
631 case SG_OGIS_TYPE_MultiLineStringZM:
632 return( _WKB_Read_MultiLine (Bytes, bSwapBytes, pShape) );
633
634 case SG_OGIS_TYPE_Polygon:
635 case SG_OGIS_TYPE_PolygonZ:
636 case SG_OGIS_TYPE_PolygonM:
637 case SG_OGIS_TYPE_PolygonZM:
638 return( _WKB_Read_Parts (Bytes, bSwapBytes, pShape) );
639
640 case SG_OGIS_TYPE_MultiPolygon:
641 case SG_OGIS_TYPE_MultiPolygonZ:
642 case SG_OGIS_TYPE_MultiPolygonM:
643 case SG_OGIS_TYPE_MultiPolygonZM:
644 return( _WKB_Read_MultiPolygon(Bytes, bSwapBytes, pShape) );
645 }
646 }
647 }
648
649 return( false );
650 }
651
652
653 ///////////////////////////////////////////////////////////
654 // //
655 ///////////////////////////////////////////////////////////
656
657 //---------------------------------------------------------
_WKB_Write_Point(CSG_Bytes & Bytes,CSG_Shape * pShape,int iPoint,int iPart)658 inline bool CSG_Shapes_OGIS_Converter::_WKB_Write_Point(CSG_Bytes &Bytes, CSG_Shape *pShape, int iPoint, int iPart)
659 {
660 TSG_Point Point = pShape->Get_Point(iPoint, iPart);
661
662 Bytes += Point.x;
663 Bytes += Point.y;
664
665 switch( pShape->Get_Vertex_Type() )
666 {
667 case SG_VERTEX_TYPE_XY:
668 break;
669
670 case SG_VERTEX_TYPE_XYZ:
671 Bytes += pShape->Get_Z(iPoint, iPart);
672 break;
673
674 case SG_VERTEX_TYPE_XYZM:
675 Bytes += pShape->Get_Z(iPoint, iPart);
676 Bytes += pShape->Get_M(iPoint, iPart);
677 break;
678 }
679
680 return( true );
681 }
682
683 //---------------------------------------------------------
_WKB_Write_Points(CSG_Bytes & Bytes,CSG_Shape * pShape,int iPart)684 bool CSG_Shapes_OGIS_Converter::_WKB_Write_Points(CSG_Bytes &Bytes, CSG_Shape *pShape, int iPart)
685 {
686 bool bFirstTwice = pShape->Get_Type() == SHAPE_TYPE_Polygon && CSG_Point(pShape->Get_Point(0, iPart)) != pShape->Get_Point(pShape->Get_Point_Count(iPart) -1, iPart);
687
688 Bytes += (DWORD)(pShape->Get_Point_Count(iPart) + (bFirstTwice ? 1 : 0));
689
690 for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
691 {
692 _WKB_Write_Point(Bytes, pShape, iPoint, iPart);
693 }
694
695 if( bFirstTwice )
696 {
697 _WKB_Write_Point(Bytes, pShape, 0, iPart);
698 }
699
700 return( true );
701 }
702
703 //---------------------------------------------------------
_WKB_Write_Parts(CSG_Bytes & Bytes,CSG_Shape * pShape)704 bool CSG_Shapes_OGIS_Converter::_WKB_Write_Parts(CSG_Bytes &Bytes, CSG_Shape *pShape)
705 {
706 Bytes += (DWORD)pShape->Get_Part_Count();
707
708 for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
709 {
710 if( !_WKB_Write_Points(Bytes, pShape, iPart) )
711 {
712 return( false );
713 }
714 }
715
716 return( true );
717 }
718
719 //---------------------------------------------------------
_WKB_Write_MultiLine(CSG_Bytes & Bytes,CSG_Shape * pShape)720 bool CSG_Shapes_OGIS_Converter::_WKB_Write_MultiLine(CSG_Bytes &Bytes, CSG_Shape *pShape)
721 {
722 Bytes += (DWORD)pShape->Get_Part_Count();
723
724 for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
725 {
726 Bytes += (BYTE)SG_OGIS_BYTEORDER_NDR;
727 Bytes += (DWORD)SG_OGIS_TYPE_LineString;
728
729 if( !_WKB_Write_Points(Bytes, pShape, iPart) )
730 {
731 return( false );
732 }
733 }
734
735 return( true );
736 }
737
738 //---------------------------------------------------------
_WKB_Write_MultiPolygon(CSG_Bytes & Bytes,CSG_Shape * pShape)739 bool CSG_Shapes_OGIS_Converter::_WKB_Write_MultiPolygon(CSG_Bytes &Bytes, CSG_Shape *pShape)
740 {
741 int iPart, nPolygons, *nRings, *iPolygon;
742
743 nPolygons = 0;
744 nRings = new int[pShape->Get_Part_Count()];
745 iPolygon = new int[pShape->Get_Part_Count()];
746
747 for(iPart=0, nPolygons=0; iPart<pShape->Get_Part_Count(); iPart++)
748 {
749 nRings [iPart] = 0;
750
751 if( ((CSG_Shape_Polygon *)pShape)->is_Lake(iPart) == false )
752 {
753 nPolygons ++;
754 nRings [iPart] ++;
755 iPolygon[iPart] = iPart;
756
757 for(int jPart=0; jPart<pShape->Get_Part_Count(); jPart++)
758 {
759 if( ((CSG_Shape_Polygon *)pShape)->is_Lake(jPart) && ((CSG_Shape_Polygon *)pShape)->Contains(pShape->Get_Point(0, jPart), iPart) )
760 {
761 nRings [iPart]++;
762 iPolygon[jPart] = iPart;
763 }
764 }
765 }
766 }
767
768 Bytes += (DWORD)nPolygons;
769
770 for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
771 {
772 if( nRings[iPart] > 0 )
773 {
774 Bytes += (BYTE)SG_OGIS_BYTEORDER_NDR;
775 Bytes += (DWORD)SG_OGIS_TYPE_Polygon;
776 Bytes += (DWORD)nRings[iPart];
777
778 for(int jPart=0; jPart<pShape->Get_Part_Count(); jPart++)
779 {
780 if( iPolygon[jPart] == iPart )
781 {
782 if( !_WKB_Write_Points(Bytes, pShape, jPart) )
783 {
784 delete[](nRings);
785 delete[](iPolygon);
786 return( false );
787 }
788 }
789 }
790 }
791 }
792
793 delete[](nRings);
794 delete[](iPolygon);
795
796 return( nPolygons > 0 );
797 }
798
799 //---------------------------------------------------------
to_WKBinary(CSG_Shape * pShape,CSG_Bytes & Bytes)800 bool CSG_Shapes_OGIS_Converter::to_WKBinary(CSG_Shape *pShape, CSG_Bytes &Bytes)
801 {
802 DWORD Type;
803
804 if( from_ShapeType(Type, pShape->Get_Type(), pShape->Get_Vertex_Type()) )
805 {
806 Bytes.Destroy();
807
808 Bytes += (BYTE)SG_OGIS_BYTEORDER_NDR;
809 Bytes += Type;
810
811 switch( pShape->Get_Type() )
812 {
813 case SHAPE_TYPE_Point : return( _WKB_Write_Point (Bytes, pShape, 0, 0) );
814 case SHAPE_TYPE_Points : return( _WKB_Write_Points (Bytes, pShape, 0 ) );
815 case SHAPE_TYPE_Line : return( _WKB_Write_MultiLine (Bytes, pShape ) );
816 case SHAPE_TYPE_Polygon: return( _WKB_Write_MultiPolygon(Bytes, pShape ) );
817
818 default: break;
819 }
820 }
821
822 return( false );
823 }
824
825
826 ///////////////////////////////////////////////////////////
827 // //
828 // //
829 // //
830 ///////////////////////////////////////////////////////////
831
832 //---------------------------------------------------------
from_ShapeType(CSG_String & Type,TSG_Shape_Type Shape,TSG_Vertex_Type Vertex)833 bool CSG_Shapes_OGIS_Converter::from_ShapeType(CSG_String &Type, TSG_Shape_Type Shape, TSG_Vertex_Type Vertex)
834 {
835 switch( Vertex )
836 {
837 case SG_VERTEX_TYPE_XY:
838 switch( Shape )
839 {
840 default: break;
841 case SHAPE_TYPE_Point: Type = Type_asWKText(SG_OGIS_TYPE_Point ); return( true );
842 case SHAPE_TYPE_Points: Type = Type_asWKText(SG_OGIS_TYPE_MultiPoint ); return( true );
843 case SHAPE_TYPE_Line: Type = Type_asWKText(SG_OGIS_TYPE_MultiLineString ); return( true );
844 case SHAPE_TYPE_Polygon: Type = Type_asWKText(SG_OGIS_TYPE_MultiPolygon ); return( true );
845 }
846 break;
847
848 case SG_VERTEX_TYPE_XYZ:
849 switch( Shape )
850 {
851 default: break;
852 case SHAPE_TYPE_Point: Type = Type_asWKText(SG_OGIS_TYPE_PointZ ); return( true );
853 case SHAPE_TYPE_Points: Type = Type_asWKText(SG_OGIS_TYPE_MultiPointZ ); return( true );
854 case SHAPE_TYPE_Line: Type = Type_asWKText(SG_OGIS_TYPE_MultiLineStringZ ); return( true );
855 case SHAPE_TYPE_Polygon: Type = Type_asWKText(SG_OGIS_TYPE_MultiPolygonZ ); return( true );
856 }
857 break;
858
859 case SG_VERTEX_TYPE_XYZM:
860 switch( Shape )
861 {
862 default: break;
863 case SHAPE_TYPE_Point: Type = Type_asWKText(SG_OGIS_TYPE_PointZM ); return( true );
864 case SHAPE_TYPE_Points: Type = Type_asWKText(SG_OGIS_TYPE_MultiPointZM ); return( true );
865 case SHAPE_TYPE_Line: Type = Type_asWKText(SG_OGIS_TYPE_MultiLineStringZM); return( true );
866 case SHAPE_TYPE_Polygon: Type = Type_asWKText(SG_OGIS_TYPE_MultiPolygonZM ); return( true );
867 }
868 break;
869 }
870
871 return( false );
872 }
873
874 //---------------------------------------------------------
from_ShapeType(DWORD & Type,TSG_Shape_Type Shape,TSG_Vertex_Type Vertex)875 bool CSG_Shapes_OGIS_Converter::from_ShapeType(DWORD &Type, TSG_Shape_Type Shape, TSG_Vertex_Type Vertex)
876 {
877 switch( Vertex )
878 {
879 case SG_VERTEX_TYPE_XY:
880 switch( Shape )
881 {
882 default: break;
883 case SHAPE_TYPE_Point: Type = SG_OGIS_TYPE_Point; return( true );
884 case SHAPE_TYPE_Points: Type = SG_OGIS_TYPE_MultiPoint; return( true );
885 case SHAPE_TYPE_Line: Type = SG_OGIS_TYPE_MultiLineString; return( true );
886 case SHAPE_TYPE_Polygon: Type = SG_OGIS_TYPE_MultiPolygon; return( true );
887 }
888 break;
889
890 case SG_VERTEX_TYPE_XYZ:
891 switch( Shape )
892 {
893 default: break;
894 case SHAPE_TYPE_Point: Type = SG_OGIS_TYPE_PointZ; return( true );
895 case SHAPE_TYPE_Points: Type = SG_OGIS_TYPE_MultiPointZ; return( true );
896 case SHAPE_TYPE_Line: Type = SG_OGIS_TYPE_MultiLineStringZ; return( true );
897 case SHAPE_TYPE_Polygon: Type = SG_OGIS_TYPE_MultiPolygonZ; return( true );
898 }
899 break;
900
901 case SG_VERTEX_TYPE_XYZM:
902 switch( Shape )
903 {
904 default: break;
905 case SHAPE_TYPE_Point: Type = SG_OGIS_TYPE_PointZM; return( true );
906 case SHAPE_TYPE_Points: Type = SG_OGIS_TYPE_MultiPointZM; return( true );
907 case SHAPE_TYPE_Line: Type = SG_OGIS_TYPE_MultiLineStringZM; return( true );
908 case SHAPE_TYPE_Polygon: Type = SG_OGIS_TYPE_MultiPolygonZM; return( true );
909 }
910 break;
911 }
912
913 return( false );
914 }
915
916 //---------------------------------------------------------
from_ShapeType(TSG_Shape_Type Shape,TSG_Vertex_Type Vertex)917 CSG_String CSG_Shapes_OGIS_Converter::from_ShapeType(TSG_Shape_Type Shape, TSG_Vertex_Type Vertex)
918 {
919 CSG_String Type;
920
921 from_ShapeType(Type, Shape, Vertex);
922
923 return( Type );
924 }
925
926 //---------------------------------------------------------
to_ShapeType(const CSG_String & Type,TSG_Shape_Type & Shape,TSG_Vertex_Type & Vertex)927 bool CSG_Shapes_OGIS_Converter::to_ShapeType(const CSG_String &Type, TSG_Shape_Type &Shape, TSG_Vertex_Type &Vertex)
928 {
929 switch( Type_asWKBinary(Type) )
930 {
931 case SG_OGIS_TYPE_Point : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XY; return( true );
932 case SG_OGIS_TYPE_MultiPoint : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XY; return( true );
933 case SG_OGIS_TYPE_LineString : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XY; return( true );
934 case SG_OGIS_TYPE_MultiLineString : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XY; return( true );
935 case SG_OGIS_TYPE_Polygon : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XY; return( true );
936 case SG_OGIS_TYPE_MultiPolygon : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XY; return( true );
937
938 case SG_OGIS_TYPE_PointZ : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
939 case SG_OGIS_TYPE_MultiPointZ : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
940 case SG_OGIS_TYPE_LineStringZ : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
941 case SG_OGIS_TYPE_MultiLineStringZ : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
942 case SG_OGIS_TYPE_PolygonZ : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
943 case SG_OGIS_TYPE_MultiPolygonZ : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
944
945 case SG_OGIS_TYPE_PointM : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
946 case SG_OGIS_TYPE_MultiPointM : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
947 case SG_OGIS_TYPE_LineStringM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
948 case SG_OGIS_TYPE_MultiLineStringM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
949 case SG_OGIS_TYPE_PolygonM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
950 case SG_OGIS_TYPE_MultiPolygonM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
951
952 case SG_OGIS_TYPE_PointZM : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
953 case SG_OGIS_TYPE_MultiPointZM : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
954 case SG_OGIS_TYPE_LineStringZM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
955 case SG_OGIS_TYPE_MultiLineStringZM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
956 case SG_OGIS_TYPE_PolygonZM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
957 case SG_OGIS_TYPE_MultiPolygonZM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
958 }
959
960 Shape = SHAPE_TYPE_Undefined;
961
962 return( false );
963 }
964
965 //---------------------------------------------------------
to_ShapeType(DWORD Type,TSG_Shape_Type & Shape,TSG_Vertex_Type & Vertex)966 bool CSG_Shapes_OGIS_Converter::to_ShapeType(DWORD Type, TSG_Shape_Type &Shape, TSG_Vertex_Type &Vertex)
967 {
968 switch( Type )
969 {
970 case SG_OGIS_TYPE_Point : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XY; return( true );
971 case SG_OGIS_TYPE_MultiPoint : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XY; return( true );
972 case SG_OGIS_TYPE_LineString : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XY; return( true );
973 case SG_OGIS_TYPE_MultiLineString : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XY; return( true );
974 case SG_OGIS_TYPE_Polygon : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XY; return( true );
975 case SG_OGIS_TYPE_MultiPolygon : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XY; return( true );
976
977 case SG_OGIS_TYPE_PointZ : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
978 case SG_OGIS_TYPE_MultiPointZ : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
979 case SG_OGIS_TYPE_LineStringZ : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
980 case SG_OGIS_TYPE_MultiLineStringZ : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
981 case SG_OGIS_TYPE_PolygonZ : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
982 case SG_OGIS_TYPE_MultiPolygonZ : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
983
984 case SG_OGIS_TYPE_PointM : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
985 case SG_OGIS_TYPE_MultiPointM : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
986 case SG_OGIS_TYPE_LineStringM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
987 case SG_OGIS_TYPE_MultiLineStringM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
988 case SG_OGIS_TYPE_PolygonM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
989 case SG_OGIS_TYPE_MultiPolygonM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZ; return( true );
990
991 case SG_OGIS_TYPE_PointZM : Shape = SHAPE_TYPE_Point; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
992 case SG_OGIS_TYPE_MultiPointZM : Shape = SHAPE_TYPE_Points; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
993 case SG_OGIS_TYPE_LineStringZM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
994 case SG_OGIS_TYPE_MultiLineStringZM : Shape = SHAPE_TYPE_Line; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
995 case SG_OGIS_TYPE_PolygonZM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
996 case SG_OGIS_TYPE_MultiPolygonZM : Shape = SHAPE_TYPE_Polygon; Vertex = SG_VERTEX_TYPE_XYZM; return( true );
997 }
998
999 Shape = SHAPE_TYPE_Undefined;
1000
1001 return( false );
1002 }
1003
1004 //---------------------------------------------------------
to_ShapeType(const CSG_String & Type)1005 TSG_Shape_Type CSG_Shapes_OGIS_Converter::to_ShapeType(const CSG_String &Type)
1006 {
1007 TSG_Shape_Type Shape;
1008 TSG_Vertex_Type Vertex;
1009
1010 to_ShapeType(Type, Shape, Vertex);
1011
1012 return( Shape );
1013 }
1014
1015 //---------------------------------------------------------
to_ShapeType(DWORD Type)1016 TSG_Shape_Type CSG_Shapes_OGIS_Converter::to_ShapeType(DWORD Type)
1017 {
1018 TSG_Shape_Type Shape;
1019 TSG_Vertex_Type Vertex;
1020
1021 to_ShapeType(Type, Shape, Vertex);
1022
1023 return( Shape );
1024 }
1025
1026
1027 ///////////////////////////////////////////////////////////
1028 // //
1029 // //
1030 // //
1031 ///////////////////////////////////////////////////////////
1032
1033 //---------------------------------------------------------
1034 // Basic Type definitions
1035 // byte : 1 byte
1036 // uint16 : 16 bit unsigned integer (2 bytes)
1037 // uint32 : 32 bit unsigned integer (4 bytes)
1038 // float64 : double precision floating point number (8 bytes)
1039 //
1040 // +------------------------------------------------------------+
1041 // | RASTER |
1042 // +---------------+-------------+------------------------------+
1043 // | - name - | - type - | - meaning - |
1044 // +---------------+-------------+------------------------------+
1045 // | endianness | byte | 1:ndr/little endian |
1046 // | | | 0:xdr/big endian |
1047 // +---------------+-------------+------------------------------+
1048 // | version | uint16 | format version (0 for this |
1049 // | | | structure) |
1050 // +---------------+-------------+------------------------------+
1051 // | nBands | uint16 | Number of bands |
1052 // +---------------+-------------+------------------------------+
1053 // | scaleX | float64 | pixel width |
1054 // | | | in geographical units |
1055 // +---------------+-------------+------------------------------+
1056 // | scaleY | float64 | pixel height |
1057 // | | | in geographical units |
1058 // +---------------+-------------+------------------------------+
1059 // | ipX | float64 | X ordinate of upper-left |
1060 // | | | pixel's upper-left corner |
1061 // | | | in geographical units |
1062 // +---------------+-------------+------------------------------+
1063 // | ipY | float64 | Y ordinate of upper-left |
1064 // | | | pixel's upper-left corner |
1065 // | | | in geographical units |
1066 // +---------------+-------------+------------------------------+
1067 // | skewX | float64 | rotation about Y-axis |
1068 // +---------------+-------------+------------------------------+
1069 // | skewY | float64 | rotation about X-axis |
1070 // +---------------+-------------+------------------------------+
1071 // | srid | int32 | Spatial reference id |
1072 // +---------------+-------------+------------------------------+
1073 // | width | uint16 | number of pixel columns |
1074 // +---------------+-------------+------------------------------+
1075 // | height | uint16 | number of pixel rows |
1076 // +---------------+-------------+------------------------------+
1077 // | bands[nBands] | RASTERBAND | Bands data |
1078 // +---------------+-------------+------------------------------+
1079
1080 ///////////////////////////////////////////////////////////
1081 // //
1082 ///////////////////////////////////////////////////////////
1083
1084 //---------------------------------------------------------
1085 #include "grid.h"
1086
1087
1088 ///////////////////////////////////////////////////////////
1089 // //
1090 ///////////////////////////////////////////////////////////
1091
1092 //---------------------------------------------------------
from_WKBinary(CSG_Bytes & Bytes,class CSG_Grid * pGrid)1093 bool CSG_Grid_OGIS_Converter::from_WKBinary(CSG_Bytes &Bytes, class CSG_Grid *pGrid)
1094 {
1095 Bytes.Rewind();
1096
1097 //-----------------------------------------------------
1098 // Raster System
1099
1100 bool bSwap = Bytes.Read_Byte () == 0; // endiannes: 1=ndr/little endian, 0=xdr/big endian
1101 short version = Bytes.Read_Short (bSwap); // version
1102 short nBands = Bytes.Read_Short (bSwap); // number of bands
1103 double dx = Bytes.Read_Double(bSwap); // scaleX
1104 double dy = Bytes.Read_Double(bSwap); // scaleY
1105 double xMin = Bytes.Read_Double(bSwap); // ipX
1106 double yMax = Bytes.Read_Double(bSwap); // ipY
1107 double skewX = Bytes.Read_Double(bSwap); // skewX
1108 double skewY = Bytes.Read_Double(bSwap); // skewY
1109 int SRID = Bytes.Read_Int (bSwap); // srid
1110 short NX = Bytes.Read_Short (bSwap); // width
1111 short NY = Bytes.Read_Short (bSwap); // height
1112
1113 //-----------------------------------------------------
1114 // Band
1115
1116 TSG_Data_Type Type;
1117
1118 BYTE Flags = Bytes.Read_Byte();
1119
1120 switch( Flags & 0x0F )
1121 {
1122 case 0: Type = SG_DATATYPE_Bit ; break; // 0: 1-bit boolean
1123 case 1: Type = SG_DATATYPE_Char ; break; // 1: 2-bit unsigned integer
1124 case 2: Type = SG_DATATYPE_Char ; break; // 2: 4-bit unsigned integer
1125 case 3: Type = SG_DATATYPE_Char ; break; // 3: 8-bit signed integer
1126 case 4: Type = SG_DATATYPE_Byte ; break; // 4: 8-bit unsigned integer
1127 case 5: Type = SG_DATATYPE_Short ; break; // 5: 16-bit signed integer
1128 case 6: Type = SG_DATATYPE_Word ; break; // 6: 16-bit unsigned integer
1129 case 7: Type = SG_DATATYPE_Int ; break; // 7: 32-bit signed integer
1130 case 8: Type = SG_DATATYPE_DWord ; break; // 8: 32-bit unsigned integer
1131 case 10: Type = SG_DATATYPE_Float ; break; // 10: 32-bit float
1132 case 11: Type = SG_DATATYPE_Double; break; // 11: 64-bit float
1133 }
1134
1135 // Flags |= 0x80; // isOffline: no, never here!
1136 Flags |= 0x40; // hasNodataValue
1137 // Flags |= 0x20; // isNoDataValue: no, never here!
1138 // Flags |= 0x10; // reserved (unused)
1139
1140 if( !pGrid->Create(Type, NX, NY, dx, xMin + 0.5 * dx, yMax - (NY - 0.5) * dx) )
1141 {
1142 return( false );
1143 }
1144
1145 pGrid->Get_Projection().Create(SRID);
1146
1147 double noData;
1148
1149 switch( pGrid->Get_Type() )
1150 {
1151 case SG_DATATYPE_Bit : noData = Bytes.Read_Byte ( ); break; // 0: 1-bit boolean
1152 case SG_DATATYPE_Char : noData = Bytes.Read_Char ( ); break; // 3: 8-bit signed integer
1153 case SG_DATATYPE_Byte : noData = Bytes.Read_Byte ( ); break; // 4: 8-bit unsigned integer
1154 case SG_DATATYPE_Short : noData = Bytes.Read_Short (bSwap); break; // 5: 16-bit signed integer
1155 case SG_DATATYPE_Word : noData = Bytes.Read_Word (bSwap); break; // 6: 16-bit unsigned integer
1156 case SG_DATATYPE_Int : noData = Bytes.Read_Int (bSwap); break; // 7: 32-bit signed integer
1157 case SG_DATATYPE_DWord : noData = Bytes.Read_DWord (bSwap); break; // 8: 32-bit unsigned integer
1158 case SG_DATATYPE_Float : noData = Bytes.Read_Float (bSwap); break; // 9: 32-bit float
1159 case SG_DATATYPE_Double: noData = Bytes.Read_Double(bSwap); break; // 10: 64-bit float
1160 default:
1161 break;
1162 }
1163
1164 pGrid->Set_NoData_Value(noData);
1165
1166 for(int y=0; y<pGrid->Get_NY() && SG_UI_Process_Set_Progress(y, pGrid->Get_NY()); y++)
1167 {
1168 for(int x=0; x<pGrid->Get_NX(); x++)
1169 {
1170 switch( pGrid->Get_Type() )
1171 {
1172 case SG_DATATYPE_Bit : pGrid->Set_Value(x, y, Bytes.Read_Byte ( )); break; // 0: 1-bit boolean
1173 case SG_DATATYPE_Char : pGrid->Set_Value(x, y, Bytes.Read_Char ( )); break; // 3: 8-bit signed integer
1174 case SG_DATATYPE_Byte : pGrid->Set_Value(x, y, Bytes.Read_Byte ( )); break; // 4: 8-bit unsigned integer
1175 case SG_DATATYPE_Short : pGrid->Set_Value(x, y, Bytes.Read_Short (bSwap)); break; // 5: 16-bit signed integer
1176 case SG_DATATYPE_Word : pGrid->Set_Value(x, y, Bytes.Read_Word (bSwap)); break; // 6: 16-bit unsigned integer
1177 case SG_DATATYPE_Int : pGrid->Set_Value(x, y, Bytes.Read_Int (bSwap)); break; // 7: 32-bit signed integer
1178 case SG_DATATYPE_DWord : pGrid->Set_Value(x, y, Bytes.Read_DWord (bSwap)); break; // 8: 32-bit unsigned integer
1179 case SG_DATATYPE_Float : pGrid->Set_Value(x, y, Bytes.Read_Float (bSwap)); break; // 9: 32-bit float
1180 case SG_DATATYPE_Double: pGrid->Set_Value(x, y, Bytes.Read_Double(bSwap)); break; // 10: 64-bit float
1181 default:
1182 break;
1183 }
1184 }
1185 }
1186
1187 return( true );
1188 }
1189
1190 //---------------------------------------------------------
to_WKBinary(CSG_Bytes & Bytes,class CSG_Grid * pGrid,int SRID)1191 bool CSG_Grid_OGIS_Converter::to_WKBinary(CSG_Bytes &Bytes, class CSG_Grid *pGrid, int SRID)
1192 {
1193 Bytes.Clear();
1194
1195 //-----------------------------------------------------
1196 // Raster System
1197
1198 if( pGrid->Get_Projection().Get_EPSG() > 0 )
1199 {
1200 SRID = pGrid->Get_Projection().Get_EPSG();
1201 }
1202
1203 Bytes += (BYTE )1; // endiannes
1204 Bytes += (short )0; // version
1205 Bytes += (short )1; // number of bands
1206 Bytes += (double)pGrid->Get_Cellsize(); // scaleX
1207 Bytes += (double)pGrid->Get_Cellsize(); // scaleY
1208 Bytes += (double)pGrid->Get_XMin(true); // ipX
1209 Bytes += (double)pGrid->Get_YMax(true); // ipY
1210 Bytes += (double)0.0; // skewX
1211 Bytes += (double)0.0; // skewY
1212 Bytes += (int )SRID; // srid
1213 Bytes += (short )pGrid->Get_NX(); // width
1214 Bytes += (short )pGrid->Get_NY(); // height
1215
1216 //-----------------------------------------------------
1217 // Band
1218
1219 BYTE Flags;
1220
1221 switch( pGrid->Get_Type() )
1222 {
1223 case SG_DATATYPE_Bit : Flags = 0; break; // 0: 1-bit boolean
1224 // case SG_DATATYPE_ : Flags = 1; break; // 1: 2-bit unsigned integer
1225 // case SG_DATATYPE_ : Flags = 2; break; // 2: 4-bit unsigned integer
1226 case SG_DATATYPE_Char : Flags = 3; break; // 3: 8-bit signed integer
1227 case SG_DATATYPE_Byte : Flags = 4; break; // 4: 8-bit unsigned integer
1228 case SG_DATATYPE_Short : Flags = 5; break; // 5: 16-bit signed integer
1229 case SG_DATATYPE_Word : Flags = 6; break; // 6: 16-bit unsigned integer
1230 case SG_DATATYPE_Int : Flags = 7; break; // 7: 32-bit signed integer
1231 case SG_DATATYPE_DWord : Flags = 8; break; // 8: 32-bit unsigned integer
1232 default : Flags = 10; break; // 10: 32-bit float
1233 case SG_DATATYPE_Double: Flags = 11; break; // 11: 64-bit float
1234 }
1235
1236 // Flags |= 0x80; // isOffline: no, never here!
1237 Flags |= 0x40; // hasNodataValue
1238 // Flags |= 0x20; // isNoDataValue: no, never here!
1239 // Flags |= 0x10; // reserved (unused)
1240
1241 Bytes += Flags;
1242
1243 switch( pGrid->Get_Type() )
1244 {
1245 case SG_DATATYPE_Bit : Bytes += (BYTE )0 ; break; // 0: 1-bit boolean
1246 case SG_DATATYPE_Char : Bytes += (char )pGrid->Get_NoData_Value(); break; // 3: 8-bit signed integer
1247 case SG_DATATYPE_Byte : Bytes += (BYTE )pGrid->Get_NoData_Value(); break; // 4: 8-bit unsigned integer
1248 case SG_DATATYPE_Short : Bytes += (short )pGrid->Get_NoData_Value(); break; // 5: 16-bit signed integer
1249 case SG_DATATYPE_Word : Bytes += (WORD )pGrid->Get_NoData_Value(); break; // 6: 16-bit unsigned integer
1250 case SG_DATATYPE_Int : Bytes += (int )pGrid->Get_NoData_Value(); break; // 7: 32-bit signed integer
1251 case SG_DATATYPE_DWord : Bytes += (DWORD )pGrid->Get_NoData_Value(); break; // 8: 32-bit unsigned integer
1252 default : Bytes += (float )pGrid->Get_NoData_Value(); break; // 9: 32-bit float
1253 case SG_DATATYPE_Double: Bytes += (double)pGrid->Get_NoData_Value(); break; // 10: 64-bit float
1254 }
1255
1256 for(int y=0; y<pGrid->Get_NY() && SG_UI_Process_Set_Progress(y, pGrid->Get_NY()); y++)
1257 {
1258 for(int x=0; x<pGrid->Get_NX(); x++)
1259 {
1260 double Value = pGrid->is_NoData(x, y) ? pGrid->Get_NoData_Value() : pGrid->asDouble(x, y);
1261
1262 switch( pGrid->Get_Type() )
1263 {
1264 case SG_DATATYPE_Bit : Bytes += (BYTE )Value; break; // 0: 1-bit boolean
1265 case SG_DATATYPE_Char : Bytes += (char )Value; break; // 3: 8-bit signed integer
1266 case SG_DATATYPE_Byte : Bytes += (BYTE )Value; break; // 4: 8-bit unsigned integer
1267 case SG_DATATYPE_Short : Bytes += (short )Value; break; // 5: 16-bit signed integer
1268 case SG_DATATYPE_Word : Bytes += (WORD )Value; break; // 6: 16-bit unsigned integer
1269 case SG_DATATYPE_Int : Bytes += (int )Value; break; // 7: 32-bit signed integer
1270 case SG_DATATYPE_DWord : Bytes += (DWORD )Value; break; // 8: 32-bit unsigned integer
1271 default : Bytes += (float )Value; break; // 9: 32-bit float
1272 case SG_DATATYPE_Double: Bytes += (double)Value; break; // 10: 64-bit float
1273 }
1274 }
1275 }
1276
1277 return( true );
1278 }
1279
1280
1281 ///////////////////////////////////////////////////////////
1282 // //
1283 // //
1284 // //
1285 ///////////////////////////////////////////////////////////
1286
1287 //---------------------------------------------------------
1288