~ubuntu-branches/ubuntu/trusty/postgis/trusty-security

« back to all changes in this revision

Viewing changes to lwgeom/lwgeom.c

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2009-12-11 13:10:34 UTC
  • mfrom: (1.1.9 upstream) (5.2.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20091211131034-wmsz69wxvt95pe5r
Tags: 1.4.0-2
* Upload to unstable.
* Better parameterized debian/rules against postgis $(VERSION).
* Added dblatex and libcunit1-dev among build-deps.
* Added postgis_comments.sql to contrib/ SQL templates.
* Dropping 8.3 support, no more supported for squeeze.
  (closes: #559587)
* Do not stop on error in postrm if the target dir does not exist.
  (closes: #560409)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**********************************************************************
2
 
 * $Id: lwgeom.c 3272 2008-11-07 13:18:11Z mcayland $
3
 
 *
4
 
 * PostGIS - Spatial Types for PostgreSQL
5
 
 * http://postgis.refractions.net
6
 
 * Copyright 2001-2006 Refractions Research Inc.
7
 
 *
8
 
 * This is free software; you can redistribute and/or modify it under
9
 
 * the terms of the GNU General Public Licence. See the COPYING file.
10
 
 * 
11
 
 **********************************************************************/
12
 
 
13
 
#include <stdio.h>
14
 
#include <stdlib.h>
15
 
#include <stdarg.h>
16
 
 
17
 
/*#include "lwgeom_pg.h"*/
18
 
#include "liblwgeom.h"
19
 
#include "wktparse.h"
20
 
 
21
 
/*#define PGIS_DEBUG_CALLS 1*/
22
 
/*#define PGIS_DEBUG 1*/
23
 
 
24
 
LWGEOM *
25
 
lwgeom_deserialize(uchar *srl)
26
 
{
27
 
        int type = lwgeom_getType(srl[0]);
28
 
 
29
 
#ifdef PGIS_DEBUG_CALLS
30
 
        lwnotice("lwgeom_deserialize got %d - %s", type, lwgeom_typename(type));
31
 
#endif
32
 
 
33
 
        switch (type)
34
 
        {
35
 
                case POINTTYPE:
36
 
                        return (LWGEOM *)lwpoint_deserialize(srl);
37
 
                case LINETYPE:
38
 
                        return (LWGEOM *)lwline_deserialize(srl);
39
 
                case CURVETYPE:
40
 
                        return (LWGEOM *)lwcurve_deserialize(srl);
41
 
                case POLYGONTYPE:
42
 
                        return (LWGEOM *)lwpoly_deserialize(srl);
43
 
                case MULTIPOINTTYPE:
44
 
                        return (LWGEOM *)lwmpoint_deserialize(srl);
45
 
                case MULTILINETYPE:
46
 
                        return (LWGEOM *)lwmline_deserialize(srl);
47
 
                case MULTIPOLYGONTYPE:
48
 
                        return (LWGEOM *)lwmpoly_deserialize(srl);
49
 
                case COLLECTIONTYPE:
50
 
                        return (LWGEOM *)lwcollection_deserialize(srl);
51
 
                case COMPOUNDTYPE:
52
 
                        return (LWGEOM *)lwcompound_deserialize(srl);
53
 
                case CURVEPOLYTYPE:
54
 
                        return (LWGEOM *)lwcurvepoly_deserialize(srl);
55
 
                case MULTICURVETYPE:
56
 
                        return (LWGEOM *)lwmcurve_deserialize(srl);
57
 
                case MULTISURFACETYPE:
58
 
                        return (LWGEOM *)lwmsurface_deserialize(srl);
59
 
                default:
60
 
#ifdef PGIS_DEBUG
61
 
                        lwerror("lwgeom_deserialize: Unknown geometry type: %d", type);
62
 
#else
63
 
                        lwerror("Unknown geometry type: %d", type);
64
 
#endif
65
 
                        return NULL;
66
 
        }
67
 
 
68
 
}
69
 
 
70
 
size_t
71
 
lwgeom_serialize_size(LWGEOM *lwgeom)
72
 
{
73
 
        int type = TYPE_GETTYPE(lwgeom->type);
74
 
 
75
 
#ifdef PGIS_DEBUG_CALLS
76
 
        lwnotice("lwgeom_serialize_size(%s) called", lwgeom_typename(type));
77
 
#endif
78
 
 
79
 
        switch (type)
80
 
        {
81
 
                case POINTTYPE:
82
 
                        return lwpoint_serialize_size((LWPOINT *)lwgeom);
83
 
                case LINETYPE:
84
 
                        return lwline_serialize_size((LWLINE *)lwgeom);
85
 
                case POLYGONTYPE:
86
 
                        return lwpoly_serialize_size((LWPOLY *)lwgeom);
87
 
                case CURVETYPE:
88
 
                        return lwcurve_serialize_size((LWCURVE *)lwgeom);
89
 
                case CURVEPOLYTYPE:
90
 
                case COMPOUNDTYPE:
91
 
                case MULTIPOINTTYPE:
92
 
                case MULTILINETYPE:
93
 
                case MULTICURVETYPE:
94
 
                case MULTIPOLYGONTYPE:
95
 
                case MULTISURFACETYPE:
96
 
                case COLLECTIONTYPE:
97
 
                        return lwcollection_serialize_size((LWCOLLECTION *)lwgeom);
98
 
                default:
99
 
#ifdef PGIS_DEBUG
100
 
                        lwerror("lwgeom_serialize_size: Unknown geometry type: %d", type);
101
 
#else
102
 
                        lwerror("Unknown geometry type: %d", type);
103
 
#endif
104
 
                        return 0;
105
 
        }
106
 
}
107
 
 
108
 
void
109
 
lwgeom_serialize_buf(LWGEOM *lwgeom, uchar *buf, size_t *retsize)
110
 
{
111
 
        int type = TYPE_GETTYPE(lwgeom->type);
112
 
 
113
 
#ifdef PGIS_DEBUG_CALLS 
114
 
        lwnotice("lwgeom_serialize_buf called with a %s",
115
 
                        lwgeom_typename(type));
116
 
#endif
117
 
        switch (type)
118
 
        {
119
 
                case POINTTYPE:
120
 
                        lwpoint_serialize_buf((LWPOINT *)lwgeom, buf, retsize);
121
 
                        break;
122
 
                case LINETYPE:
123
 
                        lwline_serialize_buf((LWLINE *)lwgeom, buf, retsize);
124
 
                        break;
125
 
                case POLYGONTYPE:
126
 
                        lwpoly_serialize_buf((LWPOLY *)lwgeom, buf, retsize);
127
 
                        break;
128
 
                case CURVETYPE:
129
 
                        lwcurve_serialize_buf((LWCURVE *)lwgeom, buf, retsize);
130
 
                        break;
131
 
                case CURVEPOLYTYPE:
132
 
                case COMPOUNDTYPE:
133
 
                case MULTIPOINTTYPE:
134
 
                case MULTILINETYPE:
135
 
                case MULTICURVETYPE:
136
 
                case MULTIPOLYGONTYPE:
137
 
                case MULTISURFACETYPE:
138
 
                case COLLECTIONTYPE:
139
 
                        lwcollection_serialize_buf((LWCOLLECTION *)lwgeom, buf,
140
 
                                retsize);
141
 
                        break;
142
 
                default:
143
 
#ifdef PGIS_DEBUG
144
 
                        lwerror("lwgeom_serialize_buf: Unknown geometry type: %d", type);
145
 
#else
146
 
                        lwerror("Unknown geometry type: %d", type);
147
 
#endif
148
 
                        return;
149
 
        }
150
 
        return;
151
 
}
152
 
 
153
 
uchar *
154
 
lwgeom_serialize(LWGEOM *lwgeom)
155
 
{
156
 
        size_t size = lwgeom_serialize_size(lwgeom);
157
 
        size_t retsize;
158
 
        uchar *serialized = lwalloc(size);
159
 
 
160
 
        lwgeom_serialize_buf(lwgeom, serialized, &retsize);
161
 
 
162
 
#ifdef PGIS_DEBUG
163
 
        if ( retsize != size )
164
 
        {
165
 
                lwerror("lwgeom_serialize: computed size %d, returned size %d",
166
 
                        size, retsize);
167
 
        }
168
 
#endif
169
 
 
170
 
        return serialized;
171
 
}
172
 
 
173
 
/* Force Right-hand-rule on LWGEOM polygons */
174
 
void
175
 
lwgeom_forceRHR(LWGEOM *lwgeom)
176
 
{
177
 
        LWCOLLECTION *coll;
178
 
        int i;
179
 
 
180
 
        switch (TYPE_GETTYPE(lwgeom->type))
181
 
        {
182
 
                case POLYGONTYPE:
183
 
                        lwpoly_forceRHR((LWPOLY *)lwgeom);
184
 
                        return;
185
 
 
186
 
                case MULTIPOLYGONTYPE:
187
 
                case COLLECTIONTYPE:
188
 
                        coll = (LWCOLLECTION *)lwgeom;
189
 
                        for (i=0; i<coll->ngeoms; i++)
190
 
                                lwgeom_forceRHR(coll->geoms[i]);
191
 
                        return;
192
 
        }
193
 
}
194
 
 
195
 
/* Reverse vertex order of LWGEOM */
196
 
void
197
 
lwgeom_reverse(LWGEOM *lwgeom)
198
 
{
199
 
        int i;
200
 
        LWCOLLECTION *col;
201
 
 
202
 
        switch (TYPE_GETTYPE(lwgeom->type))
203
 
        {
204
 
                case LINETYPE:
205
 
                        lwline_reverse((LWLINE *)lwgeom);
206
 
                        return;
207
 
                case POLYGONTYPE:
208
 
                        lwpoly_reverse((LWPOLY *)lwgeom);
209
 
                        return;
210
 
                case MULTILINETYPE:
211
 
                case MULTIPOLYGONTYPE:
212
 
                case COLLECTIONTYPE:
213
 
                        col = (LWCOLLECTION *)lwgeom;
214
 
                        for (i=0; i<col->ngeoms; i++)
215
 
                                lwgeom_reverse(col->geoms[i]);
216
 
                        return;
217
 
        }
218
 
}
219
 
 
220
 
int
221
 
lwgeom_compute_box2d_p(LWGEOM *lwgeom, BOX2DFLOAT4 *buf)
222
 
{
223
 
#ifdef PGIS_DEBUG_CALLS
224
 
        lwnotice("lwgeom_compute_box2d_p called of %p of type %d.", lwgeom, TYPE_GETTYPE(lwgeom->type));
225
 
#endif
226
 
        switch(TYPE_GETTYPE(lwgeom->type))
227
 
        {
228
 
                case POINTTYPE:
229
 
                        return lwpoint_compute_box2d_p((LWPOINT *)lwgeom, buf);
230
 
                case LINETYPE:
231
 
                        return lwline_compute_box2d_p((LWLINE *)lwgeom, buf);
232
 
                case CURVETYPE:
233
 
                        return lwcurve_compute_box2d_p((LWCURVE *)lwgeom, buf);
234
 
                case POLYGONTYPE:
235
 
                        return lwpoly_compute_box2d_p((LWPOLY *)lwgeom, buf);
236
 
                case COMPOUNDTYPE:
237
 
                case CURVEPOLYTYPE:
238
 
                case MULTIPOINTTYPE:
239
 
                case MULTILINETYPE:
240
 
                case MULTICURVETYPE:
241
 
                case MULTIPOLYGONTYPE:
242
 
                case MULTISURFACETYPE:
243
 
                case COLLECTIONTYPE:
244
 
                        return lwcollection_compute_box2d_p((LWCOLLECTION *)lwgeom, buf);
245
 
        }
246
 
        return 0;
247
 
}
248
 
 
249
 
/*
250
 
 * dont forget to lwfree() result
251
 
 */
252
 
BOX2DFLOAT4 *
253
 
lwgeom_compute_box2d(LWGEOM *lwgeom)
254
 
{
255
 
        BOX2DFLOAT4 *result = lwalloc(sizeof(BOX2DFLOAT4));
256
 
        if ( lwgeom_compute_box2d_p(lwgeom, result) ) return result;
257
 
        else  {
258
 
                lwfree(result);
259
 
                return NULL;
260
 
        }
261
 
}
262
 
 
263
 
LWPOINT *
264
 
lwgeom_as_lwpoint(LWGEOM *lwgeom)
265
 
{
266
 
        if ( TYPE_GETTYPE(lwgeom->type) == POINTTYPE )
267
 
                return (LWPOINT *)lwgeom;
268
 
        else return NULL;
269
 
}
270
 
 
271
 
LWLINE *
272
 
lwgeom_as_lwline(LWGEOM *lwgeom)
273
 
{
274
 
        if ( TYPE_GETTYPE(lwgeom->type) == LINETYPE )
275
 
                return (LWLINE *)lwgeom;
276
 
        else return NULL;
277
 
}
278
 
 
279
 
LWCURVE *
280
 
lwgeom_as_lwcurve(LWGEOM *lwgeom)
281
 
{
282
 
        if( TYPE_GETTYPE(lwgeom->type) == CURVETYPE )
283
 
                return (LWCURVE *)lwgeom;
284
 
        else return NULL;
285
 
}
286
 
 
287
 
LWPOLY *
288
 
lwgeom_as_lwpoly(LWGEOM *lwgeom)
289
 
{
290
 
        if ( TYPE_GETTYPE(lwgeom->type) == POLYGONTYPE )
291
 
                return (LWPOLY *)lwgeom;
292
 
        else return NULL;
293
 
}
294
 
 
295
 
LWCOLLECTION *
296
 
lwgeom_as_lwcollection(LWGEOM *lwgeom)
297
 
{
298
 
        if ( TYPE_GETTYPE(lwgeom->type) >= MULTIPOINTTYPE 
299
 
            && TYPE_GETTYPE(lwgeom->type) <= COLLECTIONTYPE)
300
 
                return (LWCOLLECTION *)lwgeom;
301
 
        else return NULL;
302
 
}
303
 
 
304
 
LWMPOINT *
305
 
lwgeom_as_lwmpoint(LWGEOM *lwgeom)
306
 
{
307
 
        if ( TYPE_GETTYPE(lwgeom->type) == MULTIPOINTTYPE )
308
 
                return (LWMPOINT *)lwgeom;
309
 
        else return NULL;
310
 
}
311
 
 
312
 
LWMLINE *
313
 
lwgeom_as_lwmline(LWGEOM *lwgeom)
314
 
{
315
 
        if ( TYPE_GETTYPE(lwgeom->type) == MULTILINETYPE )
316
 
                return (LWMLINE *)lwgeom;
317
 
        else return NULL;
318
 
}
319
 
 
320
 
LWMPOLY *
321
 
lwgeom_as_lwmpoly(LWGEOM *lwgeom)
322
 
{
323
 
        if ( TYPE_GETTYPE(lwgeom->type) == MULTIPOLYGONTYPE )
324
 
                return (LWMPOLY *)lwgeom;
325
 
        else return NULL;
326
 
}
327
 
 
328
 
LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj) { return (LWGEOM *)obj; }
329
 
LWGEOM *lwmline_as_lwgeom(LWMLINE *obj) { return (LWGEOM *)obj; }
330
 
LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj) { return (LWGEOM *)obj; }
331
 
LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj) { return (LWGEOM *)obj; }
332
 
LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj) { return (LWGEOM *)obj; }
333
 
LWGEOM *lwline_as_lwgeom(LWLINE *obj) { return (LWGEOM *)obj; }
334
 
LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj) { return (LWGEOM *)obj; }
335
 
 
336
 
void
337
 
lwgeom_release(LWGEOM *lwgeom)
338
 
{
339
 
        uint32 i;
340
 
        LWCOLLECTION *col;
341
 
 
342
 
#ifdef INTEGRITY_CHECKS
343
 
        if ( ! lwgeom )
344
 
                lwerror("lwgeom_release: someone called on 0x0");
345
 
#endif
346
 
 
347
 
        /* Drop bounding box (always a copy) */
348
 
        if ( lwgeom->bbox ) {
349
 
#ifdef PGIS_DEBUG
350
 
                lwnotice("lwgeom_release: releasing bbox.");
351
 
#endif
352
 
                lwfree(lwgeom->bbox);
353
 
        }
354
 
 
355
 
        /* Collection */
356
 
        if ( (col=lwgeom_as_lwcollection(lwgeom)) )
357
 
        {
358
 
 
359
 
#ifdef PGIS_DEBUG
360
 
                lwnotice("lwgeom_release: Releasing collection.");
361
 
#endif
362
 
 
363
 
                for (i=0; i<col->ngeoms; i++)
364
 
                {
365
 
                        lwgeom_release(col->geoms[i]);
366
 
                }
367
 
                lwfree(lwgeom);
368
 
        }
369
 
 
370
 
        /* Single element */
371
 
        else lwfree(lwgeom);
372
 
 
373
 
}
374
 
 
375
 
