/********************************************************************** * * rttopo - topology library * http://git.osgeo.org/gitea/rttopo/librttopo * * rttopo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * rttopo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rttopo. If not, see . * ********************************************************************** * * Copyright 2011-2016 Sandro Santilli * Copyright 2011 Paul Ramsey * Copyright 2007-2008 Mark Cave-Ayland * Copyright 2001-2006 Refractions Research Inc. * **********************************************************************/ #ifndef _LIBRTGEOM_H #define _LIBRTGEOM_H 1 #define GEOS_USE_ONLY_R_API 1 #include #include #include #include /** * @file librttopo_geom.h * * This library is the generic geometry handling section of librttopo. * The geometry objects, constructors, destructors, and a set of spatial * processing functions, are implemented here. * * Programs using this library can install their custom memory managers * passing them to the rtgeom_init function, and their custom message * handlers using the appropriate rtgeom_set_*_logger functions. */ /** * Return types for functions with status returns. */ #define RT_TRUE 1 #define RT_FALSE 0 #define RT_UNKNOWN 2 #define RT_FAILURE 0 #define RT_SUCCESS 1 /** * RTRTTYPE numbers */ #define RTPOINTTYPE 1 #define RTLINETYPE 2 #define RTPOLYGONTYPE 3 #define RTMULTIPOINTTYPE 4 #define RTMULTILINETYPE 5 #define RTMULTIPOLYGONTYPE 6 #define RTCOLLECTIONTYPE 7 #define RTCIRCSTRINGTYPE 8 #define RTCOMPOUNDTYPE 9 #define RTCURVEPOLYTYPE 10 #define RTMULTICURVETYPE 11 #define RTMULTISURFACETYPE 12 #define RTPOLYHEDRALSURFACETYPE 13 #define RTTRIANGLETYPE 14 #define RTTINTYPE 15 #define RTNUMTYPES 16 /** * Flags applied in EWKB to indicate Z/M dimensions and * presence/absence of SRID and bounding boxes */ #define RTWKBZOFFSET 0x80000000 #define RTWKBMOFFSET 0x40000000 #define RTWKBSRIDFLAG 0x20000000 #define RTWKBBBOXFLAG 0x10000000 /** Ordinate names */ typedef enum RTORD_T { RTORD_X = 0, RTORD_Y = 1, RTORD_Z = 2, RTORD_M = 3 } RTORD; /** * Macros for manipulating the 'flags' byte. A uint8_t used as follows: * ---RGBMZ * Three unused bits, followed by ReadOnly, Geodetic, HasBBox, HasM and HasZ flags. */ #define RTFLAGS_GET_Z(flags) ((flags) & 0x01) #define RTFLAGS_GET_M(flags) (((flags) & 0x02)>>1) #define RTFLAGS_GET_BBOX(flags) (((flags) & 0x04)>>2) #define RTFLAGS_GET_GEODETIC(flags) (((flags) & 0x08)>>3) #define RTFLAGS_GET_READONLY(flags) (((flags) & 0x10)>>4) #define RTFLAGS_GET_SOLID(flags) (((flags) & 0x20)>>5) #define RTFLAGS_SET_Z(flags, value) ((flags) = (value) ? ((flags) | 0x01) : ((flags) & 0xFE)) #define RTFLAGS_SET_M(flags, value) ((flags) = (value) ? ((flags) | 0x02) : ((flags) & 0xFD)) #define RTFLAGS_SET_BBOX(flags, value) ((flags) = (value) ? ((flags) | 0x04) : ((flags) & 0xFB)) #define RTFLAGS_SET_GEODETIC(flags, value) ((flags) = (value) ? ((flags) | 0x08) : ((flags) & 0xF7)) #define RTFLAGS_SET_READONLY(flags, value) ((flags) = (value) ? ((flags) | 0x10) : ((flags) & 0xEF)) #define RTFLAGS_SET_SOLID(flags, value) ((flags) = (value) ? ((flags) | 0x20) : ((flags) & 0xDF)) #define RTFLAGS_NDIMS(flags) (2 + RTFLAGS_GET_Z(flags) + RTFLAGS_GET_M(flags)) #define RTFLAGS_GET_ZM(flags) (RTFLAGS_GET_M(flags) + RTFLAGS_GET_Z(flags) * 2) #define RTFLAGS_NDIMS_BOX(flags) (RTFLAGS_GET_GEODETIC(flags) ? 3 : RTFLAGS_NDIMS(flags)) /** * Macros for manipulating the 'typemod' int. An int32_t used as follows: * Plus/minus = Top bit. * Spare bits = Next 2 bits. * SRID = Next 21 bits. * RTTYPE = Next 6 bits. * ZM Flags = Bottom 2 bits. */ #define RTTYPMOD_GET_SRID(typmod) ((((typmod) & 0x1FFFFF00)<<3)>>11) #define RTTYPMOD_SET_SRID(typmod, srid) ((typmod) = (((typmod) & 0xE00000FF) | ((srid & 0x001FFFFF)<<8))) #define RTTYPMOD_GET_TYPE(typmod) ((typmod & 0x000000FC)>>2) #define RTTYPMOD_SET_TYPE(typmod, type) ((typmod) = (typmod & 0xFFFFFF03) | ((type & 0x0000003F)<<2)) #define RTTYPMOD_GET_Z(typmod) ((typmod & 0x00000002)>>1) #define RTTYPMOD_SET_Z(typmod) ((typmod) = typmod | 0x00000002) #define RTTYPMOD_GET_M(typmod) (typmod & 0x00000001) #define RTTYPMOD_SET_M(typmod) ((typmod) = typmod | 0x00000001) #define RTTYPMOD_GET_NDIMS(typmod) (2+RTTYPMOD_GET_Z(typmod)+RTTYPMOD_GET_M(typmod)) /** * Maximum allowed SRID value in serialized geometry. * Currently we are using 21 bits (2097152) of storage for SRID. */ #define SRID_MAXIMUM 999999 /** * Maximum valid SRID value for the user * We reserve 1000 values for internal use */ #define SRID_USER_MAXIMUM 998999 /** Unknown SRID value */ #define SRID_UNKNOWN 0 #define SRID_IS_UNKNOWN(x) ((int)x<=0) /* ** EPSG WGS84 geographics, OGC standard default SRS, better be in ** the SPATIAL_REF_SYS table! */ #define SRID_DEFAULT 4326 #ifndef __GNUC__ # define __attribute__(x) #endif /** * RT library context */ typedef struct RTCTX_T RTCTX; /** * Global functions for memory/logging handlers. */ typedef void* (*rtallocator)(size_t size); typedef void* (*rtreallocator)(void *mem, size_t size); typedef void (*rtfreeor)(void* mem); typedef void (*rtreporter)(const char* fmt, va_list ap, void *arg) __attribute__ (( format(printf, 1, 0) )); typedef void (*rtdebuglogger)(int level, const char* fmt, va_list ap, void *arg) __attribute__ (( format(printf, 2,0) )); /** * Initialize the library with custom memory management functions * you want your application to use. * @param allocator function for allocating memory, * or NULL to use the default * @param reallocator function for reallocating memory, * or NULL to use the default * @param freeor function for release memory, * or NULL to use the default * @return a context object to use in subsequent calls * to the library * @see rtgeom_finish to destroy the created context * @ingroup system */ RTCTX *rtgeom_init(rtallocator allocator, rtreallocator reallocator, rtfreeor freeor); /** * Deinitialize the library, releasing all context memory * * @param ctx a context returned by rtgeom_init * */ void rtgeom_finish(RTCTX *ctx); /** Return rtgeom version string (not to be freed) */ const char* rtgeom_version(void); /** * This functions are called by programs which want to set up * custom handling for error reporting */ extern void rtgeom_set_error_logger(RTCTX *ctx, rtreporter logger, void *arg); extern void rtgeom_set_notice_logger(RTCTX *ctx, rtreporter logger, void *arg); extern void rtgeom_set_debug_logger(RTCTX *ctx, rtdebuglogger logger, void *arg); /** * Request interruption of any running code * * Safe for use from signal handlers * * Interrupted code will (as soon as it finds out * to be interrupted) cleanup and return as soon as possible. * * The return value from interrupted code is undefined, * it is the caller responsibility to not take it in consideration. * */ extern void rtgeom_request_interrupt(const RTCTX *ctx); /** * Cancel any interruption request */ extern void rtgeom_cancel_interrupt(const RTCTX *ctx); /** * Install a callback to be called periodically during * algorithm execution. Mostly only needed on WIN32 to * dispatch queued signals. * * The callback is invoked before checking for interrupt * being requested, so you can request interruption from * the callback, if you want (see rtgeom_request_interrupt). * */ typedef void (rtinterrupt_callback)(); extern rtinterrupt_callback *rtgeom_register_interrupt_callback(const RTCTX *ctx, rtinterrupt_callback *); /******************************************************************/ typedef struct { double afac, bfac, cfac, dfac, efac, ffac, gfac, hfac, ifac, xoff, yoff, zoff; } RTAFFINE; /****************************************************************** * RTGBOX structure. * We include the flags (information about dimensinality), * so we don't have to constantly pass them * into functions that use the RTGBOX. */ typedef struct { uint8_t flags; double xmin; double xmax; double ymin; double ymax; double zmin; double zmax; double mmin; double mmax; } RTGBOX; /****************************************************************** * SPHEROID * * Standard definition of an ellipsoid (what wkt calls a spheroid) * f = (a-b)/a * e_sq = (a*a - b*b)/(a*a) * b = a - fa */ typedef struct { double a; /* semimajor axis */ double b; /* semiminor axis b = (a - fa) */ double f; /* flattening f = (a-b)/a */ double e; /* eccentricity (first) */ double e_sq; /* eccentricity squared (first) e_sq = (a*a-b*b)/(a*a) */ double radius; /* spherical average radius = (2*a+b)/3 */ char name[20]; /* name of ellipse */ } SPHEROID; /****************************************************************** * RTPOINT2D, POINT3D, RTPOINT3DM, RTPOINT4D */ typedef struct { double x, y; } RTPOINT2D; typedef struct { double x, y, z; } RTPOINT3DZ; typedef struct { double x, y, z; } POINT3D; typedef struct { double x, y, m; } RTPOINT3DM; typedef struct { double x, y, z, m; } RTPOINT4D; /****************************************************************** * RTPOINTARRAY * Point array abstracts a lot of the complexity of points and point lists. * It handles 2d/3d translation * (2d points converted to 3d will have z=0 or NaN) * DO NOT MIX 2D and 3D POINTS! EVERYTHING* is either one or the other */ typedef struct { /* Array of POINT 2D, 3D or 4D, possibly missaligned. */ uint8_t *serialized_pointlist; /* Use RTFLAGS_* macros to handle */ uint8_t flags; int npoints; /* how many points we are currently storing */ int maxpoints; /* how many points we have space for in serialized_pointlist */ } RTPOINTARRAY; /****************************************************************** * GSERIALIZED */ typedef struct { uint32_t size; /* For PgSQL use only, use VAR* macros to manipulate. */ uint8_t srid[3]; /* 24 bits of SRID */ uint8_t flags; /* HasZ, HasM, HasBBox, IsGeodetic, IsReadOnly */ uint8_t data[1]; /* See gserialized.txt */ } GSERIALIZED; /****************************************************************** * RTGEOM (any geometry type) * * Abstract type, note that 'type', 'bbox' and 'srid' are available in * all geometry variants. */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; void *data; } RTGEOM; /* RTPOINTYPE */ typedef struct { uint8_t type; /* RTPOINTTYPE */ uint8_t flags; RTGBOX *bbox; int32_t srid; RTPOINTARRAY *point; /* hide 2d/3d (this will be an array of 1 point) */ } RTPOINT; /* "light-weight point" */ /* RTLINETYPE */ typedef struct { uint8_t type; /* RTLINETYPE */ uint8_t flags; RTGBOX *bbox; int32_t srid; RTPOINTARRAY *points; /* array of POINT3D */ } RTLINE; /* "light-weight line" */ /* TRIANGLE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; RTPOINTARRAY *points; } RTTRIANGLE; /* RTCIRCSTRINGTYPE */ typedef struct { uint8_t type; /* RTCIRCSTRINGTYPE */ uint8_t flags; RTGBOX *bbox; int32_t srid; RTPOINTARRAY *points; /* array of POINT(3D/3DM) */ } RTCIRCSTRING; /* "light-weight circularstring" */ /* RTPOLYGONTYPE */ typedef struct { uint8_t type; /* RTPOLYGONTYPE */ uint8_t flags; RTGBOX *bbox; int32_t srid; int nrings; /* how many rings we are currently storing */ int maxrings; /* how many rings we have space for in **rings */ RTPOINTARRAY **rings; /* list of rings (list of points) */ } RTPOLY; /* "light-weight polygon" */ /* RTMULTIPOINTTYPE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTPOINT **geoms; } RTMPOINT; /* RTMULTILINETYPE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTLINE **geoms; } RTMLINE; /* RTMULTIPOLYGONTYPE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTPOLY **geoms; } RTMPOLY; /* RTCOLLECTIONTYPE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTGEOM **geoms; } RTCOLLECTION; /* RTCOMPOUNDTYPE */ typedef struct { uint8_t type; /* RTCOMPOUNDTYPE */ uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTGEOM **geoms; } RTCOMPOUND; /* "light-weight compound line" */ /* RTCURVEPOLYTYPE */ typedef struct { uint8_t type; /* RTCURVEPOLYTYPE */ uint8_t flags; RTGBOX *bbox; int32_t srid; int nrings; /* how many rings we are currently storing */ int maxrings; /* how many rings we have space for in **rings */ RTGEOM **rings; /* list of rings (list of points) */ } RTCURVEPOLY; /* "light-weight polygon" */ /* MULTICURVE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTGEOM **geoms; } RTMCURVE; /* RTMULTISURFACETYPE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTGEOM **geoms; } RTMSURFACE; /* RTPOLYHEDRALSURFACETYPE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTPOLY **geoms; } RTPSURFACE; /* RTTINTYPE */ typedef struct { uint8_t type; uint8_t flags; RTGBOX *bbox; int32_t srid; int ngeoms; /* how many geometries we are currently storing */ int maxgeoms; /* how many geometries we have space for in **geoms */ RTTRIANGLE **geoms; } RTTIN; /* Casts RTGEOM->RT* (return NULL if cast is illegal) */ extern RTMPOLY *rtgeom_as_rtmpoly(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTMLINE *rtgeom_as_rtmline(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTMPOINT *rtgeom_as_rtmpoint(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTCOLLECTION *rtgeom_as_rtcollection(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTPOLY *rtgeom_as_rtpoly(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTLINE *rtgeom_as_rtline(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTPOINT *rtgeom_as_rtpoint(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTCIRCSTRING *rtgeom_as_rtcircstring(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTCURVEPOLY *rtgeom_as_rtcurvepoly(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTCOMPOUND *rtgeom_as_rtcompound(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTPSURFACE *rtgeom_as_rtpsurface(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTTRIANGLE *rtgeom_as_rttriangle(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTTIN *rtgeom_as_rttin(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTGEOM *rtgeom_as_multi(const RTCTX *ctx, const RTGEOM *rtgeom); extern RTGEOM *rtgeom_as_curve(const RTCTX *ctx, const RTGEOM *rtgeom); /* Casts RT*->RTGEOM (artays cast) */ extern RTGEOM *rttin_as_rtgeom(const RTCTX *ctx, const RTTIN *obj); extern RTGEOM *rttriangle_as_rtgeom(const RTCTX *ctx, const RTTRIANGLE *obj); extern RTGEOM *rtpsurface_as_rtgeom(const RTCTX *ctx, const RTPSURFACE *obj); extern RTGEOM *rtmpoly_as_rtgeom(const RTCTX *ctx, const RTMPOLY *obj); extern RTGEOM *rtmline_as_rtgeom(const RTCTX *ctx, const RTMLINE *obj); extern RTGEOM *rtmpoint_as_rtgeom(const RTCTX *ctx, const RTMPOINT *obj); extern RTGEOM *rtcollection_as_rtgeom(const RTCTX *ctx, const RTCOLLECTION *obj); extern RTGEOM *rtcircstring_as_rtgeom(const RTCTX *ctx, const RTCIRCSTRING *obj); extern RTGEOM *rtcompound_as_rtgeom(const RTCTX *ctx, const RTCOMPOUND *obj); extern RTGEOM *rtcurvepoly_as_rtgeom(const RTCTX *ctx, const RTCURVEPOLY *obj); extern RTGEOM *rtpoly_as_rtgeom(const RTCTX *ctx, const RTPOLY *obj); extern RTGEOM *rtline_as_rtgeom(const RTCTX *ctx, const RTLINE *obj); extern RTGEOM *rtpoint_as_rtgeom(const RTCTX *ctx, const RTPOINT *obj); extern RTCOLLECTION* rtcollection_add_rtgeom(const RTCTX *ctx, RTCOLLECTION *col, const RTGEOM *geom); extern RTMPOINT* rtmpoint_add_rtpoint(const RTCTX *ctx, RTMPOINT *mobj, const RTPOINT *obj); extern RTMLINE* rtmline_add_rtline(const RTCTX *ctx, RTMLINE *mobj, const RTLINE *obj); extern RTMPOLY* rtmpoly_add_rtpoly(const RTCTX *ctx, RTMPOLY *mobj, const RTPOLY *obj); extern RTPSURFACE* rtpsurface_add_rtpoly(const RTCTX *ctx, RTPSURFACE *mobj, const RTPOLY *obj); extern RTTIN* rttin_add_rttriangle(const RTCTX *ctx, RTTIN *mobj, const RTTRIANGLE *obj); /*********************************************************************** ** Utility functions for flag byte and srid_flag integer. */ /** * Construct a new flags char. */ extern uint8_t gflags(const RTCTX *ctx, int hasz, int hasm, int geodetic); /** * Extract the geometry type from the serialized form (it hides in * the anonymous data area, so this is a handy function). */ extern uint32_t gserialized_get_type(const RTCTX *ctx, const GSERIALIZED *g); /** * Returns the size in bytes to read from toast to get the basic * information from a geometry: GSERIALIZED struct, bbox and type */ extern uint32_t gserialized_max_header_size(const RTCTX *ctx); /** * Extract the SRID from the serialized form (it is packed into * three bytes so this is a handy function). */ extern int32_t gserialized_get_srid(const RTCTX *ctx, const GSERIALIZED *g); /** * Write the SRID into the serialized form (it is packed into * three bytes so this is a handy function). */ extern void gserialized_set_srid(const RTCTX *ctx, GSERIALIZED *g, int32_t srid); /** * Check if a #GSERIALIZED is empty without deserializing first. * Only checks if the number of elements of the parent geometry * is zero, will not catch collections of empty, eg: * GEOMETRYCOLLECTION(POINT EMPTY) */ extern int gserialized_is_empty(const RTCTX *ctx, const GSERIALIZED *g); /** * Check if a #GSERIALIZED has a bounding box without deserializing first. */ extern int gserialized_has_bbox(const RTCTX *ctx, const GSERIALIZED *gser); /** * Check if a #GSERIALIZED has a Z ordinate. */ extern int gserialized_has_z(const RTCTX *ctx, const GSERIALIZED *gser); /** * Check if a #GSERIALIZED has an M ordinate. */ extern int gserialized_has_m(const RTCTX *ctx, const GSERIALIZED *gser); /** * Check if a #GSERIALIZED is a geography. */ extern int gserialized_is_geodetic(const RTCTX *ctx, const GSERIALIZED *gser); /** * Return a number indicating presence of Z and M coordinates. * 0 = None, 1 = M, 2 = Z, 3 = ZM */ extern int gserialized_get_zm(const RTCTX *ctx, const GSERIALIZED *gser); /** * Return the number of dimensions (2, 3, 4) in a geometry */ extern int gserialized_ndims(const RTCTX *ctx, const GSERIALIZED *gser); /** * Call this function to drop BBOX and SRID * from RTGEOM. If RTGEOM type is *not* flagged * with the HASBBOX flag and has a bbox, it * will be released. */ extern void rtgeom_drop_bbox(const RTCTX *ctx, RTGEOM *rtgeom); extern void rtgeom_drop_srid(const RTCTX *ctx, RTGEOM *rtgeom); /** * Compute a bbox if not already computed * * After calling this function rtgeom->bbox is only * NULL if the geometry is empty. */ extern void rtgeom_add_bbox(const RTCTX *ctx, RTGEOM *rtgeom); /** * Compute a box for geom and all sub-geometries, if not already computed */ extern void rtgeom_add_bbox_deep(const RTCTX *ctx, RTGEOM *rtgeom, RTGBOX *gbox); /** * Get a non-empty geometry bounding box, computing and * caching it if not already there * * NOTE: empty geometries don't have a bounding box so * you'd still get a NULL for them. */ extern const RTGBOX *rtgeom_get_bbox(const RTCTX *ctx, const RTGEOM *rtgeom); /** * Determine whether a RTGEOM can contain sub-geometries or not */ extern int rtgeom_is_collection(const RTCTX *ctx, const RTGEOM *rtgeom); /******************************************************************/ /* Functions that work on type numbers */ /** * Determine whether a type number is a collection or not */ extern int rttype_is_collection(const RTCTX *ctx, uint8_t type); /** * Given an rttype number, what homogeneous collection can hold it? */ extern int rttype_get_collectiontype(const RTCTX *ctx, uint8_t type); /** * Return the type name string associated with a type number * (e.g. Point, LineString, Polygon) */ extern const char *rttype_name(const RTCTX *ctx, uint8_t type); /******************************************************************/ /* * copies a point from the point array into the parameter point * will set point's z=0 (or NaN) if pa is 2d * will set point's m=0 (or NaN) if pa is 3d or 2d * NOTE: point is a real POINT3D *not* a pointer */ extern RTPOINT4D rt_getPoint4d(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); /* * copies a point from the point array into the parameter point * will set point's z=0 (or NaN) if pa is 2d * will set point's m=0 (or NaN) if pa is 3d or 2d * NOTE: this will modify the point4d pointed to by 'point'. */ extern int rt_getPoint4d_p(const RTCTX *ctx, const RTPOINTARRAY *pa, int n, RTPOINT4D *point); /* * copies a point from the point array into the parameter point * will set point's z=0 (or NaN) if pa is 2d * NOTE: point is a real POINT3D *not* a pointer */ extern RTPOINT3DZ rt_getPoint3dz(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); extern RTPOINT3DM rt_getPoint3dm(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); /* * copies a point from the point array into the parameter point * will set point's z=0 (or NaN) if pa is 2d * NOTE: this will modify the point3d pointed to by 'point'. */ extern int rt_getPoint3dz_p(const RTCTX *ctx, const RTPOINTARRAY *pa, int n, RTPOINT3DZ *point); extern int rt_getPoint3dm_p(const RTCTX *ctx, const RTPOINTARRAY *pa, int n, RTPOINT3DM *point); /* * copies a point from the point array into the parameter point * z value (if present is not returned) * NOTE: point is a real POINT3D *not* a pointer */ extern RTPOINT2D rt_getPoint2d(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); /* * copies a point from the point array into the parameter point * z value (if present is not returned) * NOTE: this will modify the point2d pointed to by 'point'. */ extern int rt_getPoint2d_p(const RTCTX *ctx, const RTPOINTARRAY *pa, int n, RTPOINT2D *point); /** * Returns a RTPOINT2D pointer into the RTPOINTARRAY serialized_ptlist, * suitable for reading from. This is very high performance * and declared const because you aren't allowed to muck with the * values, only read them. */ extern const RTPOINT2D* rt_getPoint2d_cp(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); /** * Returns a RTPOINT3DZ pointer into the RTPOINTARRAY serialized_ptlist, * suitable for reading from. This is very high performance * and declared const because you aren't allowed to muck with the * values, only read them. */ extern const RTPOINT3DZ* rt_getPoint3dz_cp(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); /** * Returns a RTPOINT4D pointer into the RTPOINTARRAY serialized_ptlist, * suitable for reading from. This is very high performance * and declared const because you aren't allowed to muck with the * values, only read them. */ extern const RTPOINT4D* rt_getPoint4d_cp(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); /* * set point N to the given value * NOTE that the pointarray can be of any * dimension, the appropriate ordinate values * will be extracted from it * * N must be a valid point index */ extern void ptarray_set_point4d(const RTCTX *ctx, RTPOINTARRAY *pa, int n, const RTPOINT4D *p4d); /* * get a pointer to nth point of a RTPOINTARRAY * You'll need to cast it to appropriate dimensioned point. * Note that if you cast to a higher dimensional point you'll * possibly corrupt the RTPOINTARRAY. * * WARNING: Don't cast this to a POINT ! * it would not be reliable due to memory alignment constraints */ extern uint8_t *rt_getPoint_internal(const RTCTX *ctx, const RTPOINTARRAY *pa, int n); /* * size of point represeneted in the RTPOINTARRAY * 16 for 2d, 24 for 3d, 32 for 4d */ extern int ptarray_point_size(const RTCTX *ctx, const RTPOINTARRAY *pa); /** * Construct an empty pointarray, allocating storage and setting * the npoints, but not filling in any information. Should be used in conjunction * with ptarray_set_point4d to fill in the information in the array. */ extern RTPOINTARRAY* ptarray_construct(const RTCTX *ctx, char hasz, char hasm, uint32_t npoints); /** * Construct a new #RTPOINTARRAY, copying in the data from ptlist */ extern RTPOINTARRAY* ptarray_construct_copy_data(const RTCTX *ctx, char hasz, char hasm, uint32_t npoints, const uint8_t *ptlist); /** * Construct a new #RTPOINTARRAY, referencing to the data from ptlist */ extern RTPOINTARRAY* ptarray_construct_reference_data(const RTCTX *ctx, char hasz, char hasm, uint32_t npoints, uint8_t *ptlist); /** * Create a new #RTPOINTARRAY with no points. Allocate enough storage * to hold maxpoints vertices before having to reallocate the storage * area. */ extern RTPOINTARRAY* ptarray_construct_empty(const RTCTX *ctx, char hasz, char hasm, uint32_t maxpoints); /** * Append a point to the end of an existing #RTPOINTARRAY * If allow_duplicate is RT_TRUE, then a duplicate point will * not be added. */ extern int ptarray_append_point(const RTCTX *ctx, RTPOINTARRAY *pa, const RTPOINT4D *pt, int allow_duplicates); /** * Append a #RTPOINTARRAY, pa2 to the end of an existing #RTPOINTARRAY, pa1. * * If gap_tolerance is >= 0 then the end point of pa1 will be checked for * being within gap_tolerance 2d distance from start point of pa2 or an * error will be raised and RT_FAILURE returned. * A gap_tolerance < 0 disables the check. * * If end point of pa1 and start point of pa2 are 2d-equal, then pa2 first * point will not be appended. */ extern int ptarray_append_ptarray(const RTCTX *ctx, RTPOINTARRAY *pa1, RTPOINTARRAY *pa2, double gap_tolerance); /** * Insert a point into an existing #RTPOINTARRAY. Zero * is the index of the start of the array. */ extern int ptarray_insert_point(const RTCTX *ctx, RTPOINTARRAY *pa, const RTPOINT4D *p, int where); /** * Remove a point from an existing #RTPOINTARRAY. Zero * is the index of the start of the array. */ extern int ptarray_remove_point(const RTCTX *ctx, RTPOINTARRAY *pa, int where); /** * @brief Add a point in a pointarray. * * @param pa the source RTPOINTARRAY * @param p the point to add * @param pdims number of ordinates in p (2..4) * @param where to insert the point. 0 prepends, pa->npoints appends * * @returns a newly constructed RTPOINTARRAY using a newly allocated buffer * for the actual points, or NULL on error. */ extern RTPOINTARRAY *ptarray_addPoint(const RTCTX *ctx, const RTPOINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where); /** * @brief Remove a point from a pointarray. * @param which - is the offset (starting at 0) * @return #RTPOINTARRAY is newly allocated */ extern RTPOINTARRAY *ptarray_removePoint(const RTCTX *ctx, RTPOINTARRAY *pa, uint32_t where); /** * @brief Merge two given RTPOINTARRAY and returns a pointer * on the new aggregate one. * Warning: this function free the two inputs RTPOINTARRAY * @return #RTPOINTARRAY is newly allocated */ extern RTPOINTARRAY *ptarray_merge(const RTCTX *ctx, RTPOINTARRAY *pa1, RTPOINTARRAY *pa2); extern int ptarray_is_closed(const RTCTX *ctx, const RTPOINTARRAY *pa); extern int ptarray_is_closed_2d(const RTCTX *ctx, const RTPOINTARRAY *pa); extern int ptarray_is_closed_3d(const RTCTX *ctx, const RTPOINTARRAY *pa); extern int ptarray_is_closed_z(const RTCTX *ctx, const RTPOINTARRAY *pa); extern void ptarray_longitude_shift(const RTCTX *ctx, RTPOINTARRAY *pa); extern int ptarray_isccw(const RTCTX *ctx, const RTPOINTARRAY *pa); extern void ptarray_reverse(const RTCTX *ctx, RTPOINTARRAY *pa); extern RTPOINTARRAY* ptarray_flip_coordinates(const RTCTX *ctx, RTPOINTARRAY *pa); /** * @d1 start location (distance from start / total distance) * @d2 end location (distance from start / total distance) * @param tolerance snap to vertices at locations < tolerance away from given ones */ extern RTPOINTARRAY *ptarray_substring(const RTCTX *ctx, RTPOINTARRAY *pa, double d1, double d2, double tolerance); /** * Strip out the Z/M components of an #RTGEOM */ extern RTGEOM* rtgeom_force_2d(const RTCTX *ctx, const RTGEOM *geom); extern RTGEOM* rtgeom_force_3dz(const RTCTX *ctx, const RTGEOM *geom); extern RTGEOM* rtgeom_force_3dm(const RTCTX *ctx, const RTGEOM *geom); extern RTGEOM* rtgeom_force_4d(const RTCTX *ctx, const RTGEOM *geom); extern RTGEOM* rtgeom_simplify(const RTCTX *ctx, const RTGEOM *igeom, double dist, int preserve_collapsed); extern RTGEOM* rtgeom_set_effective_area(const RTCTX *ctx, const RTGEOM *igeom, int set_area, double area); /* * Force to use SFS 1.1 geometry type * (rather than SFS 1.2 and/or SQL/MM) */ extern RTGEOM* rtgeom_force_sfs(const RTCTX *ctx, RTGEOM *geom, int version); /*-------------------------------------------------------- * all the base types (point/line/polygon) will have a * basic constructor, basic de-serializer, basic serializer, * bounding box finder and (TODO) serialized form size finder. *--------------------------------------------------------*/ /* * convenience functions to hide the RTPOINTARRAY */ extern int rtpoint_getPoint2d_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT2D *out); extern int rtpoint_getPoint3dz_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT3DZ *out); extern int rtpoint_getPoint3dm_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT3DM *out); extern int rtpoint_getPoint4d_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT4D *out); /****************************************************************** * RTLINE functions ******************************************************************/ /** * Add a RTPOINT to an RTLINE */ extern int rtline_add_rtpoint(const RTCTX *ctx, RTLINE *line, RTPOINT *point, int where); /****************************************************************** * RTPOLY functions ******************************************************************/ /** * Add a ring, allocating extra space if necessary. The polygon takes * ownership of the passed point array. */ extern int rtpoly_add_ring(const RTCTX *ctx, RTPOLY *poly, RTPOINTARRAY *pa); /** * Add a ring, allocating extra space if necessary. The curvepolygon takes * ownership of the passed point array. */ extern int rtcurvepoly_add_ring(const RTCTX *ctx, RTCURVEPOLY *poly, RTGEOM *ring); /** * Add a component, allocating extra space if necessary. The compoundcurve * takes owership of the passed geometry. */ extern int rtcompound_add_rtgeom(const RTCTX *ctx, RTCOMPOUND *comp, RTGEOM *geom); /** * Construct an equivalent compound curve from a linestring. * Compound curves can have linear components, so this works fine */ extern RTCOMPOUND* rtcompound_construct_from_rtline(const RTCTX *ctx, const RTLINE *rtpoly); /** * Construct an equivalent curve polygon from a polygon. Curve polygons * can have linear rings as their rings, so this works fine (in theory?) */ extern RTCURVEPOLY* rtcurvepoly_construct_from_rtpoly(const RTCTX *ctx, RTPOLY *rtpoly); /****************************************************************** * RTGEOM functions ******************************************************************/ extern int rtcollection_ngeoms(const RTCTX *ctx, const RTCOLLECTION *col); /* Given a generic geometry/collection, return the "simplest" form. */ extern RTGEOM *rtgeom_homogenize(const RTCTX *ctx, const RTGEOM *geom); /****************************************************************** * RTMULTIx and RTCOLLECTION functions ******************************************************************/ RTGEOM *rtcollection_getsubgeom(const RTCTX *ctx, RTCOLLECTION *col, int gnum); RTCOLLECTION* rtcollection_extract(const RTCTX *ctx, RTCOLLECTION *col, int type); /****************************************************************** * SERIALIZED FORM functions ******************************************************************/ /** * Set the SRID on an RTGEOM * For collections, only the parent gets an SRID, all * the children get SRID_UNKNOWN. */ extern void rtgeom_set_srid(const RTCTX *ctx, RTGEOM *geom, int srid); /**************************************************************** * MEMORY MANAGEMENT ****************************************************************/ /* * The *_free family of functions frees *all* memory associated * with the pointer. When the recursion gets to the level of the * RTPOINTARRAY, the RTPOINTARRAY is only freed if it is not flagged * as "read only". RTGEOMs constructed on top of GSERIALIZED * from PgSQL use read only point arrays. */ extern void ptarray_free(const RTCTX *ctx, RTPOINTARRAY *pa); extern void rtpoint_free(const RTCTX *ctx, RTPOINT *pt); extern void rtline_free(const RTCTX *ctx, RTLINE *line); extern void rtpoly_free(const RTCTX *ctx, RTPOLY *poly); extern void rttriangle_free(const RTCTX *ctx, RTTRIANGLE *triangle); extern void rtmpoint_free(const RTCTX *ctx, RTMPOINT *mpt); extern void rtmline_free(const RTCTX *ctx, RTMLINE *mline); extern void rtmpoly_free(const RTCTX *ctx, RTMPOLY *mpoly); extern void rtpsurface_free(const RTCTX *ctx, RTPSURFACE *psurf); extern void rttin_free(const RTCTX *ctx, RTTIN *tin); extern void rtcollection_free(const RTCTX *ctx, RTCOLLECTION *col); extern void rtcircstring_free(const RTCTX *ctx, RTCIRCSTRING *curve); extern void rtgeom_free(const RTCTX *ctx, RTGEOM *geom); /* * The *_release family of functions frees the RTGEOM structures * surrounding the RTPOINTARRAYs but leaves the RTPOINTARRAYs * intact. Useful when re-shaping geometries between types, * or splicing geometries together. */ extern void rtpoint_release(const RTCTX *ctx, RTPOINT *rtpoint); extern void rtline_release(const RTCTX *ctx, RTLINE *rtline); extern void rtpoly_release(const RTCTX *ctx, RTPOLY *rtpoly); extern void rttriangle_release(const RTCTX *ctx, RTTRIANGLE *rttriangle); extern void rtcircstring_release(const RTCTX *ctx, RTCIRCSTRING *rtcirc); extern void rtmpoint_release(const RTCTX *ctx, RTMPOINT *rtpoint); extern void rtmline_release(const RTCTX *ctx, RTMLINE *rtline); extern void rtmpoly_release(const RTCTX *ctx, RTMPOLY *rtpoly); extern void rtpsurface_release(RTPSURFACE *rtpsurface); extern void rttin_release(RTTIN *rttin); extern void rtcollection_release(const RTCTX *ctx, RTCOLLECTION *rtcollection); extern void rtgeom_release(const RTCTX *ctx, RTGEOM *rtgeom); /**************************************************************** * Utility ****************************************************************/ extern void printPA(const RTCTX *ctx, RTPOINTARRAY *pa); extern void printRTPOINT(const RTCTX *ctx, RTPOINT *point); extern void printRTLINE(const RTCTX *ctx, RTLINE *line); extern void printRTPOLY(const RTCTX *ctx, RTPOLY *poly); extern void printRTTRIANGLE(const RTCTX *ctx, RTTRIANGLE *triangle); extern void printRTPSURFACE(const RTCTX *ctx, RTPSURFACE *psurf); extern void printRTTIN(const RTCTX *ctx, RTTIN *tin); extern float next_float_down(const RTCTX *ctx, double d); extern float next_float_up(const RTCTX *ctx, double d); extern double next_double_down(const RTCTX *ctx, float d); extern double next_double_up(const RTCTX *ctx, float d); /* general utilities 2D */ extern double distance2d_pt_pt(const RTCTX *ctx, const RTPOINT2D *p1, const RTPOINT2D *p2); extern double distance2d_sqr_pt_pt(const RTCTX *ctx, const RTPOINT2D *p1, const RTPOINT2D *p2); extern double distance2d_pt_seg(const RTCTX *ctx, const RTPOINT2D *p, const RTPOINT2D *A, const RTPOINT2D *B); extern double distance2d_sqr_pt_seg(const RTCTX *ctx, const RTPOINT2D *p, const RTPOINT2D *A, const RTPOINT2D *B); extern RTGEOM* rtgeom_closest_line(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern RTGEOM* rtgeom_furthest_line(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern RTGEOM* rtgeom_closest_point(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern RTGEOM* rtgeom_furthest_point(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern double rtgeom_mindistance2d(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern double rtgeom_mindistance2d_tolerance(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2, double tolerance); extern double rtgeom_maxdistance2d(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern double rtgeom_maxdistance2d_tolerance(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2, double tolerance); /* 3D */ extern double distance3d_pt_pt(const RTCTX *ctx, const POINT3D *p1, const POINT3D *p2); extern double distance3d_pt_seg(const POINT3D *p, const POINT3D *A, const POINT3D *B); extern RTGEOM* rtgeom_furthest_line_3d(const RTCTX *ctx, RTGEOM *rt1, RTGEOM *rt2); extern RTGEOM* rtgeom_closest_line_3d(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern RTGEOM* rtgeom_closest_point_3d(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern double rtgeom_mindistance3d(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern double rtgeom_mindistance3d_tolerance(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2, double tolerance); extern double rtgeom_maxdistance3d(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2); extern double rtgeom_maxdistance3d_tolerance(const RTCTX *ctx, const RTGEOM *rt1, const RTGEOM *rt2, double tolerance); extern double rtgeom_area(const RTCTX *ctx, const RTGEOM *geom); extern double rtgeom_length(const RTCTX *ctx, const RTGEOM *geom); extern double rtgeom_length_2d(const RTCTX *ctx, const RTGEOM *geom); extern double rtgeom_perimeter(const RTCTX *ctx, const RTGEOM *geom); extern double rtgeom_perimeter_2d(const RTCTX *ctx, const RTGEOM *geom); extern void rtgeom_affine(const RTCTX *ctx, RTGEOM *geom, const RTAFFINE *affine); extern void rtgeom_scale(const RTCTX *ctx, RTGEOM *geom, const RTPOINT4D *factors); extern int rtgeom_dimension(const RTCTX *ctx, const RTGEOM *geom); extern RTPOINT* rtline_get_rtpoint(const RTCTX *ctx, const RTLINE *line, int where); extern RTPOINT* rtcircstring_get_rtpoint(const RTCTX *ctx, const RTCIRCSTRING *circ, int where); extern RTPOINT* rtcompound_get_startpoint(const RTCTX *ctx, const RTCOMPOUND *rtcmp); extern RTPOINT* rtcompound_get_endpoint(const RTCTX *ctx, const RTCOMPOUND *rtcmp); extern RTPOINT* rtcompound_get_rtpoint(const RTCTX *ctx, const RTCOMPOUND *rtcmp, int where); extern double ptarray_length_2d(const RTCTX *ctx, const RTPOINTARRAY *pts); extern double ptarray_length(const RTCTX *ctx, const RTPOINTARRAY *pts); extern double ptarray_arc_length_2d(const RTCTX *ctx, const RTPOINTARRAY *pts); extern int pt_in_ring_2d(const RTCTX *ctx, const RTPOINT2D *p, const RTPOINTARRAY *ring); extern int azimuth_pt_pt(const RTCTX *ctx, const RTPOINT2D *p1, const RTPOINT2D *p2, double *ret); extern int rtpoint_inside_circle(const RTCTX *ctx, const RTPOINT *p, double cx, double cy, double rad); extern void rtgeom_reverse(const RTCTX *ctx, RTGEOM *rtgeom); extern void rtline_reverse(const RTCTX *ctx, RTLINE *line); extern void rtpoly_reverse(const RTCTX *ctx, RTPOLY *poly); extern void rttriangle_reverse(const RTCTX *ctx, RTTRIANGLE *triangle); extern char* rtgeom_summary(const RTCTX *ctx, const RTGEOM *rtgeom, int offset); extern char* rtpoint_to_latlon(const RTCTX *ctx, const RTPOINT *p, const char *format); extern int rtgeom_startpoint(const RTCTX *ctx, const RTGEOM* rtgeom, RTPOINT4D* pt); /** * Ensure the outer ring is clockwise oriented and all inner rings * are counter-clockwise. */ extern void rtgeom_force_clockwise(const RTCTX *ctx, RTGEOM *rtgeom); extern void rtpoly_force_clockwise(const RTCTX *ctx, RTPOLY *poly); extern void rttriangle_force_clockwise(const RTCTX *ctx, RTTRIANGLE *triangle); extern void interpolate_point4d(const RTCTX *ctx, RTPOINT4D *A, RTPOINT4D *B, RTPOINT4D *I, double F); void rtgeom_longitude_shift(const RTCTX *ctx, RTGEOM *rtgeom); /** * @brief Check whether or not a rtgeom is big enough to warrant a bounding box. * * Check whether or not a rtgeom is big enough to warrant a bounding box * when stored in the serialized form on disk. Currently only points are * considered small enough to not require a bounding box, because the * index operations can generate a large number of box-retrieval operations * when scanning keys. */ extern int rtgeom_needs_bbox(const RTCTX *ctx, const RTGEOM *geom); /** * Count the total number of vertices in any #RTGEOM. */ extern int rtgeom_count_vertices(const RTCTX *ctx, const RTGEOM *geom); /** * Count the total number of rings in any #RTGEOM. Multipolygons * and other collections get counted, not the same as OGC st_numrings. */ extern int rtgeom_count_rings(const RTCTX *ctx, const RTGEOM *geom); /** * Return true or false depending on whether a geometry has * a valid SRID set. */ extern int rtgeom_has_srid(const RTCTX *ctx, const RTGEOM *geom); /** * Return true or false depending on whether a geometry is an "empty" * geometry (no vertices members) */ extern int rtgeom_is_empty(const RTCTX *ctx, const RTGEOM *geom); /** * Return true or false depending on whether a geometry is a linear * feature that closes on itself. */ extern int rtgeom_is_closed(const RTCTX *ctx, const RTGEOM *geom); /** * Return the dimensionality (relating to point/line/poly) of an rtgeom */ extern int rtgeom_dimensionality(const RTCTX *ctx, RTGEOM *geom); /* Is rtgeom1 geometrically equal to rtgeom2 ? */ char rtgeom_same(const RTCTX *ctx, const RTGEOM *rtgeom1, const RTGEOM *rtgeom2); char ptarray_same(const RTCTX *ctx, const RTPOINTARRAY *pa1, const RTPOINTARRAY *pa2); char rtpoint_same(const RTCTX *ctx, const RTPOINT *p1, const RTPOINT *p2); char rtline_same(const RTCTX *ctx, const RTLINE *p1, const RTLINE *p2); char rtpoly_same(const RTCTX *ctx, const RTPOLY *p1, const RTPOLY *p2); char rttriangle_same(const RTCTX *ctx, const RTTRIANGLE *p1, const RTTRIANGLE *p2); char rtcollection_same(const RTCTX *ctx, const RTCOLLECTION *p1, const RTCOLLECTION *p2); char rtcircstring_same(const RTCTX *ctx, const RTCIRCSTRING *p1, const RTCIRCSTRING *p2); /** * @brief Clone RTGEOM object. Serialized point lists are not copied. * * #RTGBOX are copied * * @see ptarray_clone */ extern RTGEOM *rtgeom_clone(const RTCTX *ctx, const RTGEOM *rtgeom); /** * Deep clone an RTGEOM, everything is copied */ extern RTGEOM *rtgeom_clone_deep(const RTCTX *ctx, const RTGEOM *rtgeom); /* TODO Move to Internal */ RTPOINT *rtpoint_clone(const RTCTX *ctx, const RTPOINT *rtgeom); RTPOINTARRAY *ptarray_clone_deep(const RTCTX *ctx, const RTPOINTARRAY *ptarray); /* * Geometry constructors. These constructors to not copy the point arrays * passed to them, they just take references, so do not free them out * from underneath the geometries. */ extern RTPOINT* rtpoint_construct(const RTCTX *ctx, int srid, RTGBOX *bbox, RTPOINTARRAY *point); extern RTMPOINT *rtmpoint_construct(const RTCTX *ctx, int srid, const RTPOINTARRAY *pa); extern RTLINE* rtline_construct(const RTCTX *ctx, int srid, RTGBOX *bbox, RTPOINTARRAY *points); extern RTCIRCSTRING* rtcircstring_construct(const RTCTX *ctx, int srid, RTGBOX *bbox, RTPOINTARRAY *points); extern RTPOLY* rtpoly_construct(const RTCTX *ctx, int srid, RTGBOX *bbox, uint32_t nrings, RTPOINTARRAY **points); extern RTCURVEPOLY* rtcurvepoly_construct(int srid, RTGBOX *bbox, uint32_t nrings, RTGEOM **geoms); extern RTTRIANGLE* rttriangle_construct(const RTCTX *ctx, int srid, RTGBOX *bbox, RTPOINTARRAY *points); extern RTCOLLECTION* rtcollection_construct(const RTCTX *ctx, uint8_t type, int srid, RTGBOX *bbox, uint32_t ngeoms, RTGEOM **geoms); /* * Empty geometry constructors. */ extern RTGEOM* rtgeom_construct_empty(const RTCTX *ctx, uint8_t type, int srid, char hasz, char hasm); extern RTPOINT* rtpoint_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTLINE* rtline_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTPOLY* rtpoly_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTCURVEPOLY* rtcurvepoly_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTCIRCSTRING* rtcircstring_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTCOMPOUND* rtcompound_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTTRIANGLE* rttriangle_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTMPOINT* rtmpoint_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTMLINE* rtmline_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTMPOLY* rtmpoly_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm); extern RTCOLLECTION* rtcollection_construct_empty(const RTCTX *ctx, uint8_t type, int srid, char hasz, char hasm); /* Other constructors */ extern RTPOINT *rtpoint_make2d(const RTCTX *ctx, int srid, double x, double y); extern RTPOINT *rtpoint_make3dz(const RTCTX *ctx, int srid, double x, double y, double z); extern RTPOINT *rtpoint_make3dm(const RTCTX *ctx, int srid, double x, double y, double m); extern RTPOINT *rtpoint_make4d(const RTCTX *ctx, int srid, double x, double y, double z, double m); extern RTPOINT *rtpoint_make(const RTCTX *ctx, int srid, int hasz, int hasm, const RTPOINT4D *p); extern RTLINE *rtline_from_rtgeom_array(const RTCTX *ctx, int srid, uint32_t ngeoms, RTGEOM **geoms); extern RTLINE *rtline_from_ptarray(const RTCTX *ctx, int srid, uint32_t npoints, RTPOINT **points); /* TODO: deprecate */ extern RTLINE *rtline_from_rtmpoint(const RTCTX *ctx, int srid, const RTMPOINT *mpoint); extern RTLINE *rtline_addpoint(RTLINE *line, RTPOINT *point, uint32_t where); extern RTLINE *rtline_removepoint(const RTCTX *ctx, RTLINE *line, uint32_t which); extern void rtline_setPoint4d(const RTCTX *ctx, RTLINE *line, uint32_t which, RTPOINT4D *newpoint); extern RTPOLY *rtpoly_from_rtlines(const RTCTX *ctx, const RTLINE *shell, uint32_t nholes, const RTLINE **holes); extern RTTRIANGLE *rttriangle_from_rtline(const RTCTX *ctx, const RTLINE *shell); /* Some point accessors */ extern double rtpoint_get_x(const RTCTX *ctx, const RTPOINT *point); extern double rtpoint_get_y(const RTCTX *ctx, const RTPOINT *point); extern double rtpoint_get_z(const RTCTX *ctx, const RTPOINT *point); extern double rtpoint_get_m(const RTCTX *ctx, const RTPOINT *point); /** * Return SRID number */ extern int32_t rtgeom_get_srid(const RTCTX *ctx, const RTGEOM *geom); /** * Return RTRTTYPE number */ extern uint32_t rtgeom_get_type(const RTCTX *ctx, const RTGEOM *geom); /** * Return #RT_TRUE if geometry has Z ordinates */ extern int rtgeom_has_z(const RTCTX *ctx, const RTGEOM *geom); /** * Return #RT_TRUE if geometry has M ordinates. */ extern int rtgeom_has_m(const RTCTX *ctx, const RTGEOM *geom); /** * Return the number of dimensions (2, 3, 4) in a geometry */ extern int rtgeom_ndims(const RTCTX *ctx, const RTGEOM *geom); /* * Given a point, returns the location of closest point on pointarray * as a fraction of total length (0: first point -- 1: last point). * * If not-null, the third argument will be set to the actual distance * of the point from the pointarray. */ extern double ptarray_locate_point(const RTCTX *ctx, const RTPOINTARRAY *pa, const RTPOINT4D *pt, double *dist, RTPOINT4D *p_located); /** * Add a measure dimension to a line, interpolating linearly from the start * to the end value. */ extern RTLINE *rtline_measured_from_rtline(const RTCTX *ctx, const RTLINE *rtline, double m_start, double m_end); extern RTMLINE* rtmline_measured_from_rtmline(const RTCTX *ctx, const RTMLINE *rtmline, double m_start, double m_end); /** * Determine the location(s) along a measured line where m occurs and * return as a multipoint. Offset to left (positive) or right (negative). */ extern RTGEOM* rtgeom_locate_along(const RTCTX *ctx, const RTGEOM *rtin, double m, double offset); /** * Determine the segments along a measured line that fall within the m-range * given. Return as a multiline or geometrycollection. * Offset to left (positive) or right (negative). */ extern RTCOLLECTION* rtgeom_locate_between(const RTCTX *ctx, const RTGEOM *rtin, double from, double to, double offset); /** * Find the measure value at the location on the line closest to the point. */ extern double rtgeom_interpolate_point(const RTCTX *ctx, const RTGEOM *rtin, const RTPOINT *rtpt); /** * Find the time of closest point of approach * * @param mindist if not null will be set to the minimum distance between * the trajectories at the closest point of approach. * * @return the time value in which the minimum distance was reached, -1 * if inputs are invalid (rterror is called in that case), * -2 if the trajectories do not share any point in time. */ extern double rtgeom_tcpa(const RTCTX *ctx, const RTGEOM *g1, const RTGEOM *g2, double *mindist); /** * Is the closest point of approach within a distance ? * * @return RT_TRUE or RT_FALSE */ extern int rtgeom_cpa_within(const RTCTX *ctx, const RTGEOM *g1, const RTGEOM *g2, double maxdist); /** * Return RT_TRUE or RT_FALSE depending on whether or not a geometry is * a linestring with measure value growing from start to end vertex */ extern int rtgeom_is_trajectory(const RTCTX *ctx, const RTGEOM *geom); extern int rtline_is_trajectory(const RTCTX *ctx, const RTLINE *geom); /* * Ensure every segment is at most 'dist' long. * Returned RTGEOM might is unchanged if a POINT. */ extern RTGEOM *rtgeom_segmentize2d(const RTCTX *ctx, RTGEOM *line, double dist); extern RTPOINTARRAY *ptarray_segmentize2d(const RTCTX *ctx, const RTPOINTARRAY *ipa, double dist); extern RTLINE *rtline_segmentize2d(const RTCTX *ctx, RTLINE *line, double dist); extern RTPOLY *rtpoly_segmentize2d(const RTCTX *ctx, RTPOLY *line, double dist); extern RTCOLLECTION *rtcollection_segmentize2d(const RTCTX *ctx, RTCOLLECTION *coll, double dist); /** * Calculate the GeoHash (http://geohash.org) string for a geometry. Caller must free. */ char *rtgeom_geohash(const RTCTX *ctx, const RTGEOM *rtgeom, int precision); unsigned int geohash_point_as_int(const RTCTX *ctx, RTPOINT2D *pt); /** * The return values of rtline_crossing_direction(const RTCTX *ctx) */ enum RTCG_LINE_CROSS_TYPE { LINE_NO_CROSS = 0, LINE_CROSS_LEFT = -1, LINE_CROSS_RIGHT = 1, LINE_MULTICROSS_END_LEFT = -2, LINE_MULTICROSS_END_RIGHT = 2, LINE_MULTICROSS_END_SAME_FIRST_LEFT = -3, LINE_MULTICROSS_END_SAME_FIRST_RIGHT = 3 }; /** * Given two lines, characterize how (and if) they cross each other */ int rtline_crossing_direction(const RTCTX *ctx, const RTLINE *l1, const RTLINE *l2); /** * Given a geometry clip based on the from/to range of one of its ordinates (x, y, z, m). Use for m- and z- clipping. */ RTCOLLECTION* rtgeom_clip_to_ordinate_range(const RTCTX *ctx, const RTGEOM *rtin, char ordinate, double from, double to, double offset); /** * Macros for specifying GML options. * @{ */ /** For GML3 only, include srsDimension attribute in output */ #define RT_GML_IS_DIMS (1<<0) /** For GML3 only, declare that datas are lat/lon. Swaps axis order */ #define RT_GML_IS_DEGREE (1<<1) /** For GML3, use rather than for lines */ #define RT_GML_SHORTLINE (1<<2) /** For GML2 and GML3, output only extent of geometry */ #define RT_GML_EXTENT (1<<4) #define IS_DIMS(x) ((x) & RT_GML_IS_DIMS) #define IS_DEGREE(x) ((x) & RT_GML_IS_DEGREE) /** @} */ /** * Macros for specifying X3D options. * @{ */ /** For flip X/Y coordinates to Y/X */ #define RT_X3D_FLIP_XY (1<<0) #define RT_X3D_USE_GEOCOORDS (1<<1) #define X3D_USE_GEOCOORDS(x) ((x) & RT_X3D_USE_GEOCOORDS) extern char* rtgeom_to_gml2(const RTCTX *ctx, const RTGEOM *geom, const char *srs, int precision, const char *prefix); extern char* rtgeom_extent_to_gml2(const RTCTX *ctx, const RTGEOM *geom, const char *srs, int precision, const char *prefix); /** * @param opts output options bitfield, see RT_GML macros for meaning */ extern char* rtgeom_extent_to_gml3(const RTCTX *ctx, const RTGEOM *geom, const char *srs, int precision, int opts, const char *prefix); extern char* rtgeom_to_gml3(const RTCTX *ctx, const RTGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id); extern char* rtgeom_to_kml2(const RTCTX *ctx, const RTGEOM *geom, int precision, const char *prefix); extern char* rtgeom_to_geojson(const RTCTX *ctx, const RTGEOM *geo, char *srs, int precision, int has_bbox); extern char* rtgeom_to_svg(const RTCTX *ctx, const RTGEOM *geom, int precision, int relative); extern char* rtgeom_to_x3d3(const RTCTX *ctx, const RTGEOM *geom, char *srs, int precision, int opts, const char *defid); /** * Create an RTGEOM object from a GeoJSON representation * * @param geojson the GeoJSON input * @param srs output parameter. Will be set to a newly allocated * string holding the spatial reference string, or NULL * if no such parameter is found in input. * If not null, the pointer must be freed with rtfree. */ extern RTGEOM* rtgeom_from_geojson(const RTCTX *ctx, const char *geojson, char **srs); /** * Initialize a spheroid object for use in geodetic functions. */ extern void spheroid_init(const RTCTX *ctx, SPHEROID *s, double a, double b); /** * Calculate the geodetic distance from rtgeom1 to rtgeom2 on the spheroid. * A spheroid with major axis == minor axis will be treated as a sphere. * Pass in a tolerance in spheroid units. */ extern double rtgeom_distance_spheroid(const RTCTX *ctx, const RTGEOM *rtgeom1, const RTGEOM *rtgeom2, const SPHEROID *spheroid, double tolerance); /** * Calculate the location of a point on a spheroid, give a start point, bearing and distance. */ extern RTPOINT* rtgeom_project_spheroid(const RTCTX *ctx, const RTPOINT *r, const SPHEROID *spheroid, double distance, double azimuth); /** * Derive a new geometry with vertices added to ensure no vertex is more * than max_seg_length (in radians) from any other vertex. */ extern RTGEOM* rtgeom_segmentize_sphere(const RTCTX *ctx, const RTGEOM *rtg_in, double max_seg_length); /** * Calculate the bearing between two points on a spheroid. */ extern double rtgeom_azumith_spheroid(const RTCTX *ctx, const RTPOINT *r, const RTPOINT *s, const SPHEROID *spheroid); /** * Calculate the geodetic area of a rtgeom on the sphere. The result * will be multiplied by the average radius of the supplied spheroid. */ extern double rtgeom_area_sphere(const RTCTX *ctx, const RTGEOM *rtgeom, const SPHEROID *spheroid); /** * Calculate the geodetic area of a rtgeom on the spheroid. The result * will have the squared units of the spheroid axes. */ extern double rtgeom_area_spheroid(const RTCTX *ctx, const RTGEOM *rtgeom, const SPHEROID *spheroid); /** * Calculate the geodetic length of a rtgeom on the unit sphere. The result * will have to by multiplied by the real radius to get the real length. */ extern double rtgeom_length_spheroid(const RTCTX *ctx, const RTGEOM *geom, const SPHEROID *s); /** * Calculate covers predicate for two rtgeoms on the sphere. Currently * only handles point-in-polygon. */ extern int rtgeom_covers_rtgeom_sphere(const RTCTX *ctx, const RTGEOM *rtgeom1, const RTGEOM *rtgeom2); /** * Remove repeated points! */ extern RTGEOM* rtgeom_remove_repeated_points(const RTCTX *ctx, const RTGEOM *in, double tolerance); extern char rttriangle_is_repeated_points(const RTCTX *ctx, RTTRIANGLE *triangle); /** * Swap ordinate values in every vertex of the geometry. * * Ordinates to swap are specified using an index with meaning: * 0=x, 1=y, 2=z, 3=m * * Swapping an existing ordinate with an unexisting one results * in undefined value being written in the existing ordinate. * Caller should verify and prevent such calls. * * Availability: 2.2.0 */ extern void rtgeom_swap_ordinates(const RTCTX *ctx, RTGEOM *in, RTORD o1, RTORD o2); /** * Reverse the X and Y coordinate order. Useful for geometries in lat/lon order * than need to be converted to lon/lat order. * * NOTE: uses rtgeom_swap_ordinates internally, * kept for backward compatibility */ extern RTGEOM* rtgeom_flip_coordinates(const RTCTX *ctx, RTGEOM *in); struct RTPOINTITERATOR; typedef struct RTPOINTITERATOR RTPOINTITERATOR; /** * Create a new RTPOINTITERATOR over supplied RTGEOM* */ extern RTPOINTITERATOR* rtpointiterator_create(const RTCTX *ctx, const RTGEOM* g); /** * Create a new RTPOINTITERATOR over supplied RTGEOM* * Supports modification of coordinates during iteration. */ extern RTPOINTITERATOR* rtpointiterator_create_rw(const RTCTX *ctx, RTGEOM* g); /** * Free all memory associated with the iterator */ extern void rtpointiterator_destroy(const RTCTX *ctx, RTPOINTITERATOR* s); /** * Returns RT_TRUE if there is another point available in the iterator. */ extern int rtpointiterator_has_next(const RTCTX *ctx, RTPOINTITERATOR* s); /** * Attempts to replace the next point int the iterator with p, and advances * the iterator to the next point. * Returns RT_SUCCESS if the assignment was successful, RT_FAILURE otherwise. * */ extern int rtpointiterator_modify_next(const RTCTX *ctx, RTPOINTITERATOR* s, const RTPOINT4D* p); /** * Attempts to assign the next point in the iterator to p, and advances * the iterator to the next point. If p is NULL, the iterator will be * advanced without reading a point. * Returns RT_SUCCESS if the assignment was successful, RT_FAILURE otherwise. * */ extern int rtpointiterator_next(const RTCTX *ctx, RTPOINTITERATOR* s, RTPOINT4D* p); /** * Attempts to assigns the next point in the iterator to p. Does not advance. * Returns RT_SUCCESS if the assignment was successful, RT_FAILURE otherwise. */ extern int rtpointiterator_peek(const RTCTX *ctx, RTPOINTITERATOR* s, RTPOINT4D* p); /** * Convert a single hex digit into the corresponding char */ extern uint8_t parse_hex(const RTCTX *ctx, char *str); /** * Convert a char into a human readable hex digit */ extern void deparse_hex(const RTCTX *ctx, uint8_t str, char *result); /*********************************************************************** ** Functions for managing serialized forms and bounding boxes. */ /** * Calculate the geocentric bounding box directly from the serialized * form of the geodetic coordinates. Only accepts serialized geographies * flagged as geodetic. Caller is responsible for disposing of the RTGBOX. */ extern RTGBOX* gserialized_calculate_gbox_geocentric(const GSERIALIZED *g); /** * Calculate the geocentric bounding box directly from the serialized * form of the geodetic coordinates. Only accepts serialized geographies * flagged as geodetic. */ int gserialized_calculate_gbox_geocentric_p(const GSERIALIZED *g, RTGBOX *g_box); /** * Return a RTWKT representation of the gserialized geometry. * Caller is responsible for disposing of the char*. */ extern char* gserialized_to_string(const RTCTX *ctx, const GSERIALIZED *g); /** * Return a copy of the input serialized geometry. */ extern GSERIALIZED* gserialized_copy(const RTCTX *ctx, const GSERIALIZED *g); /** * Check that coordinates of RTGEOM are all within the geodetic range (-180, -90, 180, 90) */ extern int rtgeom_check_geodetic(const RTCTX *ctx, const RTGEOM *geom); /** * Gently move coordinates of RTGEOM if they are close enough into geodetic range. */ extern int rtgeom_nudge_geodetic(const RTCTX *ctx, RTGEOM *geom); /** * Force coordinates of RTGEOM into geodetic range (-180, -90, 180, 90) */ extern int rtgeom_force_geodetic(const RTCTX *ctx, RTGEOM *geom); /** * Set the RTFLAGS geodetic bit on geometry an all sub-geometries and pointlists */ extern void rtgeom_set_geodetic(const RTCTX *ctx, RTGEOM *geom, int value); /** * Calculate the geodetic bounding box for an RTGEOM. Z/M coordinates are * ignored for this calculation. Pass in non-null, geodetic bounding box for function * to fill out. RTGEOM must have been built from a GSERIALIZED to provide * double aligned point arrays. */ extern int rtgeom_calculate_gbox_geodetic(const RTCTX *ctx, const RTGEOM *geom, RTGBOX *gbox); /** * Calculate the 2-4D bounding box of a geometry. Z/M coordinates are honored * for this calculation, though for curves they are not included in calculations * of curvature. */ extern int rtgeom_calculate_gbox_cartesian(const RTCTX *ctx, const RTGEOM *rtgeom, RTGBOX *gbox); /** * Calculate bounding box of a geometry, automatically taking into account * whether it is cartesian or geodetic. */ extern int rtgeom_calculate_gbox(const RTCTX *ctx, const RTGEOM *rtgeom, RTGBOX *gbox); /** * New function to read doubles directly from the double* coordinate array * of an aligned rtgeom #RTPOINTARRAY (built by de-serializing a #GSERIALIZED). */ extern int rt_getPoint2d_p_ro(const RTCTX *ctx, const RTPOINTARRAY *pa, int n, RTPOINT2D **point); /** * Calculate geodetic (x/y/z) box and add values to gbox. Return #RT_SUCCESS on success. */ extern int ptarray_calculate_gbox_geodetic(const RTCTX *ctx, const RTPOINTARRAY *pa, RTGBOX *gbox); /** * Calculate box (x/y) and add values to gbox. Return #RT_SUCCESS on success. */ extern int ptarray_calculate_gbox_cartesian(const RTCTX *ctx, const RTPOINTARRAY *pa, RTGBOX *gbox ); /** * Calculate a spherical point that falls outside the geocentric gbox */ void gbox_pt_outside(const RTCTX *ctx, const RTGBOX *gbox, RTPOINT2D *pt_outside); /** * Create a new gbox with the dimensionality indicated by the flags. Caller * is responsible for freeing. */ extern RTGBOX* gbox_new(const RTCTX *ctx, uint8_t flags); /** * Zero out all the entries in the #RTGBOX. Useful for cleaning * statically allocated gboxes. */ extern void gbox_init(const RTCTX *ctx, RTGBOX *gbox); /** * Update the merged #RTGBOX to be large enough to include itself and the new box. */ extern int gbox_merge(const RTCTX *ctx, const RTGBOX *new_box, RTGBOX *merged_box); /** * Update the output #RTGBOX to be large enough to include both inputs. */ extern int gbox_union(const RTCTX *ctx, const RTGBOX *g1, const RTGBOX *g2, RTGBOX *gout); /** * Move the box minimums down and the maximums up by the distance provided. */ extern void gbox_expand(const RTCTX *ctx, RTGBOX *g, double d); /** * Initialize a #RTGBOX using the values of the point. */ extern int gbox_init_point3d(const RTCTX *ctx, const POINT3D *p, RTGBOX *gbox); /** * Update the #RTGBOX to be large enough to include itself and the new point. */ extern int gbox_merge_point3d(const RTCTX *ctx, const POINT3D *p, RTGBOX *gbox); /** * Return true if the point is inside the gbox */ extern int gbox_contains_point3d(const RTCTX *ctx, const RTGBOX *gbox, const POINT3D *pt); /** * Allocate a string representation of the #RTGBOX, based on dimensionality of flags. */ extern char* gbox_to_string(const RTCTX *ctx, const RTGBOX *gbox); /** * Return a copy of the #RTGBOX, based on dimensionality of flags. */ extern RTGBOX* gbox_copy(const RTCTX *ctx, const RTGBOX *gbox); /** * Warning, do not use this function, it is very particular about inputs. */ extern RTGBOX* gbox_from_string(const RTCTX *ctx, const char *str); /** * Return #RT_TRUE if the #RTGBOX overlaps, #RT_FALSE otherwise. */ extern int gbox_overlaps(const RTCTX *ctx, const RTGBOX *g1, const RTGBOX *g2); /** * Return #RT_TRUE if the #RTGBOX overlaps on the 2d plane, #RT_FALSE otherwise. */ extern int gbox_overlaps_2d(const RTCTX *ctx, const RTGBOX *g1, const RTGBOX *g2); /** * Return #RT_TRUE if the first #RTGBOX contains the second on the 2d plane, #RT_FALSE otherwise. */ extern int gbox_contains_2d(const RTCTX *ctx, const RTGBOX *g1, const RTGBOX *g2); /** * Copy the values of original #RTGBOX into duplicate. */ extern void gbox_duplicate(const RTCTX *ctx, const RTGBOX *original, RTGBOX *duplicate); /** * Return the number of bytes necessary to hold a #RTGBOX of this dimension in * serialized form. */ extern size_t gbox_serialized_size(const RTCTX *ctx, uint8_t flags); /** * Check if 2 given Gbox are the same */ extern int gbox_same(const RTCTX *ctx, const RTGBOX *g1, const RTGBOX *g2); /** * Check if 2 given RTGBOX are the same in x and y */ extern int gbox_same_2d(const RTCTX *ctx, const RTGBOX *g1, const RTGBOX *g2); /** * Check if two given RTGBOX are the same in x and y, or would round to the same * RTGBOX in x and if serialized in GSERIALIZED */ extern int gbox_same_2d_float(const RTCTX *ctx, const RTGBOX *g1, const RTGBOX *g2); /** * Round given RTGBOX to float boundaries * * This turns a RTGBOX into the version it would become * after a serialize/deserialize round trip. */ extern void gbox_float_round(const RTCTX *ctx, RTGBOX *gbox); /** * Return false if any of the dimensions is NaN or infinite */ extern int gbox_is_valid(const RTCTX *ctx, const RTGBOX *gbox); /** * Utility function to get type number from string. For example, a string 'POINTZ' * would return type of 1 and z of 1 and m of 0. Valid */ extern int geometry_type_from_string(const RTCTX *ctx, const char *str, uint8_t *type, int *z, int *m); /** * Calculate required memory segment to contain a serialized form of the RTGEOM. * Primarily used internally by the serialization code. Exposed to allow the cunit * tests to exercise it. */ extern size_t gserialized_from_rtgeom_size(const RTCTX *ctx, const RTGEOM *geom); /** * Allocate a new #GSERIALIZED from an #RTGEOM. For all non-point types, a bounding * box will be calculated and embedded in the serialization. The geodetic flag is used * to control the box calculation (cartesian or geocentric). If set, the size pointer * will contain the size of the final output, which is useful for setting the PgSQL * VARSIZE information. */ extern GSERIALIZED* gserialized_from_rtgeom(const RTCTX *ctx, RTGEOM *geom, int is_geodetic, size_t *size); /** * Allocate a new #RTGEOM from a #GSERIALIZED. The resulting #RTGEOM will have coordinates * that are double aligned and suitable for direct reading using rt_getPoint2d_p_ro */ extern RTGEOM* rtgeom_from_gserialized(const RTCTX *ctx, const GSERIALIZED *g); /** * Pull a #RTGBOX from the header of a #GSERIALIZED, if one is available. If * it is not, calculate it from the geometry. If that doesn't work (null * or empty) return RT_FAILURE. */ extern int gserialized_get_gbox_p(const RTCTX *ctx, const GSERIALIZED *g, RTGBOX *gbox); /** * Parser check flags * * @see rtgeom_from_wkb * @see rtgeom_from_hexwkb */ #define RT_PARSER_CHECK_MINPOINTS 1 #define RT_PARSER_CHECK_ODD 2 #define RT_PARSER_CHECK_CLOSURE 4 #define RT_PARSER_CHECK_ZCLOSURE 8 #define RT_PARSER_CHECK_NONE 0 #define RT_PARSER_CHECK_ALL (RT_PARSER_CHECK_MINPOINTS | RT_PARSER_CHECK_ODD | RT_PARSER_CHECK_CLOSURE) /** * Parser result structure: returns the result of attempting to convert * (E)RTWKT/(E)RTWKB to RTGEOM */ typedef struct struct_rtgeom_parser_result { const char *wkinput; /* Copy of pointer to input RTWKT/RTWKB */ uint8_t *serialized_rtgeom; /* Pointer to serialized RTGEOM */ int size; /* Size of serialized RTGEOM in bytes */ RTGEOM *geom; /* Pointer to RTGEOM struct */ const char *message; /* Error/warning message */ int errcode; /* Error/warning number */ int errlocation; /* Location of error */ int parser_check_flags; /* Bitmask of validity checks run during this parse */ } RTGEOM_PARSER_RESULT; /* * Parser error messages (these must match the message array in rtgparse.c) */ #define PARSER_ERROR_MOREPOINTS 1 #define PARSER_ERROR_ODDPOINTS 2 #define PARSER_ERROR_UNCLOSED 3 #define PARSER_ERROR_MIXDIMS 4 #define PARSER_ERROR_INVALIDGEOM 5 #define RTPARSER_ERROR_INVALIDWKBTYPE 6 #define PARSER_ERROR_INCONTINUOUS 7 #define PARSER_ERROR_TRIANGLEPOINTS 8 #define PARSER_ERROR_LESSPOINTS 9 #define PARSER_ERROR_OTHER 10 /* * Unparser result structure: returns the result of attempting to convert RTGEOM to (E)RTWKT/(E)RTWKB */ typedef struct struct_rtgeom_unparser_result { uint8_t *serialized_rtgeom; /* Copy of pointer to input serialized RTGEOM */ char *wkoutput; /* Pointer to RTWKT or RTWKB output */ int size; /* Size of serialized RTGEOM in bytes */ const char *message; /* Error/warning message */ int errlocation; /* Location of error */ } RTGEOM_UNPARSER_RESULT; /* * Unparser error messages (these must match the message array in rtgunparse.c) */ #define UNPARSER_ERROR_MOREPOINTS 1 #define UNPARSER_ERROR_ODDPOINTS 2 #define UNPARSER_ERROR_UNCLOSED 3 /* ** Variants available for RTWKB and RTWKT output types */ #define RTWKB_ISO 0x01 #define RTWKB_SFSQL 0x02 #define RTWKB_EXTENDED 0x04 #define RTWKB_NDR 0x08 #define RTWKB_XDR 0x10 #define RTWKB_HEX 0x20 #define RTWKB_NO_NPOINTS 0x40 /* Internal use only */ #define RTWKB_NO_SRID 0x80 /* Internal use only */ #define RTWKT_ISO 0x01 #define RTWKT_SFSQL 0x02 #define RTWKT_EXTENDED 0x04 /* ** Variants available for TWKB */ #define TWKB_BBOX 0x01 /* User wants bboxes */ #define TWKB_SIZE 0x02 /* User wants sizes */ #define TWKB_ID 0x04 /* User wants id */ #define RTTWKB_NO_TYPE 0x10 /* No type because it is a sub geoemtry */ #define TWKB_NO_ID 0x20 /* No ID because it is a subgeoemtry */ #define TWKB_DEFAULT_PRECISION 0 /* Aim for 1m (or ft) rounding by default */ /* ** New parsing and unparsing functions. */ /** * @param rtgeom geometry to convert to RTWKT * @param variant output format to use (RTWKT_ISO, RTWKT_SFSQL, RTWKT_EXTENDED) */ extern char* rtgeom_to_wkt(const RTCTX *ctx, const RTGEOM *geom, uint8_t variant, int precision, size_t *size_out); /** * @param rtgeom geometry to convert to RTWKT * @param variant output format to use * (RTWKB_ISO, RTWKB_SFSQL, RTWKB_EXTENDED, RTWKB_NDR, RTWKB_XDR) */ extern uint8_t* rtgeom_to_wkb(const RTCTX *ctx, const RTGEOM *geom, uint8_t variant, size_t *size_out); /** * @param rtgeom geometry to convert to HEXWKB * @param variant output format to use * (RTWKB_ISO, RTWKB_SFSQL, RTWKB_EXTENDED, RTWKB_NDR, RTWKB_XDR) */ extern char* rtgeom_to_hexwkb(const RTCTX *ctx, const RTGEOM *geom, uint8_t variant, size_t *size_out); /** * @param rtgeom geometry to convert to EWKT */ extern char *rtgeom_to_ewkt(const RTCTX *ctx, const RTGEOM *rtgeom); /** * @param check parser check flags, see RT_PARSER_CHECK_* macros * @param size length of RTWKB byte buffer * @param wkb RTWKB byte buffer */ extern RTGEOM* rtgeom_from_wkb(const RTCTX *ctx, const uint8_t *wkb, const size_t wkb_size, const char check); /** * @param check parser check flags, see RT_PARSER_CHECK_* macros */ extern RTGEOM* rtgeom_from_hexwkb(const RTCTX *ctx, const char *hexwkb, const char check); extern uint8_t* bytes_from_hexbytes(const RTCTX *ctx, const char *hexbuf, size_t hexsize); extern char* hexbytes_from_bytes(const RTCTX *ctx, uint8_t *bytes, size_t size); /* Memory management */ extern void *rtalloc(const RTCTX *ctx, size_t size); extern void *rtrealloc(const RTCTX *ctx, void *mem, size_t size); extern void rtfree(const RTCTX *ctx, void *mem); /* Utilities */ extern char *rtmessage_truncate(const RTCTX *ctx, char *str, int startpos, int endpos, int maxlength, int truncdirection); /* * TWKB functions */ /** * @param check parser check flags, see RT_PARSER_CHECK_* macros * @param size parser check flags, see RT_PARSER_CHECK_* macros */ extern RTGEOM* rtgeom_from_twkb(const RTCTX *ctx, uint8_t *twkb, size_t twkb_size, char check); /** * @param geom input geometry * @param variant what variations on TWKB are requested? * @param twkb_size returns the length of the output TWKB in bytes if set */ extern uint8_t* rtgeom_to_twkb(const RTCTX *ctx, const RTGEOM *geom, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m, size_t *twkb_size); extern uint8_t* rtgeom_to_twkb_with_idlist(const RTCTX *ctx, const RTGEOM *geom, int64_t *idlist, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m, size_t *twkb_size); /******************************************************************************* * SQLMM internal functions - TODO: Move into separate header files ******************************************************************************/ int rtgeom_has_arc(const RTCTX *ctx, const RTGEOM *geom); RTGEOM *rtgeom_stroke(const RTCTX *ctx, const RTGEOM *geom, uint32_t perQuad); RTGEOM *rtgeom_unstroke(const RTCTX *ctx, const RTGEOM *geom); /******************************************************************************* * GEOS proxy functions on RTGEOM ******************************************************************************/ /** Return GEOS version string (not to be freed) */ const char* rtgeom_geos_version(void); /** Convert an RTGEOM to a GEOS Geometry and convert back -- for debug only */ RTGEOM* rtgeom_geos_noop(const RTCTX *ctx, const RTGEOM *geom) ; RTGEOM *rtgeom_normalize(const RTCTX *ctx, const RTGEOM *geom); RTGEOM *rtgeom_intersection(const RTCTX *ctx, const RTGEOM *geom1, const RTGEOM *geom2); RTGEOM *rtgeom_difference(const RTCTX *ctx, const RTGEOM *geom1, const RTGEOM *geom2); RTGEOM *rtgeom_symdifference(const RTCTX *ctx, const RTGEOM* geom1, const RTGEOM* geom2); RTGEOM *rtgeom_union(const RTCTX *ctx, const RTGEOM *geom1, const RTGEOM *geom2); RTGEOM *rtgeom_linemerge(const RTCTX *ctx, const RTGEOM *geom1); RTGEOM *rtgeom_unaryunion(const RTCTX *ctx, const RTGEOM *geom1); RTGEOM *rtgeom_clip_by_rect(const RTCTX *ctx, const RTGEOM *geom1, double x0, double y0, double x1, double y1); RTCOLLECTION *rtgeom_subdivide(const RTCTX *ctx, const RTGEOM *geom, int maxvertices); /** * Snap vertices and segments of a geometry to another using a given tolerance. * * @param geom1 the geometry to snap * @param geom2 the geometry to snap to * @param tolerance the distance under which vertices and segments are snapped * * Requires GEOS-3.3.0+ */ RTGEOM* rtgeom_snap(const RTCTX *ctx, const RTGEOM* geom1, const RTGEOM* geom2, double tolerance); /* * Return the set of paths shared between two linear geometries, * and their direction (same or opposite). * * @param geom1 a lineal geometry * @param geom2 another lineal geometry * * Requires GEOS-3.3.0+ */ RTGEOM* rtgeom_sharedpaths(const RTCTX *ctx, const RTGEOM* geom1, const RTGEOM* geom2); /* * An offset curve against the input line. * * @param rtline a lineal geometry * @param size offset distance. Offset left if negative and right if positive * @param quadsegs number of quadrature segments in curves (try 8) * @param joinStyle (1 = round, 2 = mitre, 3 = bevel) * @param mitreLimit (try 5.0) * @return derived geometry (linestring or multilinestring) * * Requires GEOS-3.2.0+ */ RTGEOM* rtgeom_offsetcurve(const RTCTX *ctx, const RTLINE *rtline, double size, int quadsegs, int joinStyle, double mitreLimit); /* * Return true if the input geometry is "simple" as per OGC defn. * * @return 1 if simple, 0 if non-simple, -1 on exception (rterror is called * in that case) */ int rtgeom_is_simple(const RTCTX *ctx, const RTGEOM *rtgeom); /******************************************************************************* * GEOS-dependent extra functions on RTGEOM ******************************************************************************/ /** * Take a geometry and return an areal geometry * (Polygon or MultiPolygon). * Actually a wrapper around GEOSpolygonize, * transforming the resulting collection into * a valid polygon Geometry. */ RTGEOM* rtgeom_buildarea(const RTCTX *ctx, const RTGEOM *geom) ; /** * Attempts to make an invalid geometries valid w/out losing points. * * NOTE: this is only available when librtgeom is built against * GEOS 3.3.0 or higher */ RTGEOM* rtgeom_make_valid(const RTCTX *ctx, RTGEOM* geom); /* * Split (multi)polygon by line; (multi)line by (multi)line, * (multi)point or (multi)polygon boundary. * * Collections are accepted as first argument. * Returns all obtained pieces as a collection. */ RTGEOM* rtgeom_split(const RTCTX *ctx, const RTGEOM* rtgeom_in, const RTGEOM* blade_in); /* * Fully node a set of linestrings, using the least nodes preserving * all the input ones. * * Requires GEOS-3.3.0 or higher */ RTGEOM* rtgeom_node(const RTCTX *ctx, const RTGEOM* rtgeom_in); /** * Take vertices of a geometry and build a delaunay * triangulation on them. * * @param geom the input geometry * @param tolerance an optional snapping tolerance for improved tolerance * @param edgeOnly if non-zero the result will be a MULTILINESTRING, * otherwise it'll be a COLLECTION of polygons. */ RTGEOM* rtgeom_delaunay_triangulation(const RTCTX *ctx, const RTGEOM *geom, double tolerance, int edgeOnly); #endif /* !defined _LIBRTGEOM_H */