57 for (i=0; i<coll->
ngeoms; i++)
81 for (i=0; i < coll->
ngeoms; i++)
147 for (i=0; i<col->
ngeoms; i++)
163 if ( lwgeom == NULL )
return NULL;
172 if ( lwgeom == NULL )
return NULL;
181 if ( lwgeom == NULL )
return NULL;
190 if ( lwgeom == NULL )
return NULL;
199 if ( lwgeom == NULL )
return NULL;
208 if ( lwgeom == NULL )
return NULL;
217 if ( lwgeom == NULL )
return NULL;
226 if ( lwgeom == NULL )
return NULL;
235 if ( lwgeom == NULL )
return NULL;
244 if ( lwgeom == NULL )
return NULL;
262 return (
LWTIN *)lwgeom;
278 if ( obj == NULL )
return NULL;
283 if ( obj == NULL )
return NULL;
288 if ( obj == NULL )
return NULL;
293 if ( obj == NULL )
return NULL;
298 if ( obj == NULL )
return NULL;
303 if ( obj == NULL )
return NULL;
308 if ( obj == NULL )
return NULL;
313 if ( obj == NULL )
return NULL;
318 if ( obj == NULL )
return NULL;
323 if ( obj == NULL )
return NULL;
328 if ( obj == NULL )
return NULL;
354 if (
type > 15)
return 0;
388 box = ogeoms[0]->
bbox;
389 ogeoms[0]->
bbox = NULL;
453 lwerror(
"lwgeom_release: someone called on 0x0");
460 LWDEBUGF(3,
"lwgeom_release: releasing bbox. %p", lwgeom->
bbox);
475 LWDEBUGF(2,
"lwgeom_clone called with %p, %s",
478 switch (lwgeom->
type)
513 LWDEBUGF(2,
"lwgeom_clone called with %p, %s",
516 switch (lwgeom->
type)
556 lwerror(
"Error writing geom %p to WKT", lwgeom);
575 LWDEBUGF(2,
"lwgeom_same(%s, %s) called",
579 if ( lwgeom1->
type != lwgeom2->
type )
588 LWDEBUG(3,
" ZM flags differ");
594 if ( lwgeom1->
bbox && lwgeom2->
bbox )
599 LWDEBUG(3,
" bounding boxes differ");
606 switch (lwgeom1->
type)
636 lwerror(
"lwgeom_same: unsupported geometry type: %s",
649 if ( ! p || ! p->
point )
682 if ( lwgeom->
bbox )
return;
702 if ( ! ( gbox || lwgeom->
bbox ) )
707 else if ( gbox && ! lwgeom->
bbox )
717 for ( i = 0; i < lwcol->
ngeoms; i++ )
755 switch (lwgeom->
type)
852 for ( i = 0; i < col->
ngeoms; i++ )
882 for ( i = 0; i < col->
ngeoms; i++ )
898 for ( i = 0; i < col->
ngeoms; i++ )
939 if ( ! geom )
return 0;
972 for ( i = 0; i < ply->
nrings; i++ )
980 for ( i = 0; i < col->
ngeoms; i++ )
993 switch (lwgeom->
type)
1011 for (i=0; i<poly->
nrings; i++)
1025 for (i=0; i<coll->
ngeoms; i++)
1029 lwerror(
"lwgeom_longitude_shift: unsupported geom type: %s",
1065 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",
1272 LWDEBUGF(3,
"counted %d vertices", result);
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",
1362 result = ((
LWPOLY *)geom)->nrings;
1375 for( i = 0; i < col->
ngeoms; i++ )
1383 LWDEBUGF(3,
"counted %d rings", result);
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 static uint32_t out_stack_size = 32;
1610 double tolsq = tolerance*tolerance;
1611 uint32_t i, j, n = 0;
1614 LWPOINT *out_stack[out_stack_size];
1615 int use_heap = (mpt->
ngeoms > out_stack_size);
1619 return geometry_modified;
1630 for (i = 0; i < mpt->
ngeoms; i++)
1635 for (j = 0; j < n; j++)
1656 geometry_modified = mpt->
ngeoms != n;
1658 if (use_heap)
lwfree(out);
1664 return geometry_modified;
1680 for (i = 0; i < col->
ngeoms; i++)
1691 col->
geoms[j++] = g;
1704 if (geometry_modified)
1708 return geometry_modified;
1725 if (preserve_collapsed)
1741 uint32_t in_npoints = pa->
npoints;
1743 modified = in_npoints != pa->
npoints;
1748 if (preserve_collapsed)
1760 if (pa->
npoints == 2 && !preserve_collapsed)
1771 for (i = 0; i < g->
nrings; i++)
1775 int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1779 uint32_t in_npoints = pa->
npoints;
1781 modified |= in_npoints != pa->
npoints;
1788 for (i = 0; i < g->
nrings; i++)
1817 for (i = 0; i < col->
ngeoms; i++)
1828 col->
geoms[j++] = g;
1878 for ( i = 0; i < col->
ngeoms; i++ )
1897 double perimeter = 0.0;
1900 for ( i = 0; i < col->
ngeoms; i++ )
1919 double perimeter = 0.0;
1922 for ( i = 0; i < col->
ngeoms; i++ )
1941 double length = 0.0;
1944 for ( i = 0; i < col->
ngeoms; i++ )
1963 double length = 0.0;
1966 for ( i = 0; i < col->
ngeoms; i++ )
1995 for( i = 0; i < p->
nrings; i++ )
2002 for( i = 0; i < c->
nrings; i++ )
2011 for( i = 0; i < c->
ngeoms; i++ )
2049 for( i = 0; i < p->
nrings; i++ )
2056 for( i = 0; i < c->
nrings; i++ )
2065 for( i = 0; i < c->
ngeoms; i++ )
2106 lwerror(
"lwgeom_construct_empty: unsupported geometry type: %s",
2118 switch( lwgeom->
type )
2148 switch ( geom->
type )
2170 if (!ply->
rings)
return;
2179 for (i = 0; i < ply->
nrings; i++)
2189 for (i = 1; i < ply->
nrings; i++)
2197 ply->
rings[j++] = pa;
2217 if (!col->
geoms)
return;
2218 for (i = 0; i < col->
ngeoms; i++)
2229 col->
geoms[j++] = g;
2236 lwerror(
"%s: Unsupported geometry type: %s", __func__,
2256 uint32_t maxvertices,
2263 uint32_t maxvertices,
2267 const uint32_t maxdepth = 50;
2278 double width = clip.
xmax - clip.
xmin;
2279 double height = clip.
ymax - clip.
ymin;
2284 if ( width == 0.0 && height == 0.0 )
2310 for (uint32_t i = 0; i < incol->
ngeoms; i++ )
2324 if ( depth > maxdepth )
2337 if (nvertices <= maxvertices)
2343 uint8_t split_ordinate = (width > height) ? 0 : 1;
2344 double center = (split_ordinate == 0) ? (clip.
xmin + clip.
xmax) / 2 : (clip.
ymin + clip.
ymax) / 2;
2345 double pivot = DBL_MAX;
2348 uint32_t ring_to_trim = 0;
2349 double ring_area = 0;
2350 double pivot_eps = DBL_MAX;
2351 double pt_eps = DBL_MAX;
2359 for (uint32_t i = 1; i < lwpoly->
nrings; i++)
2362 if (current_ring_area >= ring_area)
2364 ring_area = current_ring_area;
2370 pa = lwpoly->
rings[ring_to_trim];
2373 for (uint32_t i = 0; i < pa->
npoints; i++)
2376 if (split_ordinate == 0)
2380 pt_eps = fabs(pt - center);
2381 if (pivot_eps > pt_eps)
2388 GBOX subbox1, subbox2;
2392 if (
pivot == DBL_MAX)
2395 if (split_ordinate == 0)
2400 subbox1.
xmax = subbox2.
xmin = center;
2407 subbox1.
ymax = subbox2.
ymin = center;
2441 static uint32_t startdepth = 0;
2442 static uint32_t minmaxvertices = 5;
2450 if ( maxvertices < minmaxvertices )
2453 lwerror(
"%s: cannot subdivide to fewer than %d vertices per output", __func__, minmaxvertices);
2468 lwnotice(
"Geometry is not a LINESTRING");
2477 int32_t bits_needed = ceil(significant_digits / log10(2));
2479 if (bits_needed > 52)
2483 else if (bits_needed < 1)
2496 int digits_left_of_decimal = (int) (1 + log10(fabs(d)));
2498 uint64_t mask = 0xffffffffffffffffULL << (52 - bits_needed);
2500 size_t dsz =
sizeof(d) <
sizeof(dint) ?
sizeof(d) :
sizeof(dint);
2502 memcpy(&dint, &d, dsz);
2504 memcpy(&d, &dint, dsz);
2539 int finite = isfinite(p.
x) &&
2541 (hasz ? isfinite(p.
z) : 1) &&
2542 (hasm ? isfinite(p.
m) : 1);
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.
LWGEOM * lwgeom_intersection(const LWGEOM *geom1, const LWGEOM *geom2)
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)
#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)
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_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.
int lwline_is_closed(const LWLINE *line)
char lwtriangle_same(const LWTRIANGLE *p1, const LWTRIANGLE *p2)
int lwpoly_startpoint(const LWPOLY *lwpoly, POINT4D *pt)
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)
double lwcompound_length(const LWCOMPOUND *comp)
LWCOLLECTION * lwcollection_clone_deep(const LWCOLLECTION *lwgeom)
Deep clone LWCOLLECTION object.
void lwtriangle_force_clockwise(LWTRIANGLE *triangle)
LWPOINT * lwpoint_force_dims(const LWPOINT *lwpoint, int hasz, int hasm)
#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)
LWPOLY * lwpoly_force_dims(const LWPOLY *lwpoly, int hasz, int hasm)
double lwcurvepoly_perimeter(const LWCURVEPOLY *poly)
LWCOLLECTION * lwcollection_force_dims(const LWCOLLECTION *lwcol, int hasz, int hasm)
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)
LWLINE * lwline_force_dims(const LWLINE *lwline, int hasz, int hasm)
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)
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.
LWGEOM * lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm)
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
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.
LWGEOM * lwgeom_force_4d(const LWGEOM *geom)
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)
int lwgeom_has_srid(const LWGEOM *geom)
Return true or false depending on whether a geometry has a valid SRID set.
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)
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.
static void lwgeom_subdivide_recursive(const LWGEOM *geom, uint8_t dimension, uint32_t maxvertices, uint32_t depth, LWCOLLECTION *col)
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 * lwgeom_force_3dm(const LWGEOM *geom)
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)
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)
LWGEOM * lwgeom_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
LWGEOM * lwgeom_force_3dz(const LWGEOM *geom)
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)