/* Clone an LWGEOM object. POINTARRAY are not copied. */
376
 
LWGEOM *
377
 
lwgeom_clone(const LWGEOM *lwgeom)
378
 
{
379
 
#ifdef PGIS_DEBUG_CALLS
380
 
        lwnotice("lwgeom_clone called with %p, %d", lwgeom, TYPE_GETTYPE(lwgeom->type));
381
 
#endif
382
 
        switch(TYPE_GETTYPE(lwgeom->type))
383
 
        {
384
 
                case POINTTYPE:
385
 
                        return (LWGEOM *)lwpoint_clone((LWPOINT *)lwgeom);
386
 
                case LINETYPE:
387
 
                        return (LWGEOM *)lwline_clone((LWLINE *)lwgeom);
388
 
                case CURVETYPE:
389
 
                        return (LWGEOM *)lwcurve_clone((LWCURVE *)lwgeom);
390
 
                case POLYGONTYPE:
391
 
                        return (LWGEOM *)lwpoly_clone((LWPOLY *)lwgeom);
392
 
                case COMPOUNDTYPE:
393
 
                case CURVEPOLYTYPE:
394
 
                case MULTIPOINTTYPE:
395
 
                case MULTILINETYPE:
396
 
                case MULTICURVETYPE:
397
 
                case MULTIPOLYGONTYPE:
398
 
                case MULTISURFACETYPE:
399
 
                case COLLECTIONTYPE:
400
 
                        return (LWGEOM *)lwcollection_clone((LWCOLLECTION *)lwgeom);
401
 
                default:
402
 
                        return NULL;
403
 
        }
404
 
}
405
 
 
406
 
