2416{
2417 const uint32_t maxdepth = 50;
2418
2419 if (!geom)
2420 return;
2421
2423 if (!box_in)
2424 return;
2425
2427
2430 double width = clip.
xmax - clip.
xmin;
2431 double height = clip.
ymax - clip.
ymin;
2432
2435
2436 if ( width == 0.0 && height == 0.0 )
2437 {
2440 return;
2441 }
2442
2443 if (width == 0.0)
2444 {
2448 }
2449 if (height == 0.0)
2450 {
2454 }
2455
2456
2458 {
2460
2461
2462 for (uint32_t i = 0; i < incol->
ngeoms; i++ )
2464 return;
2465 }
2466
2468 {
2469
2470
2471 return;
2472 }
2473
2474
2475
2476 if ( depth > maxdepth )
2477 {
2479 return;
2480 }
2481
2483
2484
2485 if (nvertices == 0)
2486 return;
2487
2488
2489 if (nvertices <= maxvertices)
2490 {
2492 return;
2493 }
2494
2495 uint8_t split_ordinate = (width > height) ? 0 : 1;
2496 double center = (split_ordinate == 0) ? (clip.
xmin + clip.
xmax) / 2 : (clip.
ymin + clip.
ymax) / 2;
2497 double pivot = DBL_MAX;
2499 {
2500 uint32_t ring_to_trim = 0;
2501 double ring_area = 0;
2502 double pivot_eps = DBL_MAX;
2503 double pt_eps = DBL_MAX;
2506
2507
2509 {
2510
2511 for (uint32_t i = 1; i < lwpoly->
nrings; i++)
2512 {
2514 if (current_ring_area >= ring_area)
2515 {
2516 ring_area = current_ring_area;
2517 ring_to_trim = i;
2518 }
2519 }
2520 }
2521
2522 pa = lwpoly->
rings[ring_to_trim];
2523
2524
2525 for (uint32_t i = 0; i < pa->
npoints; i++)
2526 {
2527 double pt;
2528 if (split_ordinate == 0)
2530 else
2532 pt_eps = fabs(pt - center);
2533 if (pivot_eps > pt_eps)
2534 {
2536 pivot_eps = pt_eps;
2537 }
2538 }
2539 }
2540 GBOX subbox1, subbox2;
2543
2544 if (
pivot == DBL_MAX)
2546
2547 if (split_ordinate == 0)
2548 {
2551 else
2552 subbox1.
xmax = subbox2.
xmin = center;
2553 }
2554 else
2555 {
2558 else
2559 subbox1.
ymax = subbox2.
ymin = center;
2560 }
2561
2562 ++depth;
2563
2564 {
2571 {
2574 }
2575 }
2576 {
2583 {
2586 }
2587 }
2588}
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.
LWGEOM * lwgeom_intersection_prec(const LWGEOM *geom1, const LWGEOM *geom2, double gridSize)
LWPOLY * lwpoly_construct_envelope(int32_t srid, double x1, double y1, double x2, double y2)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#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 LW_ON_INTERRUPT(x)
#define FP_TOLERANCE
Floating point comparators.
int lwgeom_is_collection(const LWGEOM *geom)
Determine whether a LWGEOM contains sub-geometries or not This basically just checks that the struct ...
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...
void lwgeom_free(LWGEOM *lwgeom)
static void lwgeom_subdivide_recursive(const LWGEOM *geom, uint8_t dimension, uint32_t maxvertices, uint32_t depth, LWCOLLECTION *col, double gridSize)
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 void lwerror(const char *fmt,...) __attribute__((format(printf
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)