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