/*
407
 
 * Add 'what' to 'to' at position 'where'
408
 
 *
409
 
 * where=0 == prepend
410
 
 * where=-1 == append
411
 
 * Appended-to LWGEOM gets a new type based on new condition.
412
 
 * Mix of dimensions is not allowed (TODO: allow it?).
413
 
 */
414
 
LWGEOM *
415
 
lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what)
416
 
{
417
 
        if ( TYPE_NDIMS(what->type) != TYPE_NDIMS(to->type) )
418
 
        {
419
 
                lwerror("lwgeom_add: mixed dimensions not supported");
420
 
                return NULL;
421
 
        }
422
 
 
423
 
#ifdef PGIS_DEBUG_CALLS
424
 
        lwnotice("lwgeom_add(%s, %d, %s) called",
425
 
                lwgeom_typename(TYPE_GETTYPE(to->type)),
426
 
                where,
427
 
                lwgeom_typename(TYPE_GETTYPE(what->type)));
428
 
#endif
429
 
 
430
 
        switch(TYPE_GETTYPE(to->type))
431
 
        {
432
 
                case POINTTYPE:
433
 
                        return (LWGEOM *)lwpoint_add((const LWPOINT *)to, where, what);
434
 
                case LINETYPE:
435
 
                        return (LWGEOM *)lwline_add((const LWLINE *)to, where, what);
436
 
 
437
 
                case CURVETYPE:
438
 
                        return (LWGEOM *)lwcurve_add((const LWCURVE *)to, where, what);
439
 
 
440
 
                case POLYGONTYPE:
441
 
                        return (LWGEOM *)lwpoly_add((const LWPOLY *)to, where, what);
442
 
 
443
 
                case COMPOUNDTYPE:
444
 
                        return (LWGEOM *)lwcompound_add((const LWCOMPOUND *)to, where, what);
445
 
 
446
 
                case CURVEPOLYTYPE:
447
 
                        return (LWGEOM *)lwcurvepoly_add((const LWCURVEPOLY *)to, where, what);
448
 
 
449
 
                case MULTIPOINTTYPE:
450
 
                        return (LWGEOM *)lwmpoint_add((const LWMPOINT *)to,
451
 
                                where, what);
452
 
 
453
 
                case MULTILINETYPE:
454
 
                        return (LWGEOM *)lwmline_add((const LWMLINE *)to,
455
 
                                where, what);
456
 
 
457
 
                case MULTICURVETYPE:
458
 
                        return (LWGEOM *)lwmcurve_add((const LWMCURVE *)to,
459
 
                                where, what);
460
 
 
461
 
                case MULTIPOLYGONTYPE:
462
 
                        return (LWGEOM *)lwmpoly_add((const LWMPOLY *)to,
463
 
                                where, what);
464
 
 
465
 
                case MULTISURFACETYPE:
466
 
                        return (LWGEOM *)lwmsurface_add((const LWMSURFACE *)to,
467
 
                                where, what);
468
 
 
469
 
                case COLLECTIONTYPE:
470
 
                        return (LWGEOM *)lwcollection_add(
471
 
                                (const LWCOLLECTION *)to, where, what);
472
 
 
473
 
                default:
474
 
                        lwerror("lwgeom_add: unknown geometry type: %d",
475
 
                                TYPE_GETTYPE(to->type));
476
 
                        return NULL;
477
 
        }
478
 
}
479
 
 
480
 
