source: trunk/liblwgeom/liblwgeom.h @ 5821

Last change on this file since 5821 was 5821, checked in by colivier, 6 years ago

Add Triangle and TIN new geometry type. Add Cunit tests on parse stage, related to #561. Add ST_AsGML support TIN and Triangle for GML 3. Slightly cast change in PolyhedralSurface? LWGEOM struct Remove PolyhedralSurface? support from forceRHR function as orientation is meaningfull in PS. Move is_closed functions from PostGIS to LWGEOM dir and related cunit test case on line and curves.

File size: 54.3 KB
Line 
1/**********************************************************************
2 * $Id: liblwgeom.h 5821 2010-08-13 17:29:29Z colivier $
3 *
4 * PostGIS - Spatial Types for PostgreSQL
5 * http://postgis.refractions.net
6 * Copyright 2001-2006 Refractions Research Inc.
7 * Copyright 2007-2008 Mark Cave-Ayland
8 * Copyright 2008 Paul Ramsey <pramsey@cleverelephant.ca>
9 *
10 * This is free software; you can redistribute and/or modify it under
11 * the terms of the GNU General Public Licence. See the COPYING file.
12 *
13 **********************************************************************/
14
15#ifndef _LIBLWGEOM_H
16#define _LIBLWGEOM_H 1
17
18#include "../postgis_config.h"
19#include "stringbuffer.h"
20#include <stdarg.h>
21#include <stdio.h>
22
23/**
24* @file liblwgeom.h
25*
26* This library is the generic geometry handling section of PostGIS. The geometry
27* objects, constructors, destructors, and a set of spatial processing functions,
28* are implemented here.
29*
30* The library is designed for use in non-PostGIS applications if necessary. The
31* units tests at cunit/cu_tester.c and the loader/dumper programs at
32* ../loader/shp2pgsql.c are examples of non-PostGIS applications using liblwgeom.
33*
34* Programs using this library should set up the default memory managers and error
35* handlers by implementing an lwgeom_init_allocators() function, which can be as
36* a wrapper around the lwgeom_install_default_allocators() function if you want
37* no special handling for memory management and error reporting.
38*/
39
40#define INTEGRITY_CHECKS 1
41
42/*
43** Floating point comparitors.
44*/
45#define FP_TOLERANCE 1e-12
46#define FP_IS_ZERO(A) (fabs(A) <= FP_TOLERANCE)
47#define FP_MAX(A, B) (((A) > (B)) ? (A) : (B))
48#define FP_MIN(A, B) (((A) < (B)) ? (A) : (B))
49#define FP_EQUALS(A, B) (fabs((A)-(B)) <= FP_TOLERANCE)
50#define FP_NEQUALS(A, B) (fabs((A)-(B)) > FP_TOLERANCE)
51#define FP_LT(A, B) (((A) + FP_TOLERANCE) < (B))
52#define FP_LTEQ(A, B) (((A) - FP_TOLERANCE) <= (B))
53#define FP_GT(A, B) (((A) - FP_TOLERANCE) > (B))
54#define FP_GTEQ(A, B) (((A) + FP_TOLERANCE) >= (B))
55#define FP_CONTAINS_TOP(A, X, B) (FP_LT(A, X) && FP_LTEQ(X, B))
56#define FP_CONTAINS_BOTTOM(A, X, B) (FP_LTEQ(A, X) && FP_LT(X, B))
57#define FP_CONTAINS_INCL(A, X, B) (FP_LTEQ(A, X) && FP_LTEQ(X, B))
58#define FP_CONTAINS_EXCL(A, X, B) (FP_LT(A, X) && FP_LT(X, B))
59#define FP_CONTAINS(A, X, B) FP_CONTAINS_EXCL(A, X, B)
60
61/*
62** Utility true and false defines.
63*/
64#define LW_TRUE 1
65#define LW_FALSE 0
66
67/*
68* this will change to NaN when I figure out how to
69* get NaN in a platform-independent way
70*/
71#define NO_VALUE 0.0
72#define NO_Z_VALUE NO_VALUE
73#define NO_M_VALUE NO_VALUE
74
75#ifndef MAXFLOAT
76#define MAXFLOAT      3.402823466e+38F
77#endif
78
79typedef unsigned char uchar;
80
81#ifndef C_H
82typedef unsigned int uint32;
83typedef int int32;
84#endif
85
86/**
87* Global functions for memory/logging handlers.
88*/
89typedef void* (*lwallocator)(size_t size);
90typedef void* (*lwreallocator)(void *mem, size_t size);
91typedef void (*lwfreeor)(void* mem);
92typedef void (*lwreporter)(const char* fmt, va_list ap);
93extern lwreallocator lwrealloc_var;
94extern lwallocator lwalloc_var;
95extern lwfreeor lwfree_var;
96extern lwreporter lwerror_var;
97extern lwreporter lwnotice_var;
98
99/**
100* Supply the memory management and error handling functions you want your
101* application to use.
102* @ingroup system
103*/
104extern void lwgeom_init_allocators(void);
105
106/**
107* Apply the default memory management (malloc() and free()) and error handlers.
108* Called inside lwgeom_init_allocators() generally.
109* @ingroup system
110*/
111extern void lwgeom_install_default_allocators(void);
112
113/**
114* Write a notice out to the notice handler. Uses standard printf() substitutions.
115* Use for messages you always want output. For debugging, use LWDEBUG() or LWDEBUGF().
116* @ingroup logging
117*/
118void lwnotice(const char *fmt, ...);
119
120/**
121* Write a notice out to the error handler. Uses standard printf() substitutions.
122* Use for errors you always want output. For debugging, use LWDEBUG() or LWDEBUGF().
123* @ingroup logging
124*/
125void lwerror(const char *fmt, ...);
126
127/**
128* The default memory/logging handlers installed by lwgeom_install_default_allocators()
129*/
130void *default_allocator(size_t size);
131void *default_reallocator(void *mem, size_t size);
132void default_freeor(void *ptr);
133void default_errorreporter(const char *fmt, va_list ap);
134void default_noticereporter(const char *fmt, va_list ap);
135
136extern int lw_vasprintf (char **result, const char *format, va_list args);
137extern int lw_asprintf
138#if __STDC__
139(char **result, const char *format, ...);
140#else
141(result, va_alist);
142char **result;
143va_dcl
144#endif
145
146
147/* Debug macros */
148#if POSTGIS_DEBUG_LEVEL > 0
149
150/* Display a notice at the given debug level */
151#define LWDEBUG(level, msg) \
152        do { \
153                if (POSTGIS_DEBUG_LEVEL >= level) \
154                        lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__); \
155        } while (0);
156
157/* Display a formatted notice at the given debug level (like printf, with variadic arguments) */
158#define LWDEBUGF(level, msg, ...) \
159        do { \
160                if (POSTGIS_DEBUG_LEVEL >= level) \
161                        lwnotice("[%s:%s:%d] " msg, __FILE__, __func__, __LINE__, __VA_ARGS__); \
162        } while (0);
163
164#else
165
166/* Empty prototype that can be optimised away by the compiler for non-debug builds */
167#define LWDEBUG(level, msg) \
168        ((void) 0)
169
170/* Empty prototype that can be optimised away by the compiler for non-debug builds */
171#define LWDEBUGF(level, msg, ...) \
172        ((void) 0)
173
174#endif
175
176/******************************************************************/
177
178
179typedef struct
180{
181        float xmin;
182        float ymin;
183        float xmax;
184        float ymax;
185}
186BOX2DFLOAT4;
187
188typedef struct
189{
190        double xmin, ymin, zmin;
191        double xmax, ymax, zmax;
192}
193BOX3D;
194
195typedef struct chiptag
196{
197        int size; /* unused (for use by postgresql) */
198
199        int endian_hint; /* the number 1 in the endian of this datastruct */
200
201        BOX3D bvol;
202        int SRID;
203        char future[4];
204        float factor;   /* Usually 1.0.
205                                 * Integer values are multiplied by this number
206                                 * to get the actual height value
207                                 * (for sub-meter accuracy height data).
208                                 */
209
210        int datatype;   /* 1 = float32,
211                                 * 5 = 24bit integer,
212                                 * 6 = 16bit integer (short)
213                                 * 7 = 16bit ???
214                                 * 8 = 8bit ???
215                                 * 101 = float32 (NDR),
216                                 * 105 = 24bit integer (NDR),
217                                 * 106 = 16bit int (NDR)
218                                 * 107 = 16bit ??? (NDR)
219                                 * 108 = 8bit ??? (NDR) (this doesn't make sense)
220                                 */
221        int height;
222        int width;
223        int compression;        /* 0 = no compression, 1 = differencer
224                                         * 0x80 = new value
225                                         * 0x7F = nodata
226                                         */
227
228        /*
229         * this is provided for convenience, it should be set to
230         *  sizeof(chip) bytes into the struct because the serialized form is:
231         *    <header><data>
232         * NULL when serialized
233         */
234        void  *data;    /* data[0] = bottm left,
235                                 * data[width] = 1st pixel, 2nd row (uncompressed)
236                                 */
237
238}
239CHIP;
240
241/*
242 * standard definition of an ellipsoid (what wkt calls a spheroid)
243 *    f = (a-b)/a
244 *    e_sq = (a*a - b*b)/(a*a)
245 *    b = a - fa
246 */
247typedef struct
248{
249        double  a;      /* semimajor axis */
250        double  b;      /* semiminor axis */
251        double  f;      /* flattening     */
252        double  e;      /* eccentricity (first) */
253        double  e_sq;   /* eccentricity (first), squared */
254        double  radius; /* (2*a+b)/3 spherical average radius */
255        char    name[20]; /* name of ellipse */
256}
257SPHEROID;
258
259
260/*
261 * ALL LWGEOM structures will use POINT3D as an abstract point.
262 * This means a 2d geometry will be stored as (x,y) in its serialized
263 * form, but all functions will work on (x,y,0).  This keeps all the
264 * analysis functions simple.
265 * NOTE: for GEOS integration, we'll probably set z=NaN
266 *        so look out - z might be NaN for 2d geometries!
267 */
268typedef struct
269{
270        double  x,y,z;
271}
272POINT3DZ;
273typedef struct
274{
275        double  x,y,z;
276}
277POINT3D; /* alias for POINT3DZ */
278typedef struct
279{
280        double  x,y,m;
281}
282POINT3DM;
283
284
285/*
286 * type for 2d points.  When you convert this to 3d, the
287 *   z component will be either 0 or NaN.
288 */
289typedef struct
290{
291        double x;
292        double y;
293}
294POINT2D;
295
296typedef struct
297{
298        double x;
299        double y;
300        double z;
301        double m;
302}
303POINT4D;
304
305/******************************************************************/
306
307/*
308 * Point array abstracts a lot of the complexity of points and point lists.
309 * It handles miss-alignment in the serialized form, 2d/3d translation
310 *    (2d points converted to 3d will have z=0 or NaN)
311 * DONT MIX 2D and 3D POINTS!  *EVERYTHING* is either one or the other
312 */
313typedef struct
314{
315        /* array of POINT 2D, 3D or 4D. probably missaligned. */
316        uchar *serialized_pointlist;
317
318        /* use TYPE_* macros to handle */
319        uchar  dims;
320
321        int npoints;
322        int maxpoints;
323}
324POINTARRAY;
325
326
327/*
328 * Use the following to build pointarrays
329 * when number of points in output is not
330 * known in advance
331 */
332typedef struct
333{
334        POINTARRAY *pa;
335        size_t ptsize;
336        size_t capacity; /* given in points */
337}
338DYNPTARRAY;
339
340/* Create a new dynamic pointarray */
341extern DYNPTARRAY *dynptarray_create(size_t initial_capacity, int dims);
342
343/*
344 * Add a POINT4D to the dynamic pointarray.
345 *
346 * The dynamic pointarray may be of any dimension, only
347 * accepted dimensions will be copied.
348 *
349 * If allow_duplicates is set to 0 (false) a check
350 * is performed to see if last point in array is equal to the
351 * provided one. NOTE that the check is 4d based, with missing
352 * ordinates in the pointarray set to NO_Z_VALUE and NO_M_VALUE
353 * respectively.
354 */
355extern int dynptarray_addPoint4d(DYNPTARRAY *dpa, POINT4D *p4d,
356                                 int allow_duplicates);
357
358/******************************************************************
359 *
360 * LWGEOM (any type)
361 *
362 ******************************************************************/
363
364typedef struct
365{
366        uchar type;
367        BOX2DFLOAT4 *bbox;
368        uint32 SRID; /* -1 == unneeded */
369        void *data;
370}
371LWGEOM;
372
373/* POINTYPE */
374typedef struct
375{
376        uchar type; /* POINTTYPE */
377        BOX2DFLOAT4 *bbox;
378        uint32 SRID;
379        POINTARRAY *point;  /* hide 2d/3d (this will be an array of 1 point) */
380}
381LWPOINT; /* "light-weight point" */
382
383/* LINETYPE */
384typedef struct
385{
386        uchar type; /* LINETYPE */
387        BOX2DFLOAT4 *bbox;
388        uint32 SRID;
389        POINTARRAY *points; /* array of POINT3D */
390}
391LWLINE; /* "light-weight line" */
392
393/* POLYGONTYPE */
394typedef struct
395{
396        uchar type; /* POLYGONTYPE */
397        BOX2DFLOAT4 *bbox;
398        uint32 SRID;
399        int nrings;
400        int maxrings;
401        POINTARRAY **rings; /* list of rings (list of points) */
402}
403LWPOLY; /* "light-weight polygon" */
404
405/* MULTIPOINTTYPE */
406typedef struct
407{
408        uchar type;
409        BOX2DFLOAT4 *bbox;
410        uint32 SRID;
411        int ngeoms;
412        int maxgeoms;
413        LWPOINT **geoms;
414}
415LWMPOINT;
416
417/* MULTILINETYPE */
418typedef struct
419{
420        uchar type;
421        BOX2DFLOAT4 *bbox;
422        uint32 SRID;
423        int ngeoms;
424        int maxgeoms;
425        LWLINE **geoms;
426}
427LWMLINE;
428
429/* MULTIPOLYGONTYPE */
430typedef struct
431{
432        uchar type;
433        BOX2DFLOAT4 *bbox;
434        uint32 SRID;
435        int ngeoms;
436        int maxgeoms;
437        LWPOLY **geoms;
438}
439LWMPOLY;
440
441/* COLLECTIONTYPE */
442typedef struct
443{
444        uchar type;
445        BOX2DFLOAT4 *bbox;
446        uint32 SRID;
447        int ngeoms;
448        int maxgeoms;
449        LWGEOM **geoms;
450}
451LWCOLLECTION;
452
453/* CIRCSTRINGTYPE */
454typedef struct
455{
456        uchar type; /* CIRCSTRINGTYPE */
457        BOX2DFLOAT4 *bbox;
458        uint32 SRID;
459        POINTARRAY *points; /* array of POINT(3D/3DM) */
460}
461LWCIRCSTRING; /* "light-weight circularstring" */
462
463/* COMPOUNDTYPE */
464typedef struct
465{
466        uchar type; /* COMPOUNDTYPE */
467        BOX2DFLOAT4 *bbox;
468        uint32 SRID;
469        int ngeoms;
470        int maxgeoms;
471        LWGEOM **geoms;
472}
473LWCOMPOUND; /* "light-weight compound line" */
474
475/* CURVEPOLYTYPE */
476typedef struct
477{
478        uchar type; /* CURVEPOLYTYPE */
479        BOX2DFLOAT4 *bbox;
480        uint32 SRID;
481        int nrings;
482        int maxrings;
483        LWGEOM **rings; /* list of rings (list of points) */
484}
485LWCURVEPOLY; /* "light-weight polygon" */
486
487/* MULTICURVE */
488typedef struct
489{
490        uchar type;
491        BOX2DFLOAT4 *bbox;
492        uint32 SRID;
493        int ngeoms;
494        int maxgeoms;
495        LWGEOM **geoms;
496}
497LWMCURVE;
498
499/* MULTISURFACETYPE */
500typedef struct
501{
502        uchar type;
503        BOX2DFLOAT4 *bbox;
504        uint32 SRID;
505        int ngeoms;
506        int maxgeoms;
507        LWGEOM **geoms;
508}
509LWMSURFACE;
510
511/* POLYHEDRALSURFACETYPE */
512typedef struct
513{
514        uchar type;
515        BOX2DFLOAT4 *bbox;
516        uint32 SRID;
517        int ngeoms;
518        int maxgeoms;
519        LWPOLY **geoms;
520}
521LWPSURFACE;
522
523/* TRIANGLE */
524typedef struct
525{
526        uchar type;
527        BOX2DFLOAT4 *bbox;
528        uint32 SRID;
529        POINTARRAY *points;
530}
531LWTRIANGLE;
532
533/* TINTYPE */
534typedef struct
535{
536        uchar type;
537        BOX2DFLOAT4 *bbox;
538        uint32 SRID;
539        int ngeoms;
540        int maxgeoms;
541        LWTRIANGLE **geoms;
542}
543LWTIN;
544
545/* Casts LWGEOM->LW* (return NULL if cast is illegal) */
546extern LWMPOLY *lwgeom_as_lwmpoly(const LWGEOM *lwgeom);
547extern LWMLINE *lwgeom_as_lwmline(const LWGEOM *lwgeom);
548extern LWMPOINT *lwgeom_as_lwmpoint(const LWGEOM *lwgeom);
549extern LWCOLLECTION *lwgeom_as_lwcollection(const LWGEOM *lwgeom);
550extern LWPOLY *lwgeom_as_lwpoly(const LWGEOM *lwgeom);
551extern LWLINE *lwgeom_as_lwline(const LWGEOM *lwgeom);
552extern LWPOINT *lwgeom_as_lwpoint(const LWGEOM *lwgeom);
553extern LWCIRCSTRING *lwgeom_as_lwcircstring(const LWGEOM *lwgeom);
554extern LWPSURFACE *lwgeom_as_lwpsurface(const LWGEOM *lwgeom);
555extern LWTRIANGLE *lwgeom_as_lwtriangle(const LWGEOM *lwgeom);
556extern LWTIN *lwgeom_as_lwtin(const LWGEOM *lwgeom);
557extern LWGEOM *lwgeom_as_multi(const LWGEOM *lwgeom);
558
559/* Casts LW*->LWGEOM (always cast) */
560extern LWGEOM *lwtin_as_lwgeom(const LWTIN *obj);
561extern LWGEOM *lwtriangle_as_lwgeom(const LWTRIANGLE *obj);
562extern LWGEOM *lwpsurface_as_lwgeom(const LWPSURFACE *obj);
563extern LWGEOM *lwmpoly_as_lwgeom(const LWMPOLY *obj);
564extern LWGEOM *lwmline_as_lwgeom(const LWMLINE *obj);
565extern LWGEOM *lwmpoint_as_lwgeom(const LWMPOINT *obj);
566extern LWGEOM *lwcollection_as_lwgeom(const LWCOLLECTION *obj);
567extern LWGEOM *lwcircstring_as_lwgeom(const LWCIRCSTRING *obj);
568extern LWGEOM *lwpoly_as_lwgeom(const LWPOLY *obj);
569extern LWGEOM *lwline_as_lwgeom(const LWLINE *obj);
570extern LWGEOM *lwpoint_as_lwgeom(const LWPOINT *obj);
571
572
573extern LWCOLLECTION* lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom);
574extern LWMPOINT* lwmpoint_add_lwpoint(LWMPOINT *mobj, const LWPOINT *obj);
575extern LWMLINE* lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj);
576extern LWMPOLY* lwmpoly_add_lwpoly(LWMPOLY *mobj, const LWPOLY *obj);
577extern LWPSURFACE* lwpsurface_add_lwpoly(LWPSURFACE *mobj, const LWPOLY *obj);
578extern LWTIN* lwtin_add_lwtriangle(LWTIN *mobj, const LWTRIANGLE *obj);
579
580/*
581 * Call this function everytime LWGEOM coordinates
582 * change so to invalidate bounding box
583 */
584extern void lwgeom_changed(LWGEOM *lwgeom);
585
586/*
587 * Call this function to drop BBOX and SRID
588 * from LWGEOM. If LWGEOM type is *not* flagged
589 * with the HASBBOX flag and has a bbox, it
590 * will be released.
591 */
592extern void lwgeom_drop_bbox(LWGEOM *lwgeom);
593
594/* Compute a bbox if not already computed */
595extern void lwgeom_add_bbox(LWGEOM *lwgeom);
596
597extern void lwgeom_dropSRID(LWGEOM *lwgeom);
598
599/* Determine whether a LWGEOM can contain sub-geometries or not */
600extern int lwgeom_is_collection(int type);
601
602/******************************************************************/
603
604/*
605 * copies a point from the point array into the parameter point
606 * will set point's z=0 (or NaN) if pa is 2d
607 * will set point's m=0 (or NaN) if pa is 3d or 2d
608 * NOTE: point is a real POINT3D *not* a pointer
609 */
610extern POINT4D getPoint4d(const POINTARRAY *pa, int n);
611
612/*
613 * copies a point from the point array into the parameter point
614 * will set point's z=0 (or NaN) if pa is 2d
615 * will set point's m=0 (or NaN) if pa is 3d or 2d
616 * NOTE: this will modify the point4d pointed to by 'point'.
617 */
618extern int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point);
619
620/*
621 * copies a point from the point array into the parameter point
622 * will set point's z=0 (or NaN) if pa is 2d
623 * NOTE: point is a real POINT3D *not* a pointer
624 */
625extern POINT3DZ getPoint3dz(const POINTARRAY *pa, int n);
626extern POINT3DM getPoint3dm(const POINTARRAY *pa, int n);
627
628/*
629 * copies a point from the point array into the parameter point
630 * will set point's z=0 (or NaN) if pa is 2d
631 * NOTE: this will modify the point3d pointed to by 'point'.
632 */
633extern int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point);
634extern int getPoint3dm_p(const POINTARRAY *pa, int n, POINT3DM *point);
635
636
637/*
638 * copies a point from the point array into the parameter point
639 * z value (if present is not returned)
640 * NOTE: point is a real POINT3D *not* a pointer
641 */
642extern POINT2D getPoint2d(const POINTARRAY *pa, int n);
643
644/*
645 * copies a point from the point array into the parameter point
646 * z value (if present is not returned)
647 * NOTE: this will modify the point2d pointed to by 'point'.
648 */
649extern int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point);
650
651/*
652 * set point N to the given value
653 * NOTE that the pointarray can be of any
654 * dimension, the appropriate ordinate values
655 * will be extracted from it
656 *
657 */
658extern void setPoint4d(POINTARRAY *pa, int n, POINT4D *p4d);
659
660/*
661 * get a pointer to nth point of a POINTARRAY
662 * You'll need to cast it to appropriate dimensioned point.
663 * Note that if you cast to a higher dimensional point you'll
664 * possibly corrupt the POINTARRAY.
665 *
666 * WARNING: Don't cast this to a POINT !
667 * it would not be reliable due to memory alignment constraints
668 */
669extern uchar *getPoint_internal(const POINTARRAY *pa, int n);
670
671/* --- here is a macro equivalent, for speed... */
672/* #define getPoint(x,n) &( (x)->serialized_pointlist[((x)->ndims*8)*(n)] ) */
673
674
675/*
676 * constructs a POINTARRAY.
677 * NOTE: points is *not* copied, so be careful about modification
678 * (can be aligned/missaligned)
679 * NOTE: hasz and hasm are descriptive - it describes what type of data
680 *       'points' points to.  No data conversion is done.
681 */
682extern POINTARRAY *pointArray_construct(uchar *points, char hasz, char hasm,
683                                        uint32 npoints);
684
685/*
686 * Calculate the (BOX3D) bounding box of a set of points.
687 * Returns an alloced BOX3D or NULL (for empty geom) in the first form.
688 * Write result in user-provided BOX3D in second form (return 0 if untouched).
689 * If pa is 2d, then box3d's zmin/zmax will be set to NO_Z_VALUE
690 */
691extern BOX3D *ptarray_compute_box3d(const POINTARRAY *pa);
692extern int ptarray_compute_box3d_p(const POINTARRAY *pa, BOX3D *out);
693
694
695
696/*
697 * size of point represeneted in the POINTARRAY
698 * 16 for 2d, 24 for 3d, 32 for 4d
699 */
700extern int pointArray_ptsize(const POINTARRAY *pa);
701
702#define POINTTYPE               1
703#define LINETYPE                2
704#define POLYGONTYPE             3
705#define MULTIPOINTTYPE          4
706#define MULTILINETYPE           5
707#define MULTIPOLYGONTYPE        6
708#define COLLECTIONTYPE          7
709#define CIRCSTRINGTYPE          8
710#define COMPOUNDTYPE            9
711#define CURVEPOLYTYPE           10
712#define MULTICURVETYPE          11
713#define MULTISURFACETYPE        12
714#define POLYHEDRALSURFACETYPE   13
715#define TRIANGLETYPE            14
716#define TINTYPE                 15
717
718#define WKBZOFFSET 0x80000000
719#define WKBMOFFSET 0x40000000
720#define WKBSRIDFLAG 0x20000000
721#define WKBBBOXFLAG 0x10000000
722
723/* These macros work on PG_LWGEOM.type, LWGEOM.type and all its subclasses */
724
725#define TYPE_SETTYPE(c,t) ((c)=(((c)&0xF0)|(t)))
726#define TYPE_SETZM(t,z,m) ((t)=(((t)&0xCF)|((z)<<5)|((m)<<4)))
727#define TYPE_SETHASBBOX(t,b) ((t)=(((t)&0x7F)|((b)<<7)))
728#define TYPE_SETHASSRID(t,s) ((t)=(((t)&0xBF)|((s)<<6)))
729
730#define TYPE_HASZ(t) ( ((t)&0x20)>>5 )
731#define TYPE_HASM(t) ( ((t)&0x10)>>4 )
732#define TYPE_HASBBOX(t) ( ((t)&0x80)>>7 )
733#define TYPE_HASSRID(t) ( (((t)&0x40))>>6 )
734#define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2)
735#define TYPE_GETTYPE(t) ((t)&0x0F)
736
737/* 0x02==Z 0x01==M */
738#define TYPE_GETZM(t) (((t)&0x30)>>4)
739
740extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set     */
741extern int  lwgeom_ndims(uchar type);   /* returns 2,3 or 4       */
742extern int  lwgeom_hasZ(uchar type);    /* has Z ?                */
743extern int  lwgeom_hasM(uchar type);    /* has M ?                */
744extern int  lwgeom_getType(uchar type); /* returns the tttt value */
745
746extern uchar lwgeom_makeType(char hasZ, char hasM, char hasSRID, int type);
747extern uchar lwgeom_makeType_full(char hasZ, char hasM, char hasSRID, int type, char hasBBOX);
748extern char lwgeom_hasSRID(uchar type); /* true iff S bit is set */
749extern char lwgeom_hasBBOX(uchar type); /* true iff B bit set    */
750
751
752
753/*
754 * This is the binary representation of lwgeom compatible
755 * with postgresql varlena struct
756 */
757typedef struct
758{
759        uint32 size;        /* varlena header (do not touch directly!) */
760        uchar type;         /* encodes ndims, type, bbox presence,
761                                        srid presence */
762        uchar data[1];
763}
764PG_LWGEOM;
765
766/*
767 * Construct a full PG_LWGEOM type (including size header)
768 * from a serialized form.
769 * The constructed PG_LWGEOM object will be allocated using palloc
770 * and the serialized form will be copied.
771 * If you specify a SRID other then -1 it will be set.
772 * If you request bbox (wantbbox=1) it will be extracted or computed
773 * from the serialized form.
774 */
775extern PG_LWGEOM *PG_LWGEOM_construct(uchar *serialized, int SRID, int wantbbox);
776
777/*
778 * Compute bbox of serialized geom
779 */
780extern int compute_serialized_box2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
781extern BOX3D *compute_serialized_box3d(uchar *serialized_form);
782extern int compute_serialized_box3d_p(uchar *serialized_form, BOX3D *box);
783
784
785/*
786 * Evaluate with an heuristic if the provided PG_LWGEOM is worth
787 * caching a bbox
788 */
789char is_worth_caching_pglwgeom_bbox(const PG_LWGEOM *);
790char is_worth_caching_serialized_bbox(const uchar *);
791char is_worth_caching_lwgeom_bbox(const LWGEOM *);
792
793
794/*
795 * This function computes the size in bytes
796 * of the serialized geometries.
797 */
798extern size_t lwgeom_size(const uchar *serialized_form);
799extern size_t lwgeom_size_subgeom(const uchar *serialized_form, int geom_number);
800extern size_t lwgeom_size_line(const uchar *serialized_line);
801extern size_t lwgeom_size_circstring(const uchar *serialized_curve);
802extern size_t lwgeom_size_point(const uchar *serialized_point);
803extern size_t lwgeom_size_poly(const uchar *serialized_line);
804extern size_t lwgeom_size_triangle(const uchar *serialized_line);
805
806
807/*--------------------------------------------------------
808 * all the base types (point/line/polygon) will have a
809 * basic constructor, basic de-serializer, basic serializer,
810 * bounding box finder and (TODO) serialized form size finder.
811 *--------------------------------------------------------*/
812
813/*
814 * given the LWPOINT serialized form (or a pointer into a muli* one)
815 * construct a proper LWPOINT.
816 * serialized_form should point to the 8bit type format (with type = 1)
817 * Returns NULL if serialized form is not a point.
818 * See serialized form doc
819 */
820extern LWPOINT *lwpoint_deserialize(uchar *serialized_form);
821
822/*
823 * Find size this point would get when serialized (no BBOX)
824 */
825extern size_t lwpoint_serialize_size(LWPOINT *point);
826
827/*
828 * convert this point into its serialize form
829 * result's first char will be the 8bit type.
830 * See serialized form doc
831 */
832extern uchar *lwpoint_serialize(LWPOINT *point);
833
834/* same as above, writes to buf */
835extern void lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *size);
836
837/*
838 * find bounding box (standard one)
839 * zmin=zmax=0 if 2d (might change to NaN)
840 */
841extern BOX3D *lwpoint_compute_box3d(LWPOINT *point);
842
843/*
844 * convenience functions to hide the POINTARRAY
845 */
846extern int lwpoint_getPoint2d_p(const LWPOINT *point, POINT2D *out);
847extern int lwpoint_getPoint3dz_p(const LWPOINT *point, POINT3DZ *out);
848extern int lwpoint_getPoint3dm_p(const LWPOINT *point, POINT3DM *out);
849extern int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out);
850
851/******************************************************************
852 * LWLINE functions
853 ******************************************************************/
854
855/*
856 * given the LWGEOM serialized form (or a pointer into a muli* one)
857 * construct a proper LWLINE.
858 * serialized_form should point to the 8bit type format (with type = 2)
859 * See SERIALIZED_FORM doc
860 */
861extern LWLINE *lwline_deserialize(uchar *serialized_form);
862
863/* find the size this line would get when serialized */
864extern size_t lwline_serialize_size(LWLINE *line);
865
866/*
867 * convert this line into its serialize form
868 * result's first char will be the 8bit type.  See serialized form doc
869 * copies data.
870 */
871extern uchar *lwline_serialize(LWLINE *line);
872
873/* same as above, writes to buf */
874extern void lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *size);
875
876/*
877 * find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
878 */
879extern BOX3D *lwline_compute_box3d(LWLINE *line);
880
881/******************************************************************
882 * LWPOLY functions
883 ******************************************************************/
884
885/*
886 * given the LWPOLY serialized form (or a pointer into a muli* one)
887 * construct a proper LWPOLY.
888 * serialized_form should point to the 8bit type format (with type = 3)
889 * See SERIALIZED_FORM doc
890 */
891extern LWPOLY *lwpoly_deserialize(uchar *serialized_form);
892
893/* find the size this polygon would get when serialized */
894extern size_t lwpoly_serialize_size(LWPOLY *poly);
895
896/*
897 * create the serialized form of the polygon
898 * result's first char will be the 8bit type.  See serialized form doc
899 * points copied
900 */
901extern uchar *lwpoly_serialize(LWPOLY *poly);
902
903/* same as above, writes to buf */
904extern void lwpoly_serialize_buf(LWPOLY *poly, uchar *buf, size_t *size);
905
906/*
907 * find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
908 */
909extern BOX3D *lwpoly_compute_box3d(LWPOLY *poly);
910
911/******************************************************************
912 * LWTRIANGLE functions
913 ******************************************************************/
914
915/*
916 * given the LWGEOM serialized form
917 * construct a proper LWTRIANGLE.
918 * serialized_form should point to the 8bit type format
919 * See SERIALIZED_FORM doc
920 */
921extern LWTRIANGLE *lwtriangle_deserialize(uchar *serialized_form);
922
923/* find the size this triangle would get when serialized */
924extern size_t lwtriangle_serialize_size(LWTRIANGLE *triangle);
925
926/*
927 * convert this triangle into its serialize form
928 * result's first char will be the 8bit type.  See serialized form doc
929 * copies data.
930 */
931extern uchar *lwtriangle_serialize(LWTRIANGLE *triangle);
932
933/* same as above, writes to buf */
934extern void lwtriangle_serialize_buf(LWTRIANGLE *triangle, uchar *buf, size_t *size);
935
936/*
937 * find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
938 */
939extern BOX3D *lwtriangle_compute_box3d(LWTRIANGLE *triangle);
940
941/******************************************************************
942 * LWCIRCSTRING functions
943 ******************************************************************/
944
945/*
946 * given the LWGEOM serialized form (or a pointer into a muli* one)
947 * construct a proper LWCIRCSTRING.
948 * serialized_form should point to the 8bit type format (with type = 2)
949 * See SERIALIZED_FORM doc
950 */
951extern LWCIRCSTRING *lwcircstring_deserialize(uchar *serialized_form);
952
953/* find the size this curve would get when serialized */
954extern size_t lwcircstring_serialize_size(LWCIRCSTRING *curve);
955
956/*
957 * convert this circularstring into its serialize form
958 * result's first char will be the 8bit type.  See serialized form doc
959 * copies data.
960 */
961extern uchar *lwcircstring_serialize(LWCIRCSTRING *curve);
962
963/* same as above, writes to buf */
964extern void lwcircstring_serialize_buf(LWCIRCSTRING *curve, uchar *buf, size_t *size);
965
966/*
967 * find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
968 */
969extern BOX3D *lwcircstring_compute_box3d(const LWCIRCSTRING *curve);
970
971
972
973/******************************************************************
974 * LWGEOM functions
975 ******************************************************************/
976
977extern size_t lwgeom_serialize_size(LWGEOM *geom);
978extern size_t lwcollection_serialize_size(LWCOLLECTION *coll);
979extern void lwgeom_serialize_buf(LWGEOM *geom, uchar *buf, size_t *size);
980extern uchar *lwgeom_serialize(LWGEOM *geom);
981extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, uchar *buf, size_t *size);
982extern int lwcollection_ngeoms(const LWCOLLECTION *col);
983
984/* Given a generic geometry/collection, return the "simplest" form. */
985extern LWGEOM *lwgeom_homogenize(const LWGEOM *geom);
986extern LWGEOM *lwcollection_homogenize(const LWCOLLECTION *col);
987
988/*
989 * Deserialize an lwgeom serialized form.
990 * The deserialized (recursive) structure will store
991 * pointers to the serialized form (POINTARRAYs).
992 */
993LWGEOM *lwgeom_deserialize(uchar *serializedform);
994BOX3D *lwgeom_compute_box3d(const LWGEOM *geom);
995
996
997/******************************************************************
998 * LWMULTIx and LWCOLLECTION functions
999 ******************************************************************/
1000
1001LWMPOINT *lwmpoint_deserialize(uchar *serializedform);
1002LWMLINE *lwmline_deserialize(uchar *serializedform);
1003LWMPOLY *lwmpoly_deserialize(uchar *serializedform);
1004LWCOLLECTION *lwcollection_deserialize(uchar *serializedform);
1005LWCOMPOUND *lwcompound_deserialize(uchar *serialized_form);
1006LWCURVEPOLY *lwcurvepoly_deserialize(uchar *serialized_form);
1007LWMCURVE *lwmcurve_deserialize(uchar *serialized_form);
1008LWMSURFACE *lwmsurface_deserialize(uchar *serialized_form);
1009LWPSURFACE *lwpsurface_deserialize(uchar *serialized_form);
1010LWTIN *lwtin_deserialize(uchar *serialized_form);
1011
1012LWGEOM *lwcollection_getsubgeom(LWCOLLECTION *col, int gnum);
1013BOX3D *lwcollection_compute_box3d(LWCOLLECTION *col);
1014LWCOLLECTION* lwcollection_extract(LWCOLLECTION *col, int type);
1015
1016/******************************************************************
1017 * SERIALIZED FORM functions
1018 ******************************************************************/
1019
1020
1021/******************************************************************
1022 * Multi-geometries
1023 *
1024 * These are all handled equivelently so its easy to write iterator code.
1025 *  NOTE NOTE: you can hand in a non-multigeometry to most of these functions
1026 *             and get usual behavior (ie. get geometry 0 on a POINT
1027 *             will return the point).
1028 *             This makes coding even easier since you dont have to necessarily
1029 *             differenciate between the multi* and non-multi geometries.
1030 *
1031 * NOTE: these usually work directly off the serialized form, so
1032 *      they're a little more difficult to handle (and slower)
1033 * NOTE NOTE: the get functions maybe slow, so we may want to have an
1034 *            "analysed" lwgeom that would just have pointer to the start
1035 *            of each sub-geometry.
1036 *
1037 ******************************************************************/
1038
1039/* use this version for speed.  READ-ONLY! */
1040typedef struct
1041{
1042        int   SRID;
1043        const uchar *serialized_form; /* orginal structure */
1044        uchar  type;        /* 8-bit type for the LWGEOM */
1045        int ngeometries;    /* number of sub-geometries */
1046        uchar **sub_geoms;  /* list of pointers (into serialized_form)
1047                                       of the sub-geoms */
1048}
1049LWGEOM_INSPECTED;
1050
1051extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number);
1052
1053/*
1054 * note - for a simple type (ie. point), this will have
1055 * sub_geom[0] = serialized_form.
1056 * for multi-geomtries sub_geom[0] will be a few bytes into the
1057 * serialized form.
1058 * This function just computes the length of each sub-object and
1059 * pre-caches this info.
1060 * For a geometry collection of multi* geometries, you can inspect
1061 * the sub-components as well.
1062 */
1063extern LWGEOM_INSPECTED *lwgeom_inspect(const uchar *serialized_form);
1064
1065
1066/*
1067 * 1st geometry has geom_number = 0
1068 * if the actual sub-geometry isnt a POINT, null is returned (see _gettype()).
1069 * if there arent enough geometries, return null.
1070 * this is fine to call on a point (with geom_num=0), multipoint
1071 * or geometrycollection
1072 */
1073extern LWPOINT *lwgeom_getpoint(uchar *serialized_form, int geom_number);
1074extern LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1075
1076/*
1077 * 1st geometry has geom_number = 0
1078 * if the actual geometry isnt a LINE, null is returned (see _gettype()).
1079 * if there arent enough geometries, return null.
1080 * this is fine to call on a line, multiline or geometrycollection
1081 */
1082extern LWLINE *lwgeom_getline(uchar *serialized_form, int geom_number);
1083extern LWLINE *lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1084
1085/*
1086 * 1st geometry has geom_number = 0
1087 * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
1088 * if there arent enough geometries, return null.
1089 * this is fine to call on a polygon, multipolygon or geometrycollection
1090 */
1091extern LWPOLY *lwgeom_getpoly(uchar *serialized_form, int geom_number);
1092extern LWPOLY *lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1093
1094/*
1095 * 1st geometry has geom_number = 0
1096 * if the actual geometry isnt a TRIANGLE, null is returned (see _gettype()).
1097 * if there arent enough geometries, return null.
1098 * this is fine to call on a triangle, Tin or geometrycollection
1099 */
1100extern LWTRIANGLE *lwgeom_gettriangle(uchar *serialized_form, int geom_number);
1101extern LWTRIANGLE *lwgeom_gettriangle_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1102
1103/*
1104 * 1st geometry has geom_number = 0
1105 * if the actual geometry isnt a POLYGON, null is returned (see _gettype()).
1106 * if there arent enough geometries, return null.
1107 * this is fine to call on a polygon, multipolygon or geometrycollection
1108 */
1109extern LWCIRCSTRING *lwgeom_getcircstring_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1110
1111extern LWGEOM *lwgeom_getgeom_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1112
1113
1114
1115/*
1116 * this gets the serialized form of a sub-geometry
1117 * 1st geometry has geom_number = 0
1118 * if this isnt a multi* geometry, and geom_number ==0 then it returns
1119 * itself
1120 * returns null on problems.
1121 * in the future this is how you would access a muli* portion of a
1122 * geometry collection.
1123 *    GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1))
1124 *   ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1)
1125 *           --> POINT(1 1)
1126 * you can inspect the sub-geometry as well if you wish.
1127 */
1128extern uchar *lwgeom_getsubgeometry(const uchar *serialized_form, int geom_number);
1129extern uchar *lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1130
1131
1132/*
1133 * 1st geometry has geom_number = 0
1134 *  use geom_number = -1 to find the actual type of the serialized form.
1135 *    ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1)
1136 *                 --> multipoint
1137 *   ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0)
1138 *                 --> point
1139 * gets the 8bit type of the geometry at location geom_number
1140 */
1141extern uchar lwgeom_getsubtype(uchar *serialized_form, int geom_number);
1142extern uchar lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number);
1143
1144
1145/*
1146 * how many sub-geometries are there?
1147 *  for point,line,polygon will return 1.
1148 */
1149extern int lwgeom_getnumgeometries(uchar *serialized_form);
1150extern int lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected);
1151
1152
1153
1154/*
1155 * set finalType to COLLECTIONTYPE or 0 (0 means choose a best type)
1156 *   (ie. give it 2 points and ask it to be a multipoint)
1157 *  use SRID=-1 for unknown SRID  (will have 8bit type's S = 0)
1158 * all subgeometries must have the same SRID
1159 * if you want to construct an inspected, call this then inspect the result...
1160 */
1161extern uchar *lwgeom_serialized_construct(int SRID, int finalType, char hasz, char hasm, int nsubgeometries, uchar **serialized_subs);
1162
1163
1164/* construct the empty geometry (GEOMETRYCOLLECTION(EMPTY)) */
1165extern uchar *lwgeom_constructempty(int SRID, char hasz, char hasm);
1166extern void lwgeom_constructempty_buf(int SRID, char hasz, char hasm, uchar *buf, size_t *size);
1167size_t lwgeom_empty_length(int SRID);
1168
1169/*
1170 * get the SRID from the LWGEOM
1171 * none present => -1
1172 */
1173extern int lwgeom_getsrid(uchar *serialized);
1174
1175
1176/*------------------------------------------------------
1177 * other stuff
1178 *
1179 * handle the double-to-float conversion.  The results of this
1180 * will usually be a slightly bigger box because of the difference
1181 * between float8 and float4 representations.
1182 */
1183
1184extern BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box);
1185extern int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *res);
1186
1187extern BOX3D box2df_to_box3d(BOX2DFLOAT4 *box);
1188extern void box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *box3d);
1189
1190extern BOX3D *box3d_union(BOX3D *b1, BOX3D *b2);
1191extern int box3d_union_p(BOX3D *b1, BOX3D *b2, BOX3D *ubox);
1192
1193/*
1194 * Returns a pointer to the BBOX internal to the serialized form.
1195 * READ-ONLY!
1196 * Or NULL if serialized form does not have a BBOX
1197 * OBSOLETED to avoid memory alignment problems.
1198 */
1199/*extern BOX2DFLOAT4 *getbox2d_internal(uchar *serialized_form);*/
1200
1201/*
1202 * this function writes to 'box' and returns 0 if serialized_form
1203 * does not have a bounding box (empty geom)
1204 */
1205extern int getbox2d_p(uchar *serialized_form, BOX2DFLOAT4 *box);
1206
1207/* Expand given box of 'd' units in all directions */
1208void expand_box2d(BOX2DFLOAT4 *box, double d);
1209void expand_box3d(BOX3D *box, double d);
1210
1211/* Check if to boxes are equal (considering FLOAT approximations) */
1212char box2d_same(BOX2DFLOAT4 *box1, BOX2DFLOAT4 *box2);
1213
1214
1215
1216/****************************************************************
1217 * MEMORY MANAGEMENT
1218 ****************************************************************/
1219
1220/*
1221 * The lwfree_* family of functions frees *all* memory associated
1222 * with the pointer, including the serialized__pointlist in the
1223 * point arrays. Do not use these on LWGEOMs de-serialized from
1224 * PG_LWGEOMs or they will try to free an underlying structure
1225 * managed by PgSQL. Only use these on LWGEOMs you have
1226 * constructed yourself.
1227 */
1228
1229extern void ptarray_free(POINTARRAY *pa);
1230extern void lwpoint_free(LWPOINT *pt);
1231extern void lwline_free(LWLINE *line);
1232extern void lwpoly_free(LWPOLY *poly);
1233extern void lwtriangle_free(LWTRIANGLE *triangle);
1234extern void lwmpoint_free(LWMPOINT *mpt);
1235extern void lwmline_free(LWMLINE *mline);
1236extern void lwmpoly_free(LWMPOLY *mpoly);
1237extern void lwpsurface_free(LWPSURFACE *psurf);
1238extern void lwtin_free(LWTIN *tin);
1239extern void lwcollection_free(LWCOLLECTION *col);
1240extern void lwcircstring_free(LWCIRCSTRING *curve);
1241extern void lwgeom_free(LWGEOM *geom);
1242
1243extern void lwinspected_release(LWGEOM_INSPECTED *inspected); /* TODO: make this deep free... */
1244
1245/*
1246 * The *_release family of functions frees the LWGEOM structures
1247 * surrounding the POINTARRAYs but leaves the POINTARRAYs
1248 * intact. Use these on LWGEOMs that have been de-serialized
1249 * from PG_LWGEOMs. Do not use these on LWGEOMs you have
1250 * constructed yourself, or you will leak lots of memory.
1251 */
1252
1253extern void lwpoint_release(LWPOINT *lwpoint);
1254extern void lwline_release(LWLINE *lwline);
1255extern void lwpoly_release(LWPOLY *lwpoly);
1256extern void lwtriangle_release(LWTRIANGLE *lwtriangle);
1257extern void lwcircstring_release(LWCIRCSTRING *lwcirc);
1258extern void lwmpoint_release(LWMPOINT *lwpoint);
1259extern void lwmline_release(LWMLINE *lwline);
1260extern void lwmpoly_release(LWMPOLY *lwpoly);
1261extern void lwpsurface_release(LWPSURFACE *lwpsurface);
1262extern void lwtin_release(LWTIN *lwtin);
1263extern void lwcollection_release(LWCOLLECTION *lwcollection);
1264extern void lwgeom_release(LWGEOM *lwgeom);
1265
1266
1267/****************************************************************
1268 * utility
1269 ****************************************************************/
1270
1271extern uint32 lw_get_uint32(const uchar *loc);
1272extern int32 lw_get_int32(const uchar *loc);
1273extern void printBOX3D(BOX3D *b);
1274extern void printPA(POINTARRAY *pa);
1275extern void printLWPOINT(LWPOINT *point);
1276extern void printLWLINE(LWLINE *line);
1277extern void printLWPOLY(LWPOLY *poly);
1278extern void printLWTRIANGLE(LWTRIANGLE *triangle);
1279extern void printLWPSURFACE(LWPSURFACE *psurf);
1280extern void printLWTIN(LWTIN *tin);
1281extern void printBYTES(uchar *a, int n);
1282extern void printMULTI(uchar *serialized);
1283extern void printType(uchar str);
1284
1285
1286extern float LWGEOM_Minf(float a, float b);
1287extern float LWGEOM_Maxf(float a, float b);
1288extern double LWGEOM_Mind(double a, double b);
1289extern double LWGEOM_Maxd(double a, double b);
1290
1291extern float  next_float_down(double d);
1292extern float  next_float_up(double d);
1293extern double next_double_down(float d);
1294extern double next_double_up(float d);
1295
1296
1297#define LW_MAX(a,b) ((a) >      (b) ? (a) : (b))
1298#define LW_MIN(a,b) ((a) <= (b) ? (a) : (b))
1299#define LW_ABS(a)   ((a) <      (0) ? -(a) : (a))
1300
1301/* for the measure functions*/
1302#define DIST2D_MAX              -1
1303#define DIST2D_MIN              1
1304
1305/* general utilities */
1306extern double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2);
1307extern double distance2d_pt_seg(const POINT2D *p, const POINT2D *A, const POINT2D *B);
1308extern LWGEOM *lw_dist2d_distancepoint(LWGEOM *lw1, LWGEOM *lw2,int srid,int mode);
1309extern LWGEOM *lw_dist2d_distanceline(LWGEOM *lw1, LWGEOM *lw2,int srid,int mode);
1310extern double lwgeom_mindistance2d(LWGEOM *lw1, LWGEOM *lw2);
1311extern double lwgeom_mindistance2d_tolerance(LWGEOM *lw1, LWGEOM *lw2, double tolerance);
1312extern double lwgeom_maxdistance2d(LWGEOM *lw1, LWGEOM *lw2);
1313extern double lwgeom_maxdistance2d_tolerance(LWGEOM *lw1, LWGEOM *lw2, double tolerance);
1314extern double lwgeom_polygon_area(const LWPOLY *poly);
1315extern double lwgeom_polygon_perimeter(const LWPOLY *poly);
1316extern double lwgeom_polygon_perimeter2d(const LWPOLY *poly);
1317extern double lwgeom_pointarray_length2d(const POINTARRAY *pts);
1318extern double lwgeom_pointarray_length(const POINTARRAY *pts);
1319extern void lwgeom_force2d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
1320extern void lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize);
1321extern void lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize);
1322extern void lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize);
1323extern int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring);
1324extern int pt_in_poly_2d(const POINT2D *p, const LWPOLY *poly);
1325extern int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret);
1326extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
1327extern char ptarray_isccw(const POINTARRAY *pa);
1328extern void lwgeom_reverse(LWGEOM *lwgeom);
1329extern void lwline_reverse(LWLINE *line);
1330extern void lwpoly_reverse(LWPOLY *poly);
1331extern void lwtriangle_reverse(LWTRIANGLE *triangle);
1332extern void lwpoly_forceRHR(LWPOLY *poly);
1333extern void lwtriangle_forceRHR(LWTRIANGLE *triangle);
1334extern void lwgeom_force_rhr(LWGEOM *lwgeom);
1335extern char* lwgeom_summary(const LWGEOM *lwgeom, int offset);
1336extern const char *lwtype_name(int type);
1337extern int ptarray_compute_box2d_p(const POINTARRAY *pa, BOX2DFLOAT4 *result);
1338extern BOX2DFLOAT4 *ptarray_compute_box2d(const POINTARRAY *pa);
1339extern int lwpoint_compute_box2d_p(const LWPOINT *point, BOX2DFLOAT4 *box);
1340extern int lwline_compute_box2d_p(const LWLINE *line, BOX2DFLOAT4 *box);
1341extern int lwpoly_compute_box2d_p(const LWPOLY *poly, BOX2DFLOAT4 *box);
1342extern int lwtriangle_compute_box2d_p(const LWTRIANGLE *triangle, BOX2DFLOAT4 *box);
1343extern int lwcollection_compute_box2d_p(const LWCOLLECTION *col, BOX2DFLOAT4 *box);
1344extern int lwcircstring_compute_box2d_p(const LWCIRCSTRING *curve, BOX2DFLOAT4 *box);
1345extern BOX2DFLOAT4* lwgeom_compute_box2d(const LWGEOM *lwgeom);
1346extern char* lwpoint_to_latlon(const LWPOINT *p, const char *format);
1347extern int lwline_is_closed(LWLINE *line);
1348extern int lwcircstring_is_closed(LWCIRCSTRING *curve);
1349extern int lwcompound_is_closed(LWCOMPOUND *curve);
1350extern int lwpsurface_is_closed(LWPSURFACE *psurface);
1351extern int lwtin_is_closed(LWTIN *tin);
1352
1353
1354extern void interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F);
1355
1356/* return alloced memory */
1357extern BOX2DFLOAT4 *box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2);
1358
1359/* args may overlap ! */
1360extern int box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox);
1361extern int lwgeom_compute_box2d_p(const LWGEOM *lwgeom, BOX2DFLOAT4 *box);
1362void lwgeom_longitude_shift(LWGEOM *lwgeom);
1363
1364
1365/**
1366* @brief Check whether or not a lwgeom is big enough to warrant a bounding box.
1367*
1368* Check whether or not a lwgeom is big enough to warrant a bounding box
1369* when stored in the serialized form on disk. Currently only points are
1370* considered small enough to not require a bounding box, because the
1371* index operations can generate a large number of box-retrieval operations
1372* when scanning keys.
1373*/
1374extern int lwgeom_needs_bbox(const LWGEOM *geom);
1375
1376/**
1377* Count the total number of vertices in any #LWGEOM.
1378*/
1379extern int lwgeom_count_vertices(const LWGEOM *geom);
1380extern int lwgeom_npoints(uchar *serialized);
1381
1382/**
1383* Return true or false depending on whether a geometry has
1384* a valid SRID set.
1385*/
1386extern int lwgeom_has_srid(const LWGEOM *geom);
1387
1388/**
1389* Return true of false depending on whether a geometry is an "empty"
1390* geometry (no vertices members)
1391*/
1392extern int lwgeom_is_empty(const LWGEOM *geom);
1393
1394/**
1395* Return the dimensionality (relating to point/line/poly) of an lwgeom
1396*/
1397extern int lwgeom_dimensionality(LWGEOM *geom);
1398
1399/* Is lwgeom1 geometrically equal to lwgeom2 ? */
1400char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2);
1401char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2);
1402char lwpoint_same(const LWPOINT *p1, const LWPOINT *p2);
1403char lwline_same(const LWLINE *p1, const LWLINE *p2);
1404char lwpoly_same(const LWPOLY *p1, const LWPOLY *p2);
1405char lwtriangle_same(const LWTRIANGLE *p1, const LWTRIANGLE *p2);
1406char lwcollection_same(const LWCOLLECTION *p1, const LWCOLLECTION *p2);
1407
1408
1409/*
1410 * Clone an LWGEOM
1411 * pointarray are not copied.
1412 * BBOXes are copied
1413 */
1414extern LWGEOM *lwgeom_clone(const LWGEOM *lwgeom);
1415extern LWPOINT *lwpoint_clone(const LWPOINT *lwgeom);
1416extern LWLINE *lwline_clone(const LWLINE *lwgeom);
1417extern LWPOLY *lwpoly_clone(const LWPOLY *lwgeom);
1418extern LWTRIANGLE *lwtriangle_clone(const LWTRIANGLE *lwgeom);
1419extern LWCOLLECTION *lwcollection_clone(const LWCOLLECTION *lwgeom);
1420extern LWCIRCSTRING *lwcircstring_clone(const LWCIRCSTRING *curve);
1421extern BOX2DFLOAT4 *box2d_clone(const BOX2DFLOAT4 *lwgeom);
1422extern POINTARRAY *ptarray_clone(const POINTARRAY *ptarray);
1423
1424/*
1425* Geometry constructors. These constructors to not copy the point arrays
1426* passed to them, they just take references, so do not free them out
1427* from underneath the geometries.
1428*/
1429extern LWPOINT *lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point);
1430extern LWLINE *lwline_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points);
1431extern LWCIRCSTRING *lwcircstring_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points);
1432extern LWPOLY *lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox, uint32 nrings, POINTARRAY **points);
1433extern LWTRIANGLE *lwtriangle_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points);
1434extern LWCOLLECTION *lwcollection_construct(uint32 type, int SRID, BOX2DFLOAT4 *bbox, uint32 ngeoms, LWGEOM **geoms);
1435
1436/*
1437* Empty geometry constructors.
1438*/
1439extern LWPOINT* lwpoint_construct_empty(int srid, char hasz, char hasm);
1440extern LWLINE* lwline_construct_empty(int srid, char hasz, char hasm);
1441extern LWPOLY* lwpoly_construct_empty(int srid, char hasz, char hasm);
1442extern LWTRIANGLE* lwtriangle_construct_empty(int srid, char hasz, char hasm);
1443extern LWMPOINT* lwmpoint_construct_empty(int srid, char hasz, char hasm);
1444extern LWMLINE* lwmline_construct_empty(int srid, char hasz, char hasm);
1445extern LWMPOLY* lwmpoly_construct_empty(int srid, char hasz, char hasm);
1446extern LWCOLLECTION* lwcollection_construct_empty(int srid, char hasz, char hasm);
1447
1448
1449/* Other constructors */
1450extern LWPOINT *make_lwpoint2d(int SRID, double x, double y);
1451extern LWPOINT *make_lwpoint3dz(int SRID, double x, double y, double z);
1452extern LWPOINT *make_lwpoint3dm(int SRID, double x, double y, double m);
1453extern LWPOINT *make_lwpoint4d(int SRID, double x, double y, double z, double m);
1454extern LWLINE *lwline_from_lwpointarray(int SRID, uint32 npoints, LWPOINT **points);
1455extern LWLINE *lwline_from_lwmpoint(int SRID, LWMPOINT *mpoint);
1456extern LWLINE *lwline_addpoint(LWLINE *line, LWPOINT *point, uint32 where);
1457extern LWLINE *lwline_removepoint(LWLINE *line, uint32 which);
1458extern void lwline_setPoint4d(LWLINE *line, uint32 which, POINT4D *newpoint);
1459extern LWPOLY *lwpoly_from_lwlines(const LWLINE *shell, uint32 nholes, const LWLINE **holes);
1460extern LWTRIANGLE *lwtriangle_from_lwline(const LWLINE *shell);
1461
1462/* Return a char string with ASCII versionf of type flags */
1463extern const char *lwgeom_typeflags(uchar type);
1464
1465/* Construct an empty pointarray */
1466extern POINTARRAY* ptarray_construct(char hasz, char hasm, uint32 npoints);
1467
1468/* Construct a pointarray, *copying* in the data from ptlist */
1469extern POINTARRAY* ptarray_construct_copy_data(char hasz, char hasm, uint32 npoints, uchar *ptlist);
1470
1471/*
1472 * extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts);
1473 * extern POINTARRAY *ptarray_construct3dz(uint32 npoints, const POINT3DZ *pts);
1474 * extern POINTARRAY *ptarray_construct3dm(uint32 npoints, const POINT3DM *pts);
1475 * extern POINTARRAY *ptarray_construct4d(uint32 npoints, const POINT4D *pts);
1476 */
1477
1478extern POINTARRAY *ptarray_addPoint(const POINTARRAY *pa, uchar *p, size_t pdims,
1479                                    uint32 where);
1480extern POINTARRAY *ptarray_removePoint(POINTARRAY *pa, uint32 where);
1481extern POINTARRAY *ptarray_merge(POINTARRAY *pa1, POINTARRAY *pa2);
1482
1483extern int ptarray_isclosed2d(const POINTARRAY *pa);
1484extern int ptarray_isclosed3d(const POINTARRAY *pa);
1485
1486extern void ptarray_longitude_shift(POINTARRAY *pa);
1487
1488extern int32 lwgeom_nrings_recursive(uchar *serialized);
1489extern void ptarray_reverse(POINTARRAY *pa);
1490extern POINTARRAY* ptarray_flip_coordinates(POINTARRAY *pa);
1491
1492extern POINTARRAY *ptarray_substring(POINTARRAY *, double, double);
1493
1494/*
1495 * Given a point, returns the location of closest point on pointarray
1496 * as a fraction of total length (0: first point -- 1: last point).
1497 *
1498 * If not-null, the third argument will be set to the actual distance
1499 * of the point from the pointarray.
1500 */
1501extern double ptarray_locate_point(POINTARRAY *, POINT2D *, double *);
1502
1503/*
1504 * Write into *ret the coordinates of the closest point on
1505 * segment A-B to the reference input point R
1506 */
1507extern void closest_point_on_segment(POINT2D *R, POINT2D *A, POINT2D *B, POINT2D *ret);
1508
1509extern LWLINE *lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end);
1510extern LWMLINE* lwmline_measured_from_lwmline(const LWMLINE *lwmline, double m_start, double m_end);
1511
1512/*
1513 * Ensure every segment is at most 'dist' long.
1514 * Returned LWGEOM might is unchanged if a POINT.
1515 */
1516extern LWGEOM *lwgeom_segmentize2d(LWGEOM *line, double dist);
1517extern POINTARRAY *ptarray_segmentize2d(const POINTARRAY *ipa, double dist);
1518extern LWLINE *lwline_segmentize2d(LWLINE *line, double dist);
1519extern LWPOLY *lwpoly_segmentize2d(LWPOLY *line, double dist);
1520extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
1521
1522
1523/*
1524 * Export functions
1525 */
1526#define OUT_MAX_DOUBLE 1E15
1527#define OUT_SHOW_DIGS_DOUBLE 20
1528#define OUT_MAX_DOUBLE_PRECISION 15
1529#define OUT_MAX_DIGS_DOUBLE (OUT_SHOW_DIGS_DOUBLE + 2) /* +2 mean add dot and sign */
1530
1531extern char* lwgeom_to_gml2(uchar *geom, char *srs, int precision, const char *prefix);
1532extern char* lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, int is_dims, const char *prefix);
1533extern char* lwgeom_to_kml2(uchar *geom, int precision, const char *prefix);
1534extern char* lwgeom_to_geojson(uchar *geom, char *srs, int precision, int has_bbox);
1535extern char* lwgeom_to_svg(uchar *geom, int precision, int relative);
1536
1537
1538extern POINTARRAY *ptarray_remove_repeated_points(POINTARRAY *in);
1539extern LWGEOM* lwgeom_remove_repeated_points(LWGEOM *in);
1540extern LWGEOM* lwmpoint_remove_repeated_points(LWMPOINT *in);
1541extern LWGEOM* lwline_remove_repeated_points(LWLINE *in);
1542extern LWGEOM* lwcollection_remove_repeated_points(LWCOLLECTION *in);
1543extern LWGEOM* lwpoly_remove_repeated_points(LWPOLY *in);
1544extern char lwtriangle_is_repeated_points(LWTRIANGLE *triangle);
1545
1546extern LWGEOM* lwgeom_flip_coordinates(LWGEOM *in);
1547
1548extern uchar parse_hex(char *str);
1549extern void deparse_hex(uchar str, char *result);
1550
1551/*
1552** New parsing and unparsing functions.
1553*/
1554extern char* lwgeom_to_wkt(const LWGEOM *geom, uchar variant, int precision, size_t *size_out);
1555extern char* lwgeom_to_wkb(const LWGEOM *geom, uchar variant, size_t *size_out);
1556
1557
1558/* Parser check flags */
1559#define PARSER_CHECK_MINPOINTS  1
1560#define PARSER_CHECK_ODD        2
1561#define PARSER_CHECK_CLOSURE    4
1562
1563#define PARSER_CHECK_NONE   0
1564#define PARSER_CHECK_ALL        (PARSER_CHECK_MINPOINTS | PARSER_CHECK_ODD | PARSER_CHECK_CLOSURE)
1565
1566/*
1567 * Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM
1568 */
1569typedef struct struct_lwgeom_parser_result
1570{
1571        const char *wkinput;            /* Copy of pointer to input WKT/WKB */
1572        uchar *serialized_lwgeom;       /* Pointer to serialized LWGEOM */
1573        int size;                       /* Size of serialized LWGEOM in bytes */
1574        const char *message;            /* Error/warning message */
1575        int errlocation;                /* Location of error */
1576}
1577LWGEOM_PARSER_RESULT;
1578
1579/*
1580 * Parser error messages (these must match the message array in lwgparse.c)
1581 */
1582#define PARSER_ERROR_MOREPOINTS     1
1583#define PARSER_ERROR_ODDPOINTS      2
1584#define PARSER_ERROR_UNCLOSED       3
1585#define PARSER_ERROR_MIXDIMS        4
1586#define PARSER_ERROR_INVALIDGEOM    5
1587#define PARSER_ERROR_INVALIDWKBTYPE 6
1588#define PARSER_ERROR_INCONTINUOUS   7
1589#define PARSER_ERROR_TRIANGLEPOINTS 8
1590
1591
1592
1593/*
1594 * Unparser result structure: returns the result of attempting to convert LWGEOM to (E)WKT/(E)WKB
1595 */
1596typedef struct struct_lwgeom_unparser_result
1597{
1598        uchar *serialized_lwgeom;       /* Copy of pointer to input serialized LWGEOM */
1599        char *wkoutput;                 /* Pointer to WKT or WKB output */
1600        int size;                       /* Size of serialized LWGEOM in bytes */
1601        const char *message;            /* Error/warning message */
1602        int errlocation;                /* Location of error */
1603}
1604LWGEOM_UNPARSER_RESULT;
1605
1606/*
1607 * Unparser error messages (these must match the message array in lwgunparse.c)
1608 */
1609#define UNPARSER_ERROR_MOREPOINTS       1
1610#define UNPARSER_ERROR_ODDPOINTS        2
1611#define UNPARSER_ERROR_UNCLOSED         3
1612
1613
1614/* Parser access routines */
1615extern char *lwgeom_to_ewkt(LWGEOM *lwgeom, int flags);
1616extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, int flags, uint32 byteorder);
1617extern LWGEOM *lwgeom_from_ewkb(uchar *ewkb, int flags, size_t ewkblen);
1618extern LWGEOM *lwgeom_from_ewkt(char *ewkt, int flags);
1619extern uchar *lwgeom_to_ewkb(LWGEOM *lwgeom, int flags, char byteorder, size_t *ewkblen);
1620
1621extern int serialized_lwgeom_to_ewkt(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar *serialized, int flags);
1622extern int serialized_lwgeom_from_ewkt(LWGEOM_PARSER_RESULT *lwg_parser_result, char *wkt_input, int flags);
1623extern int serialized_lwgeom_to_hexwkb(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar *serialized, int flags, uint32 byteorder);
1624extern int serialized_lwgeom_from_hexwkb(LWGEOM_PARSER_RESULT *lwg_parser_result, char *hexwkb_input, int flags);
1625extern int serialized_lwgeom_to_ewkb(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar *serialized, int flags, uint32 byteorder);
1626
1627extern void *lwalloc(size_t size);
1628extern void *lwrealloc(void *mem, size_t size);
1629extern void lwfree(void *mem);
1630
1631/* Utilities */
1632extern void trim_trailing_zeros(char *num);
1633extern char *lwmessage_truncate(char *str, int startpos, int endpos, int maxlength, int truncdirection);
1634
1635/* Machine endianness */
1636#define XDR 0
1637#define NDR 1
1638extern char getMachineEndian(void);
1639
1640void errorIfSRIDMismatch(int srid1, int srid2);
1641
1642
1643/*******************************************************************************
1644 * SQLMM internal functions - TODO: Move into separate header files
1645 ******************************************************************************/
1646
1647int has_arc(const LWGEOM *geom);
1648double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
1649LWGEOM *lwgeom_segmentize(LWGEOM *geom, uint32 perQuad);
1650LWGEOM *lwgeom_desegmentize(LWGEOM *geom);
1651extern double lwgeom_curvepolygon_area(LWCURVEPOLY *curvepoly);
1652double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
1653
1654#endif /* !defined _LIBLWGEOM_H  */
1655
Note: See TracBrowser for help on using the repository browser.