2266{
2267 const uint32_t maxdepth = 50;
2268
2269 if (!geom)
2270 return;
2271
2273 if (!box_in)
2274 return;
2275
2278 double width = clip.
xmax - clip.
xmin;
2279 double height = clip.
ymax - clip.
ymin;
2280
2283
2284 if ( width == 0.0 && height == 0.0 )
2285 {
2288 return;
2289 }
2290
2291 if (width == 0.0)
2292 {
2296 }
2297 if (height == 0.0)
2298 {
2302 }
2303
2304
2306 {
2308
2309
2310 for (uint32_t i = 0; i < incol->
ngeoms; i++ )
2312 return;
2313 }
2314
2316 {
2317
2318
2319 return;
2320 }
2321
2322
2323
2324 if ( depth > maxdepth )
2325 {
2327 return;
2328 }
2329
2331
2332
2333 if (nvertices == 0)
2334 return;
2335
2336
2337 if (nvertices <= maxvertices)
2338 {
2340 return;
2341 }
2342
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;
2347 {
2348 uint32_t ring_to_trim = 0;
2349 double ring_area = 0;
2350 double pivot_eps = DBL_MAX;
2351 double pt_eps = DBL_MAX;
2354
2355
2357 {
2358
2359 for (uint32_t i = 1; i < lwpoly->
nrings; i++)
2360 {
2362 if (current_ring_area >= ring_area)
2363 {
2364 ring_area = current_ring_area;
2365 ring_to_trim = i;
2366 }
2367 }
2368 }
2369
2370 pa = lwpoly->
rings[ring_to_trim];
2371
2372
2373 for (uint32_t i = 0; i < pa->
npoints; i++)
2374 {
2375 double pt;
2376 if (split_ordinate == 0)
2378 else
2380 pt_eps = fabs(pt - center);
2381 if (pivot_eps > pt_eps)
2382 {
2384 pivot_eps = pt_eps;
2385 }
2386 }
2387 }
2388 GBOX subbox1, subbox2;
2391
2392 if (
pivot == DBL_MAX)
2394
2395 if (split_ordinate == 0)
2396 {
2399 else
2400 subbox1.
xmax = subbox2.
xmin = center;
2401 }
2402 else
2403 {
2406 else
2407 subbox1.
ymax = subbox2.
ymin = center;
2408 }
2409
2410 ++depth;
2411
2412 {
2419 {
2422 }
2423 }
2424 {
2431 {
2434 }
2435 }
2436}
void gbox_duplicate(const GBOX *original, GBOX *duplicate)
Copy the values of original GBOX into duplicate.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
LWPOLY * lwpoly_construct_envelope(int32_t srid, double x1, double y1, double x2, double y2)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
LWGEOM * lwgeom_intersection(const LWGEOM *geom1, const LWGEOM *geom2)
#define POLYHEDRALSURFACETYPE
#define LW_TRUE
Return types for functions with status returns.
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
double ptarray_signed_area(const POINTARRAY *pa)
Returns the area in cartesian units.
#define FP_TOLERANCE
Floating point comparators.
int lwgeom_is_collection(const LWGEOM *geom)
Determine whether a LWGEOM can contain sub-geometries or not.
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count points in an LWGEOM.
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...
static void lwgeom_subdivide_recursive(const LWGEOM *geom, uint8_t dimension, uint32_t maxvertices, uint32_t depth, LWCOLLECTION *col)
void lwgeom_free(LWGEOM *lwgeom)
int lwgeom_simplify_in_place(LWGEOM *geom, double epsilon, int preserve_collapsed)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwg)
Get a non-empty geometry bounding box, computing and caching it if not already there.
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep-clone an LWGEOM object.
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
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 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 pivot(double *left, double *right)