/*
481
 
 * Return an alloced string
482
 
 */
483
 
char *
484
 
lwgeom_to_ewkt(LWGEOM *lwgeom)
485
 
{
486
 
        uchar *serialized = lwgeom_serialize(lwgeom);
487
 
        char *ret;
488
 
        if ( ! serialized ) {
489
 
                lwerror("Error serializing geom %p", lwgeom);
490
 
        }
491
 
        ret = unparse_WKT(serialized, lwalloc, lwfree);
492
 
        lwfree(serialized);
493
 
        return ret;
494
 
}
495
 
 
496
 
/*
497
 
 * Return an alloced string
498
 
 */
499
 
char *
500
 
lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder)
501
 
{
502
 
        uchar *serialized = lwgeom_serialize(lwgeom);
503
 
        char *hexwkb = unparse_WKB(serialized, lwalloc, lwfree, byteorder,NULL,1);
504
 
        lwfree(serialized);
505
 
        return hexwkb;
506
 
}
507
 
 
508
 
/*
509
 
 * Return an alloced string
510
 
 */
511
 
uchar *
512
 
lwgeom_to_ewkb(LWGEOM *lwgeom, char byteorder, size_t *outsize)
513
 
{
514
 
        uchar *serialized = lwgeom_serialize(lwgeom);
515
 
 
516
 
        /*
517
 
         * We cast return to "unsigned" char as we are
518
 
         * requesting a "binary" output, not HEX
519
 
         * (last argument set to 0)
520
 
         */
521
 
        uchar *hexwkb = (uchar *)unparse_WKB(serialized, lwalloc, lwfree,
522
 
                byteorder, outsize, 0);
523
 
        lwfree(serialized);
524
 
        return hexwkb;
525
 
}
526
 
 
527
 
