1 #include <math.h>
2 #include <float.h>
3 #include "wkbtest.h"
4
5 #define WKBZOFFSET 0x80000000
6 #define WKBMOFFSET 0x40000000
7
8
9 // DO NOT USE THESE decoding function (except for debugging purposes)
10 // The code is NOT maintained and is thrown together
11
12
13 // unsupported debugging function.
14 // given a wkb input thats a geometrycollection, returns its size and prints out
15 // its contents
16 //
17 // Its really messy - dont even think about using this for anything
18 //
19 // you shouldnt call this function; just call decode_wkb() and it will
20 // call this function
21
22 //#define DEBUG 1
23
24
25
26
27 void decode_wkb_collection(char *wkb,int *size);
28
swap_char(char * a,char * b)29 void swap_char(char *a,char *b)
30 {
31 char c;
32
33 c = *a;
34 *a=*b;
35 *b=c;
36 }
37
38
flip_endian_double(char * d)39 void flip_endian_double(char *d)
40 {
41 swap_char(d+7, d);
42 swap_char(d+6, d+1);
43 swap_char(d+5, d+2);
44 swap_char(d+4, d+3);
45 }
46
flip_endian_int32(char * i)47 void flip_endian_int32(char *i)
48 {
49 swap_char (i+3,i);
50 swap_char (i+2,i+1);
51 }
52
53
decode_wkb_collection(char * wkb,int * size)54 void decode_wkb_collection(char *wkb,int *size)
55 {
56 int offset =0;
57 bool flipbytes;
58 int total_size=0,sub_size;
59 int numb_sub,t;
60 bool first_one = TRUE;
61
62 if (wkb[0] ==0 ) //big endian
63 {
64 if (BYTE_ORDER == LITTLE_ENDIAN)
65 flipbytes= 1;
66 else
67 flipbytes= 0;
68 }
69 else //little
70 {
71 if (BYTE_ORDER == LITTLE_ENDIAN)
72 flipbytes= 0;
73 else
74 flipbytes= 1;
75 }
76
77 memcpy(&numb_sub, wkb+5,4);
78 if (flipbytes)
79 flip_endian_int32( (char *) & numb_sub) ;
80
81 printf("GEOMETRYCOLLECTION(\n");
82 offset = 9;
83 for (t=0; t<numb_sub; t++)
84 {
85 if (first_one)
86 {
87 first_one = FALSE;
88 }
89 else
90 {
91 printf(",");
92 }
93
94 printf(" ");
95 decode_wkb( wkb + offset, &sub_size);
96 total_size += sub_size;
97 offset += sub_size;
98 }
99 *size = total_size +9 ;
100 printf(")\n");
101 return;
102 }
103
104 //dump wkb to screen (for debugging)
105 // assume endian is constant though out structure
decode_wkb(char * wkb,int * size)106 void decode_wkb(char *wkb, int *size)
107 {
108
109 bool flipbytes;
110 uint32 type;
111 uint32 n1,n2,n3,t,u,v;
112 bool is3d;
113 bool first_one,first_one2,first_one3;
114
115 int offset,offset1;
116 double x,y,z;
117 int total_points;
118
119
120
121 #if DEBUG
122 printf("decoding wkb\n");
123 #endif
124
125
126 if (wkb[0] ==0 ) //big endian
127 {
128 if (BYTE_ORDER == LITTLE_ENDIAN)
129 flipbytes= 1;
130 else
131 flipbytes= 0;
132 }
133 else //little
134 {
135 if (BYTE_ORDER == LITTLE_ENDIAN)
136 flipbytes= 0;
137 else
138 flipbytes= 1;
139 }
140
141 #if DEBUG
142 printf(" + flipbytes = %i\n", flipbytes);
143 #endif
144
145 #if DEBUG
146 printf("info about wkb:\n");
147 #endif
148 memcpy(&type, wkb+1,4);
149 if (flipbytes)
150 flip_endian_int32( (char *) & type) ;
151
152 is3d = 0;
153
154 if (type&WKBZOFFSET)
155 {
156 is3d = 1;
157 type = type&(~WKBZOFFSET);
158 }
159 #if DEBUG
160 printf(" Type = %i (is3d = %i)\n", type, is3d);
161 #endif
162 if (type == 1) //POINT()
163 {
164 printf("POINT(");
165 if (is3d)
166 {
167 memcpy(&x, &wkb[5], 8);
168 memcpy(&y, &wkb[5+8], 8);
169 memcpy(&z, &wkb[5+16], 8);
170 if (flipbytes)
171 {
172 flip_endian_double( (char *) & x) ;
173 flip_endian_double( (char *) & y) ;
174 flip_endian_double( (char *) & z) ;
175 }
176 printf("%g %g %g)",x,y,z );
177 }
178 else
179 {
180 memcpy(&x, &wkb[5], 8);
181 memcpy(&y, &wkb[5+8], 8);
182 if (flipbytes)
183 {
184 flip_endian_double( (char *) & x) ;
185 flip_endian_double( (char *) & y) ;
186 }
187 printf("%g %g)", x,y);
188 }
189 printf("\n");
190 if (is3d)
191 *size = 29;
192 else
193 *size = 21;
194 return;
195
196 }
197 if (type == 2)
198 {
199 printf("LINESTRING(");
200 memcpy(&n1, &wkb[5],4);
201 if (flipbytes)
202 flip_endian_int32( (char *) & n1) ;
203 // printf(" --- has %i sub points\n",n1);
204 first_one = TRUE;
205 for (t=0; t<n1; t++)
206 {
207 if (first_one)
208 {
209 first_one = FALSE;
210 }
211 else
212 {
213 printf(",");
214 }
215 if (is3d)
216 {
217 memcpy(&x, &wkb[9+t*24],8);
218 memcpy(&y, &wkb[9+t*24+8],8);
219 memcpy(&z, &wkb[9+t*24+16],8);
220 if (flipbytes)
221 {
222 flip_endian_double( (char *) & x) ;
223 flip_endian_double( (char *) & y) ;
224 flip_endian_double( (char *) & z) ;
225 }
226 printf("%g %g %g",x,y,z);
227 }
228 else
229 {
230 memcpy(&x, &wkb[9+t*16],8);
231 memcpy(&y, &wkb[9+t*16+8],8);
232 if (flipbytes)
233 {
234 flip_endian_double( (char *) & x) ;
235 flip_endian_double( (char *) & y) ;
236 }
237 printf("%g %g",x,y);
238 }
239 }
240
241
242 printf(")\n");
243 if (is3d)
244 *size = 9 + n1*24;
245 else
246 *size = 9 + n1*16;
247 return;
248 }
249 if (type == 3)
250 {
251 *size = 9;
252 printf("POLYGON(");
253 memcpy(&n1, &wkb[5],4);
254 if (flipbytes)
255 flip_endian_int32( (char *) & n1) ;
256 //printf(" --- has %i rings\n",n1);
257 *size += 4*n1;
258 offset= 9;
259 first_one = TRUE;
260 for (u=0; u<n1; u++)
261 {
262 memcpy(&n2, &wkb[offset],4);
263 if (flipbytes)
264 flip_endian_int32( (char *) & n2) ;
265 // printf(" ring %i: has %i points\n",u,n2);
266
267
268 if (first_one)
269 {
270 first_one = FALSE;
271 }
272 else
273 {
274 printf(",");
275 }
276 printf("(");
277
278 first_one2 = TRUE;
279 for (v=0; v< n2; v++)
280 {
281 if (first_one2)
282 {
283 first_one2 = FALSE;
284 }
285 else
286 {
287 printf(",");
288 }
289 if (is3d)
290 {
291 memcpy(&x, &wkb[offset + 4+ v*24],8);
292 memcpy(&y, &wkb[offset + 4+ v*24 + 8],8);
293 memcpy(&z, &wkb[offset + 4+ v*24 + 16],8);
294 if (flipbytes)
295 {
296 flip_endian_double( (char *) & x) ;
297 flip_endian_double( (char *) & y) ;
298 flip_endian_double( (char *) & z) ;
299 }
300 printf("%g %g %g",x,y,z);
301
302 }
303 else
304 {
305 memcpy(&x, &wkb[offset +4 +v*16],8);
306 memcpy(&y, &wkb[offset +4 +v*16 + 8],8);
307 if (flipbytes)
308 {
309 flip_endian_double( (char *) & x) ;
310 flip_endian_double( (char *) & y) ;
311 }
312 printf("%g %g",x,y);
313
314 }
315 }
316 if (is3d)
317 {
318 offset +=4 +24*n2;
319 *size += n2*24;
320 }
321 else
322 {
323 offset += 4+ 16*n2;
324 *size += n2*16;
325 }
326 printf(")");
327 }
328
329 printf(")\n");
330
331 return;
332
333 }
334 if (type == 4)
335 {
336 printf("MULTIPOINT(");
337 memcpy(&n1,&wkb[5],4);
338 if (flipbytes)
339 flip_endian_int32( (char *) & n1) ;
340 // printf(" -- has %i points\n",n1);
341 if (is3d)
342 *size = 9 + n1*29;
343 else
344 *size = 9 + n1*21;
345 first_one = TRUE;
346 for (t=0; t<n1; t++)
347 {
348 if (first_one)
349 {
350 first_one= FALSE;
351 }
352 else
353 {
354 printf(",");
355 }
356 if (is3d)
357 {
358 memcpy(&x, &wkb[9+t*29+5],8);
359 memcpy(&y, &wkb[9+t*29+8+5],8);
360 memcpy(&z, &wkb[9+t*29+16+5],8);
361 if (flipbytes)
362 {
363 flip_endian_double( (char *) & x) ;
364 flip_endian_double( (char *) & y) ;
365 flip_endian_double( (char *) & z) ;
366 }
367 printf("%g %g %g",x,y,z);
368 }
369 else
370 {
371 memcpy(&x, &wkb[9+t*21+5],8);
372 memcpy(&y, &wkb[9+t*21+8+5],8);
373 if (flipbytes)
374 {
375 flip_endian_double( (char *) & x) ;
376 flip_endian_double( (char *) & y) ;
377 }
378 printf("%g %g",x,y);
379 }
380 }
381 printf (")\n");
382 return;
383 }
384 if (type == 5)
385 {
386 *size = 9;
387 printf("MULTILINESTRING(");
388 memcpy(&n2,&wkb[5],4);
389 if (flipbytes)
390 flip_endian_int32( (char *) & n2) ;
391 // printf(" -- has %i sub-lines\n",n2);
392 *size += 9 *n2;
393 offset =9;
394 first_one2 = TRUE;
395 for (u=0; u<n2; u++)
396 {
397 if (first_one2)
398 {
399 first_one2= FALSE;
400 }
401 else
402 {
403 printf(",");
404 }
405 printf("(");
406 memcpy(&n1, &wkb[5 +offset],4);
407 if (flipbytes)
408 flip_endian_int32( (char *) & n1) ;
409 // printf(" --- has %i sub points\n",n1);
410 first_one = TRUE;
411 for (t=0; t<n1; t++)
412 {
413 if (first_one)
414 {
415 first_one= FALSE;
416 }
417 else
418 {
419 printf(",");
420 }
421
422 if (is3d)
423 {
424 memcpy(&x, &wkb[offset+9+t*24],8);
425 memcpy(&y, &wkb[offset+9+t*24+8],8);
426 memcpy(&z, &wkb[offset+9+t*24+16],8);
427 if (flipbytes)
428 {
429 flip_endian_double( (char *) & x) ;
430 flip_endian_double( (char *) & y) ;
431 flip_endian_double( (char *) & z) ;
432 }
433 printf("%g %g %g",x,y,z);
434 }
435 else
436 {
437 memcpy(&x, &wkb[offset+9+t*16],8);
438 memcpy(&y, &wkb[offset+9+t*16+8],8);
439 if (flipbytes)
440 {
441 flip_endian_double( (char *) & x) ;
442 flip_endian_double( (char *) & y) ;
443 }
444 printf("%g %g",x,y);
445 }
446 }
447 printf(")");
448 if (is3d)
449 {
450 *size += (24*n1);
451 offset += 9 + (24*n1);
452 }
453 else
454 {
455 *size += (16*n1);
456 offset += 9 + (16*n1);
457 }
458 }
459 printf(")\n");
460 return;
461
462 }
463 if (type == 6)
464 {
465 *size = 9;
466 printf("MULTIPOLYGON(");
467 memcpy(&n3,&wkb[5],4);
468 if (flipbytes)
469 flip_endian_int32( (char *) & n3) ;
470 //printf(" -- has %i sub-poly\n",n3);
471 *size += 9*n3;
472 offset1 =9;//where polygon starts
473 first_one3= TRUE;
474 for (t=0; t<n3; t++) //for each polygon
475 {
476 if (first_one3)
477 {
478 first_one3= FALSE;
479 }
480 else
481 {
482 printf(",");
483 }
484 printf("(");
485 //printf("polygon #%i\n",t);
486 total_points = 0;
487 memcpy(&n1,&wkb[offset1+5],4); //# rings
488 *size += 4*n1;
489 if (flipbytes)
490 flip_endian_int32( (char *) & n1) ;
491 //printf("This polygon has %i rings\n",n1);
492 offset = offset1+9; //where linear rings are
493 first_one = TRUE;
494 for (u=0; u<n1; u++) //for each ring
495 {
496 if (first_one)
497 {
498 first_one= FALSE;
499 }
500 else
501 {
502 printf(",");
503 }
504 printf("(");
505 memcpy(&n2, &wkb[offset],4);
506 if (flipbytes)
507 flip_endian_int32( (char *) & n2) ; //pts in linear ring
508 // printf(" ring %i: has %i points\n",u,n2);
509 total_points += n2;
510 first_one2 = TRUE;
511 for (v=0; v< n2; v++) //for each point
512 {
513 if (first_one2)
514 {
515 first_one2= FALSE;
516 }
517 else
518 {
519 printf(",");
520 }
521 if (is3d)
522 {
523 memcpy(&x, &wkb[offset + 4+ v*24],8);
524 memcpy(&y, &wkb[offset + 4+ v*24 + 8],8);
525 memcpy(&z, &wkb[offset + 4+ v*24 + 16],8);
526 if (flipbytes)
527 {
528 flip_endian_double( (char *) & x) ;
529 flip_endian_double( (char *) & y) ;
530 flip_endian_double( (char *) & z) ;
531 }
532 printf("%g %g %g",x,y,z);
533 }
534 else
535 {
536 memcpy(&x, &wkb[offset +4 +v*16],8);
537 memcpy(&y, &wkb[offset +4 +v*16 + 8],8);
538 if (flipbytes)
539 {
540 flip_endian_double( (char *) & x) ;
541 flip_endian_double( (char *) & y) ;
542 }
543 printf("%g %g",x,y);
544 }
545 }
546 if (is3d)
547 {
548 *size += 24*n2;
549 offset += 4+ 24*n2;
550 }
551 else
552 {
553 *size += 16*n2;
554 offset += 4+ 16*n2;
555 }
556 printf(")");
557 }
558 printf(")");
559 if (is3d)
560 offset1 +=9 +24*total_points +4*n1;
561 else
562 offset1 += 9+ 16*total_points +4*n1;
563 }
564 printf(")\n");
565 return;
566 }
567 if (type == 7)
568 {
569 return decode_wkb_collection(wkb, size);
570 }
571
572
573
574
575 }
576
577
578