34 #define out_stack_size 32
58 for (i=0; i<coll->
ngeoms; i++)
82 for (i=0; i < coll->
ngeoms; i++)
148 for (i=0; i<col->
ngeoms; i++)
164 if ( lwgeom == NULL )
return NULL;
173 if ( lwgeom == NULL )
return NULL;
182 if ( lwgeom == NULL )
return NULL;
191 if ( lwgeom == NULL )
return NULL;
200 if ( lwgeom == NULL )
return NULL;
209 if ( lwgeom == NULL )
return NULL;
218 if ( lwgeom == NULL )
return NULL;
227 if ( lwgeom == NULL )
return NULL;
236 if ( lwgeom == NULL )
return NULL;
245 if ( lwgeom == NULL )
return NULL;
263 return (
LWTIN *)lwgeom;
279 if ( obj == NULL )
return NULL;
284 if ( obj == NULL )
return NULL;
289 if ( obj == NULL )
return NULL;
294 if ( obj == NULL )
return NULL;
299 if ( obj == NULL )
return NULL;
304 if ( obj == NULL )
return NULL;
309 if ( obj == NULL )
return NULL;
314 if ( obj == NULL )
return NULL;
319 if ( obj == NULL )
return NULL;
324 if ( obj == NULL )
return NULL;
329 if ( obj == NULL )
return NULL;
355 if (
type > 15)
return 0;
389 box = ogeoms[0]->
bbox;
390 ogeoms[0]->
bbox = NULL;
454 lwerror(
"lwgeom_release: someone called on 0x0");
461 LWDEBUGF(3,
"lwgeom_release: releasing bbox. %p", lwgeom->
bbox);
476 LWDEBUGF(2,
"lwgeom_clone called with %p, %s",
479 switch (lwgeom->
type)
514 LWDEBUGF(2,
"lwgeom_clone called with %p, %s",
517 switch (lwgeom->
type)
557 lwerror(
"Error writing geom %p to WKT", lwgeom);
576 LWDEBUGF(2,
"lwgeom_same(%s, %s) called",
580 if ( lwgeom1->
type != lwgeom2->
type )
589 LWDEBUG(3,
" ZM flags differ");
595 if ( lwgeom1->
bbox && lwgeom2->
bbox )
600 LWDEBUG(3,
" bounding boxes differ");
607 switch (lwgeom1->
type)
637 lwerror(
"lwgeom_same: unsupported geometry type: %s",
650 if ( ! p || ! p->
point )
683 if ( lwgeom->
bbox )
return;
703 if ( ! ( gbox || lwgeom->
bbox ) )
708 else if ( gbox && ! lwgeom->
bbox )
718 for ( i = 0; i < lwcol->
ngeoms; i++ )
756 switch (lwgeom->
type)
853 for ( i = 0; i < col->
ngeoms; i++ )
883 for ( i = 0; i < col->
ngeoms; i++ )
899 for ( i = 0; i < col->
ngeoms; i++ )
940 if ( ! geom )
return 0;
973 for ( i = 0; i < ply->
nrings; i++ )
981 for ( i = 0; i < col->
ngeoms; i++ )
994 switch (lwgeom->
type)
1012 for (i=0; i<poly->
nrings; i++)
1026 for (i=0; i<coll->
ngeoms; i++)
1030 lwerror(
"lwgeom_longitude_shift: unsupported geom type: %s",
1066 for ( i = 0; i < col->
ngeoms; i++ )
1142 if( ! lwgeom )
return;
1146 switch (lwgeom->
type)
1234 if( ! geom )
return 0;
1236 LWDEBUGF(4,
"lwgeom_count_vertices got type %s",
1268 lwerror(
"%s: unsupported input geometry type: %s",
1285 if( ! geom )
return -1;
1287 LWDEBUGF(4,
"lwgeom_dimension got type %s",
1315 return ( closed ? 3 : 2 );
1322 for( i = 0; i < col->
ngeoms; i++ )
1325 maxdim = ( dim > maxdim ? dim : maxdim );
1330 lwerror(
"%s: unsupported input geometry type: %s",
1375 for( i = 0; i < col->
ngeoms; i++ )
1399 int dimensionality = 0;
1400 for ( i = 0; i < col->
ngeoms; i++ )
1403 if ( d > dimensionality )
1406 return dimensionality;
1413 LWDEBUGF(3,
"lwgeom_dimensionality got type %s",
1447 lwerror(
"lwgeom_dimensionality: unsupported input geometry type: %s",
1471 LWDEBUGF(4,
"lwgeom_flip_coordinates, got type: %s",
1490 for (i=0; i<poly->
nrings; i++)
1511 for (i=0; i<col->
ngeoms; i++)
1518 lwerror(
"lwgeom_swap_ordinates: unsupported geometry type: %s",
1524 if ( in->
bbox && (o1 < 2 || o2 < 2) )
1534 LWDEBUGF(4,
"entered with srid=%d",srid);
1542 for ( i = 0; i < col->
ngeoms; i++ )
1562 return geometry_modified;
1567 uint32_t npoints = pa->
npoints;
1569 geometry_modified = npoints != pa->
npoints;
1583 for (i = 0; i < g->
nrings; i++)
1587 uint32_t npoints = 0;
1593 geometry_modified |= npoints != pa->
npoints;
1609 double tolsq = tolerance*tolerance;
1610 uint32_t i, j, n = 0;
1618 return geometry_modified;
1629 for (i = 0; i < mpt->
ngeoms; i++)
1634 for (j = 0; j < n; j++)
1655 geometry_modified = mpt->
ngeoms != n;
1657 if (use_heap)
lwfree(out);
1663 return geometry_modified;
1679 for (i = 0; i < col->
ngeoms; i++)
1690 col->
geoms[j++] = g;
1703 if (geometry_modified)
1707 return geometry_modified;
1724 if (preserve_collapsed)
1740 uint32_t in_npoints = pa->
npoints;
1742 modified = in_npoints != pa->
npoints;
1747 if (preserve_collapsed)
1759 if (pa->
npoints == 2 && !preserve_collapsed)
1770 for (i = 0; i < g->
nrings; i++)
1774 int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1778 uint32_t in_npoints = pa->
npoints;
1780 modified |= in_npoints != pa->
npoints;
1787 for (i = 0; i < g->
nrings; i++)
1816 for (i = 0; i < col->
ngeoms; i++)
1827 col->
geoms[j++] = g;
1877 for ( i = 0; i < col->
ngeoms; i++ )
1896 double perimeter = 0.0;
1899 for ( i = 0; i < col->
ngeoms; i++ )
1918 double perimeter = 0.0;
1921 for ( i = 0; i < col->
ngeoms; i++ )
1940 double length = 0.0;
1943 for ( i = 0; i < col->
ngeoms; i++ )
1962 double length = 0.0;
1965 for ( i = 0; i < col->
ngeoms; i++ )
1994 for( i = 0; i < p->
nrings; i++ )
2001 for( i = 0; i < c->
nrings; i++ )
2010 for( i = 0; i < c->
ngeoms; i++ )
2048 for( i = 0; i < p->
nrings; i++ )
2055 for( i = 0; i < c->
nrings; i++ )
2064 for( i = 0; i < c->
ngeoms; i++ )
2105 lwerror(
"lwgeom_construct_empty: unsupported geometry type: %s",
2117 switch( lwgeom->
type )
2147 switch ( geom->
type )
2169 if (!ply->
rings)
return;
2178 for (i = 0; i < ply->
nrings; i++)
2188 for (i = 1; i < ply->
nrings; i++)
2196 ply->
rings[j++] = pa;
2216 if (!col->
geoms)
return;
2217 for (i = 0; i < col->
ngeoms; i++)
2228 col->
geoms[j++] = g;
2235 lwerror(
"%s: Unsupported geometry type: %s", __func__,
2255 uint32_t maxvertices,
2263 uint32_t maxvertices,
2268 const uint32_t maxdepth = 50;
2281 double width = clip.
xmax - clip.
xmin;
2282 double height = clip.
ymax - clip.
ymin;
2287 if ( width == 0.0 && height == 0.0 )
2313 for (uint32_t i = 0; i < incol->
ngeoms; i++ )
2327 if ( depth > maxdepth )
2340 if (nvertices <= maxvertices)
2346 uint8_t split_ordinate = (width > height) ? 0 : 1;
2347 double center = (split_ordinate == 0) ? (clip.
xmin + clip.
xmax) / 2 : (clip.
ymin + clip.
ymax) / 2;
2348 double pivot = DBL_MAX;
2351 uint32_t ring_to_trim = 0;
2352 double ring_area = 0;
2353 double pivot_eps = DBL_MAX;
2354 double pt_eps = DBL_MAX;
2362 for (uint32_t i = 1; i < lwpoly->
nrings; i++)
2365 if (current_ring_area >= ring_area)
2367 ring_area = current_ring_area;
2373 pa = lwpoly->
rings[ring_to_trim];
2376 for (uint32_t i = 0; i < pa->
npoints; i++)
2379 if (split_ordinate == 0)
2383 pt_eps = fabs(pt - center);
2384 if (pivot_eps > pt_eps)
2391 GBOX subbox1, subbox2;
2395 if (
pivot == DBL_MAX)
2398 if (split_ordinate == 0)
2403 subbox1.
xmax = subbox2.
xmin = center;
2410 subbox1.
ymax = subbox2.
ymin = center;
2444 static uint32_t startdepth = 0;
2445 static uint32_t minmaxvertices = 5;
2453 if ( maxvertices < minmaxvertices )
2456 lwerror(
"%s: cannot subdivide to fewer than %d vertices per output", __func__, minmaxvertices);
2479 lwnotice(
"Geometry is not a LINESTRING");
2488 int32_t bits_needed = ceil(significant_digits / log10(2));
2490 if (bits_needed > 52)
2494 else if (bits_needed < 1)
2507 int digits_left_of_decimal = (int) (1 + log10(fabs(d)));
2509 uint64_t mask = 0xffffffffffffffffULL << (52 - bits_needed);
2511 size_t dsz =
sizeof(d) <
sizeof(dint) ?
sizeof(d) :
sizeof(dint);
2513 memcpy(&dint, &d, dsz);
2515 memcpy(&d, &dint, dsz);
2550 int finite = isfinite(p.
x) &&
2552 (hasz ? isfinite(p.
z) : 1) &&
2553 (hasm ? isfinite(p.
m) : 1);
char result[OUT_DOUBLE_BUFFER_SIZE]
int gbox_same(const GBOX *g1, const GBOX *g2)
Check if 2 given Gbox are the same.
void gbox_duplicate(const GBOX *original, GBOX *duplicate)
Copy the values of original GBOX into duplicate.
int lwgeom_calculate_gbox_cartesian(const LWGEOM *lwgeom, GBOX *gbox)
Calculate the 2-4D bounding box of a geometry.
GBOX * gbox_new(lwflags_t flags)
Create a new gbox with the dimensionality indicated by the flags.
GBOX * gbox_clone(const GBOX *gbox)
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
void lwmpoint_free(LWMPOINT *mpt)
LWPOINTITERATOR * lwpointiterator_create(const LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM*.
LWLINE * lwline_segmentize2d(const LWLINE *line, double dist)
void lwpoint_free(LWPOINT *pt)
LWCOLLECTION * lwcollection_segmentize2d(const LWCOLLECTION *coll, double dist)
void lwmpoly_free(LWMPOLY *mpoly)
LWCURVEPOLY * lwcurvepoly_construct_from_lwpoly(LWPOLY *lwpoly)
Construct an equivalent curve polygon from a polygon.
int lwpointiterator_next(LWPOINTITERATOR *s, POINT4D *p)
Attempts to assign the next point in the iterator to p, and advances the iterator to the next point.
void lwtin_free(LWTIN *tin)
int lwgeom_calculate_gbox_geodetic(const LWGEOM *geom, GBOX *gbox)
Calculate the geodetic bounding box for an LWGEOM.
LWGEOM * lwgeom_stroke(const LWGEOM *geom, uint32_t perQuad)
Convert type with arcs into equivalent linearized type.
#define FLAGS_SET_BBOX(flags, value)
int lwpointiterator_peek(LWPOINTITERATOR *s, POINT4D *p)
Attempts to assigns the next point in the iterator to p.
void lwpointiterator_destroy(LWPOINTITERATOR *s)
Free all memory associated with the iterator.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#define FLAGS_GET_Z(flags)
LWTRIANGLE * lwtriangle_construct_empty(int32_t srid, char hasz, char hasm)
LWPOLY * lwpoly_construct_envelope(int32_t srid, double x1, double y1, double x2, double y2)
int lwpointiterator_modify_next(LWPOINTITERATOR *s, const POINT4D *p)
Attempts to replace the next point int the iterator with p, and advances the iterator to the next poi...
#define FLAGS_NDIMS(flags)
void lwcircstring_free(LWCIRCSTRING *curve)
void lwtriangle_free(LWTRIANGLE *triangle)
#define POLYHEDRALSURFACETYPE
LWPOINTITERATOR * lwpointiterator_create_rw(LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM* Supports modification of coordinates during iterat...
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
#define FLAGS_GET_M(flags)
void lwcollection_free(LWCOLLECTION *col)
LWGEOM * lwgeom_intersection_prec(const LWGEOM *geom1, const LWGEOM *geom2, double gridSize)
void ptarray_free(POINTARRAY *pa)
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
#define FLAGS_GET_SOLID(flags)
#define FLAGS_GET_ZM(flags)
LWPOLY * lwpoly_segmentize2d(const LWPOLY *line, double dist)
int lwpointiterator_has_next(LWPOINTITERATOR *s)
Returns LW_TRUE if there is another point available in the iterator.
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
#define FLAGS_SET_GEODETIC(flags, value)
void * lwalloc(size_t size)
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
void lwpsurface_free(LWPSURFACE *psurf)
void lwpoly_free(LWPOLY *poly)
void lwmline_free(LWMLINE *mline)
#define LW_TRUE
Return types for functions with status returns.
int lwline_is_trajectory(const LWLINE *geom)
LWCURVEPOLY * lwcurvepoly_construct_empty(int32_t srid, char hasz, char hasm)
#define SRID_UNKNOWN
Unknown SRID value.
LWPOLY * lwpoly_from_lwlines(const LWLINE *shell, uint32_t nholes, const LWLINE **holes)
LWCOMPOUND * lwcompound_construct_from_lwline(const LWLINE *lwpoly)
Construct an equivalent compound curve from a linestring.
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
LWCIRCSTRING * lwcircstring_construct_empty(int32_t srid, char hasz, char hasm)
void lwline_free(LWLINE *line)
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
#define FLAGS_GET_GEODETIC(flags)
enum LWORD_T LWORD
Ordinate names.
double lwline_length_2d(const LWLINE *line)
void ptarray_longitude_shift(POINTARRAY *pa)
Longitude shift for a pointarray.
LWLINE * lwline_clone_deep(const LWLINE *lwgeom)
double lwcircstring_length_2d(const LWCIRCSTRING *circ)
LWPOINT * lwpoint_clone(const LWPOINT *lwgeom)
int lwcircstring_is_closed(const LWCIRCSTRING *curve)
void ptarray_reverse_in_place(POINTARRAY *pa)
LWLINE * lwline_clone(const LWLINE *lwgeom)
char lwcollection_same(const LWCOLLECTION *p1, const LWCOLLECTION *p2)
check for same geometry composition
double lwtriangle_area(const LWTRIANGLE *triangle)
Find the area of the outer ring.
double lwcompound_length_2d(const LWCOMPOUND *comp)
uint32_t lwpoly_count_vertices(LWPOLY *poly)
double ptarray_signed_area(const POINTARRAY *pa)
Returns the area in cartesian units.
#define LW_ON_INTERRUPT(x)
int lwline_is_closed(const LWLINE *line)
char lwtriangle_same(const LWTRIANGLE *p1, const LWTRIANGLE *p2)
int lwpoly_startpoint(const LWPOLY *lwpoly, POINT4D *pt)
LWPOINT * lwpoint_force_dims(const LWPOINT *lwpoint, int hasz, int hasm, double zval, double mval)
int lwcollection_startpoint(const LWCOLLECTION *col, POINT4D *pt)
int ptarray_startpoint(const POINTARRAY *pa, POINT4D *pt)
int lwcompound_is_closed(const LWCOMPOUND *curve)
double lwtriangle_perimeter_2d(const LWTRIANGLE *triangle)
int lwpoly_is_clockwise(LWPOLY *poly)
void ptarray_grid_in_place(POINTARRAY *pa, const gridspec *grid)
Snap to grid.
double lwpoly_area(const LWPOLY *poly)
Find the area of the outer ring - sum (area of inner rings).
int lwtriangle_is_clockwise(LWTRIANGLE *triangle)
char lwline_same(const LWLINE *p1, const LWLINE *p2)
void ptarray_remove_repeated_points_in_place(POINTARRAY *pa, double tolerance, uint32_t min_points)
double lwtriangle_perimeter(const LWTRIANGLE *triangle)
void ptarray_simplify_in_place(POINTARRAY *pa, double tolerance, uint32_t minpts)
LWLINE * lwline_force_dims(const LWLINE *lwline, int hasz, int hasm, double zval, double mval)
double lwcompound_length(const LWCOMPOUND *comp)
LWCOLLECTION * lwcollection_clone_deep(const LWCOLLECTION *lwgeom)
Deep clone LWCOLLECTION object.
LWCOLLECTION * lwcollection_force_dims(const LWCOLLECTION *lwcol, int hasz, int hasm, double zval, double mval)
void lwtriangle_force_clockwise(LWTRIANGLE *triangle)
#define FP_TOLERANCE
Floating point comparators.
void ptarray_scale(POINTARRAY *pa, const POINT4D *factor)
WARNING, make sure you send in only 16-member double arrays or obviously things will go pear-shaped f...
void ptarray_affine(POINTARRAY *pa, const AFFINE *affine)
Affine transform a pointarray.
int lwpsurface_is_closed(const LWPSURFACE *psurface)
double lwcurvepoly_perimeter(const LWCURVEPOLY *poly)
char lwpoly_same(const LWPOLY *p1, const LWPOLY *p2)
double lwline_length(const LWLINE *line)
void lwpoly_force_clockwise(LWPOLY *poly)
void ptarray_swap_ordinates(POINTARRAY *pa, LWORD o1, LWORD o2)
Swap ordinate values o1 and o2 on a given POINTARRAY.
double lwpoly_perimeter_2d(const LWPOLY *poly)
Compute the sum of polygon rings length (forcing 2d computation).
int lwtin_is_closed(const LWTIN *tin)
char lwcircstring_same(const LWCIRCSTRING *p1, const LWCIRCSTRING *p2)
LWPOLY * lwpoly_clone_deep(const LWPOLY *lwgeom)
double lwcircstring_length(const LWCIRCSTRING *circ)
uint32_t lwcollection_count_vertices(LWCOLLECTION *col)
double lwcurvepoly_area(const LWCURVEPOLY *curvepoly)
This should be rewritten to make use of the curve itself.
LWCOLLECTION * lwcollection_clone(const LWCOLLECTION *lwgeom)
Clone LWCOLLECTION object.
int lwpoly_is_closed(const LWPOLY *poly)
LWPOLY * lwpoly_clone(const LWPOLY *lwgeom)
void ptarray_copy_point(POINTARRAY *pa, uint32_t from, uint32_t to)
uint32_t lwline_count_vertices(LWLINE *line)
double lwcurvepoly_perimeter_2d(const LWCURVEPOLY *poly)
double lwpoly_perimeter(const LWPOLY *poly)
Compute the sum of polygon rings length.
LWTRIANGLE * lwtriangle_clone(const LWTRIANGLE *lwgeom)
char lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
LWCIRCSTRING * lwcircstring_clone(const LWCIRCSTRING *curve)
LWPOLY * lwpoly_force_dims(const LWPOLY *lwpoly, int hasz, int hasm, double zval, double mval)
int p2d_same(const POINT2D *p1, const POINT2D *p2)
int lwgeom_is_closed(const LWGEOM *geom)
Return true or false depending on whether a geometry is a linear feature that closes on itself.
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
LWGEOM * lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm, double zval, double mval)
static double trim_preserve_decimal_digits(double d, int32_t decimal_digits)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
LWGEOM * lwcompound_as_lwgeom(const LWCOMPOUND *obj)
void lwgeom_set_geodetic(LWGEOM *geom, int value)
Set the FLAGS geodetic bit on geometry an all sub-geometries and pointlists.
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
LWGEOM * lwgeom_simplify(const LWGEOM *igeom, double dist, int preserve_collapsed)
Simplification.
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
int lwgeom_ndims(const LWGEOM *geom)
Return the number of dimensions (2, 3, 4) in a geometry.
uint32_t lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
int lwgeom_is_collection(const LWGEOM *geom)
Determine whether a LWGEOM can contain sub-geometries or not.
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
void lwgeom_trim_bits_in_place(LWGEOM *geom, int32_t prec_x, int32_t prec_y, int32_t prec_z, int32_t prec_m)
Trim the bits of an LWGEOM in place, to optimize it for compression.
void lwgeom_longitude_shift(LWGEOM *lwgeom)
LWGEOM * lwgeom_segmentize2d(const LWGEOM *lwgeom, double dist)
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
double lwgeom_perimeter_2d(const LWGEOM *geom)
int lwpoint_inside_circle(const LWPOINT *p, double cx, double cy, double rad)
LWGEOM * lwmline_as_lwgeom(const LWMLINE *obj)
static uint8_t bits_for_precision(int32_t significant_digits)
LWGEOM * lwmpoint_as_lwgeom(const LWMPOINT *obj)
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
int lwgeom_is_trajectory(const LWGEOM *geom)
Return LW_TRUE or LW_FALSE depending on whether or not a geometry is a linestring with measure value ...
LWGEOM * lwgeom_force_sfs(LWGEOM *geom, int version)
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep-clone an LWGEOM object.
LWMPOLY * lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
LWGEOM * lwgeom_force_3dm(const LWGEOM *geom, double mval)
int lwgeom_has_srid(const LWGEOM *geom)
Return true or false depending on whether a geometry has a valid SRID set.
LWGEOM * lwgeom_force_4d(const LWGEOM *geom, double zval, double mval)
double lwgeom_length(const LWGEOM *geom)
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
int lwgeom_remove_repeated_points_in_place(LWGEOM *geom, double tolerance)
LWGEOM * lwpsurface_as_lwgeom(const LWPSURFACE *obj)
LWGEOM * lwgeom_force_3dz(const LWGEOM *geom, double zval)
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
LWGEOM * lwmpoly_as_lwgeom(const LWMPOLY *obj)
int lwtype_is_collection(uint8_t type)
Return TRUE if the geometry may contain sub-geometries, i.e.
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
int lwgeom_isfinite(const LWGEOM *lwgeom)
Check if a LWGEOM has any non-finite (NaN or Inf) coordinates.
static int lwcollection_dimensionality(const LWCOLLECTION *col)
LWTRIANGLE * lwgeom_as_lwtriangle(const LWGEOM *lwgeom)
double lwgeom_area(const LWGEOM *geom)
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count points in an LWGEOM.
LWGEOM * lwgeom_reverse(const LWGEOM *geom)
int lwgeom_dimension(const LWGEOM *geom)
For an LWGEOM, returns 0 for points, 1 for lines, 2 for polygons, 3 for volume, and the max dimension...
LWCOLLECTION * lwgeom_subdivide(const LWGEOM *geom, uint32_t maxvertices)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
LWGEOM * lwgeom_as_curve(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate CURVE* type.
void lwgeom_swap_ordinates(LWGEOM *in, LWORD o1, LWORD o2)
Swap ordinate values in every vertex of the geometry.
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
uint8_t lwtype_multitype(uint8_t type)
LWCURVEPOLY * lwgeom_as_lwcurvepoly(const LWGEOM *lwgeom)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwg)
Get a non-empty geometry bounding box, computing and caching it if not already there.
double lwgeom_length_2d(const LWGEOM *geom)
uint32_t lwgeom_count_rings(const LWGEOM *geom)
Count rings in an LWGEOM.
void lwgeom_reverse_in_place(LWGEOM *geom)
Reverse vertex order of LWGEOM.
void lwgeom_force_clockwise(LWGEOM *lwgeom)
Force Right-hand-rule on LWGEOM polygons.
int lwgeom_is_solid(const LWGEOM *geom)
Return LW_TRUE if geometry has SOLID flag.
LWGEOM * lwtin_as_lwgeom(const LWTIN *obj)
LWGEOM * lwcurvepoly_as_lwgeom(const LWCURVEPOLY *obj)
uint8_t MULTITYPE[NUMTYPES]
Look-up for the correct MULTI* type promotion for singleton types.
LWTIN * lwgeom_as_lwtin(const LWGEOM *lwgeom)
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate the gbox for this geometry, a cartesian box or geodetic box, depending on how it is flagged...
LWGEOM * lwcircstring_as_lwgeom(const LWCIRCSTRING *obj)
LWPSURFACE * lwgeom_as_lwpsurface(const LWGEOM *lwgeom)
void lwgeom_add_bbox_deep(LWGEOM *lwgeom, GBOX *gbox)
Compute a box for geom and all sub-geometries, if not already computed.
int lwgeom_dimensionality(const LWGEOM *geom)
Return the dimensionality (relating to point/line/poly) of an lwgeom.
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
void lwgeom_free(LWGEOM *lwgeom)
LWGEOM * lwtriangle_as_lwgeom(const LWTRIANGLE *obj)
LWCIRCSTRING * lwgeom_as_lwcircstring(const LWGEOM *lwgeom)
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
static void lwgeom_subdivide_recursive(const LWGEOM *geom, uint8_t dimension, uint32_t maxvertices, uint32_t depth, LWCOLLECTION *col, double gridSize)
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
double lwgeom_perimeter(const LWGEOM *geom)
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
void lwgeom_scale(LWGEOM *geom, const POINT4D *factor)
LWCOLLECTION * lwgeom_subdivide_prec(const LWGEOM *geom, uint32_t maxvertices, double gridSize)
LWGEOM * lwgeom_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
LWGEOM * lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid)
int lwgeom_is_clockwise(LWGEOM *lwgeom)
Check clockwise orientation on LWGEOM polygons.
int lwgeom_simplify_in_place(LWGEOM *geom, double epsilon, int preserve_collapsed)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Ensure there's a box in the LWGEOM.
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
void lwgeom_drop_srid(LWGEOM *lwgeom)
void lwgeom_grid_in_place(LWGEOM *geom, const gridspec *grid)
LWCOMPOUND * lwgeom_as_lwcompound(const LWGEOM *lwgeom)
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
static double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
static double pivot(double *left, double *right)