/*
528
 
 * Make an LWGEOM object from a EWKB binary representation.
529
 
 * Currently highly unoptimized as it:
530
 
 *      - convert EWKB to HEXEWKB 
531
 
 *      - construct PG_LWGEOM
532
 
 *      - deserialize it
533
 
 */
534
 
LWGEOM *
535
 
lwgeom_from_ewkb(uchar *ewkb, size_t size)
536
 
{
537
 
        size_t hexewkblen = size*2;
538
 
        char *hexewkb;
539
 
        long int i;
540
 
        LWGEOM *ret;
541
 
    SERIALIZED_LWGEOM *serialized_lwgeom;
542
 
 
543
 
        /* "HEXify" the EWKB */
544
 
        hexewkb = lwalloc(hexewkblen+1);
545
 
        for (i=0; i<size; ++i) deparse_hex(ewkb[i], &hexewkb[i*2]);
546
 
        hexewkb[hexewkblen] = '\0';
547
 
 
548
 
        /* Rely on grammar parser to construct a LWGEOM */
549
 
    serialized_lwgeom = parse_lwgeom_wkt(hexewkb);
550
 
 
551
 
        /* Free intermediate HEXified representation */
552
 
        lwfree(hexewkb);
553
 
 
554
 
        /* Deserialize */
555
 
        ret = lwgeom_deserialize(serialized_lwgeom->lwgeom);
556
 
 
557
 
        return ret;
558
 
}
559
 
 
560
 
/*
561
 
 * geom1 same as geom2
562
 
 *  iff
563
 
 *      + have same type 
564
 
 *      + have same # objects
565
 
 *      + have same bvol
566
 
 *      + each object in geom1 has a corresponding object in geom2 (see above)
567
 
 */
568
 
char
569
 
lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
570
 
{
571
 
#if PGIS_DEBUG
572
 
                lwnotice("lwgeom_same(%s, %s) called",
573
 
                        lwgeom_typename(TYPE_GETTYPE(lwgeom1->type)),
574
 
                        lwgeom_typename(TYPE_GETTYPE(lwgeom2->type)));
575
 
#endif
576
 
 
577
 
        if ( TYPE_GETTYPE(lwgeom1->type) != TYPE_GETTYPE(lwgeom2->type) )
578
 
        {
579
 
#if PGIS_DEBUG
580
 
                lwnotice(" type differ");
581
 
#endif
582
 
                return 0;
583
 
        }
584
 
 
585
 
        if ( TYPE_GETZM(lwgeom1->type) != TYPE_GETZM(lwgeom2->type) )
586
 
        {
587
 
#if PGIS_DEBUG
588
 
                lwnotice(" ZM flags differ");
589
 
#endif
590
 
                return 0;
591
 
        }
592
 
 
593
 
        /* Check boxes if both already computed  */
594
 
        if ( lwgeom1->bbox && lwgeom2->bbox )
595
 
        {
596
 
                /*lwnotice("bbox1:%p, bbox2:%p", lwgeom1->bbox, lwgeom2->bbox);*/
597
 
                if ( ! box2d_same(lwgeom1->bbox, lwgeom2->bbox) )
598
 
                {
599
 
#if PGIS_DEBUG
600
 
                        lwnotice(" bounding boxes differ");
601
 
#endif
602
 
                        return 0;
603
 
                }
604
 
        }
605
 
 
606
 
        /* geoms have same type, invoke type-specific function */
607
 
        switch(TYPE_GETTYPE(lwgeom1->type))
608
 
        {
609
 
                case POINTTYPE:
610
 
                        return lwpoint_same((LWPOINT *)lwgeom1,
611
 
                                (LWPOINT *)lwgeom2);
612
 
                case LINETYPE:
613
 
                        return lwline_same((LWLINE *)lwgeom1,
614
 
                                (LWLINE *)lwgeom2);
615
 
                case POLYGONTYPE:
616
 
                        return lwpoly_same((LWPOLY *)lwgeom1,
617
 
                                (LWPOLY *)lwgeom2);
618
 
                case MULTIPOINTTYPE:
619
 
                case MULTILINETYPE:
620
 
                case MULTIPOLYGONTYPE:
621
 
                case COLLECTIONTYPE:
622
 
                        return lwcollection_same((LWCOLLECTION *)lwgeom1,
623
 
                                (LWCOLLECTION *)lwgeom2);
624
 
                default:
625
 
                        lwerror("lwgeom_same: unknown geometry type: %d",
626
 
                                TYPE_GETTYPE(lwgeom1->type));
627
 
                        return 0;
628
 
        }
629
 
 
630
 
}
631
 
 
632
 
void
633
 
lwgeom_changed(LWGEOM *lwgeom)
634
 
{
635
 
        if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
636
 
        lwgeom->bbox = NULL;
637
 
        TYPE_SETHASBBOX(lwgeom->type, 0);
638
 
}
639
 
 
640
 
void
641
 
lwgeom_dropBBOX(LWGEOM *lwgeom)
642
 
{
643
 
        if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
644
 
        lwgeom->bbox = NULL;
645
 
        TYPE_SETHASBBOX(lwgeom->type, 0);
646
 
}
647
 
 
648
 
/*
649
 
 * Ensure there's a box in the LWGEOM.
650
 
 * If the box is already there just return,
651
 
 * else compute it.
652
 
 */
653
 
void
654
 
lwgeom_addBBOX(LWGEOM *lwgeom)
655
 
{
656
 
        if ( lwgeom->bbox ) return;
657
 
        lwgeom->bbox = lwgeom_compute_box2d(lwgeom);
658
 
        TYPE_SETHASBBOX(lwgeom->type, 1);
659
 
}
660
 
 
661
 
void
662
 
lwgeom_dropSRID(LWGEOM *lwgeom)
663
 
{
664
 
        TYPE_SETHASSRID(lwgeom->type, 0);
665
 
        lwgeom->SRID = -1;
666
 
}
667
 
 
668
 
LWGEOM *
669
 
lwgeom_segmentize2d(LWGEOM *lwgeom, double dist)
670
 
{
671
 
        switch(TYPE_GETTYPE(lwgeom->type))
672
 
        {
673
 
                case LINETYPE:
674
 
                        return (LWGEOM *)lwline_segmentize2d((LWLINE *)lwgeom,
675
 
                                dist);
676
 
                case POLYGONTYPE:
677
 
                        return (LWGEOM *)lwpoly_segmentize2d((LWPOLY *)lwgeom,
678
 
                                dist);
679
 
                case MULTILINETYPE:
680
 
                case MULTIPOLYGONTYPE:
681
 
                case COLLECTIONTYPE:
682
 
                        return (LWGEOM *)lwcollection_segmentize2d(
683
 
                                (LWCOLLECTION *)lwgeom, dist);
684
 
 
685
 
                default:
686
 
                        return lwgeom_clone(lwgeom);
687
 
        }
688
 
}
689
 
 
690
 
void
691
 
lwgeom_longitude_shift(LWGEOM *lwgeom)
692
 
{
693
 
        int i;
694
 
        switch(TYPE_GETTYPE(lwgeom->type))
695
 
        {
696
 
                LWPOINT *point;
697
 
                LWLINE *line;
698
 
                LWPOLY *poly;
699
 
                LWCOLLECTION *coll;
700
 
 
701
 
                case POINTTYPE:
702
 
                        point = (LWPOINT *)lwgeom;
703
 
                        ptarray_longitude_shift(point->point);
704
 
                        return;
705
 
                case LINETYPE:
706
 
                        line = (LWLINE *)lwgeom;
707
 
                        ptarray_longitude_shift(line->points);
708
 
                        return;
709
 
                case POLYGONTYPE:
710
 
                        poly = (LWPOLY *)lwgeom;
711
 
                        for (i=0; i<poly->nrings; i++)
712
 
                                ptarray_longitude_shift(poly->rings[i]);
713
 
                        return;
714
 
                case MULTIPOINTTYPE:
715
 
                case MULTILINETYPE:
716
 
                case MULTIPOLYGONTYPE:
717
 
                case COLLECTIONTYPE:
718
 
                        coll = (LWCOLLECTION *)lwgeom;
719
 
                        for (i=0; i<coll->ngeoms; i++)
720
 
                                lwgeom_longitude_shift(coll->geoms[i]);
721
 
                        return;
722
 
                default:
723
 
                        lwerror("%s:%d: unsupported geom type: %s",
724
 
                                __FILE__, __LINE__,
725
 
                                lwgeom_typename(TYPE_GETTYPE(lwgeom->type)));
726
 
        }
727
 
}