#include "postgres.h" #include "utils/geo_decls.h" static void make_bound_box(POLYGON *poly) { int i; double min_x, min_y; double max_x, max_y; min_x = max_x = poly->p[0].x; min_y = max_y = poly->p[0].y; for (i = 1; i < poly->npts; i++) { if (poly->p[i].x < min_x) min_x = poly->p[i].x; if (poly->p[i].y < min_y) min_y = poly->p[i].y; if (poly->p[i].x > max_x) max_x = poly->p[i].x; if (poly->p[i].y > max_y) max_y = poly->p[i].y; } poly->boundbox.low.x = min_x; poly->boundbox.low.y = min_y; poly->boundbox.high.x = max_x; poly->boundbox.high.y = max_y; } PG_FUNCTION_INFO_V1(geo_part); Datum geo_part(PG_FUNCTION_ARGS) { POLYGON *orig = PG_GETARG_POLYGON_P(0); int32 offset = PG_GETARG_INT32(1); int32 limit = PG_GETARG_INT32(2); int32 remaining; POLYGON *poly; int32 size; int i; double min_x, min_y; double max_x, max_y; if (offset < 0 || limit < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("offset and limit values have to be a " "nonnegative integer"))); if (offset > orig->npts) PG_RETURN_NULL(); remaining = orig->npts - offset; if (limit > remaining) limit = remaining; if (!limit) PG_RETURN_NULL(); size = offsetof(POLYGON, p[0]) + sizeof(poly->p[0]) * limit; poly = (POLYGON *) palloc(size); poly->size = size; poly->npts = limit; memcpy(poly->p, orig->p + offset, sizeof(orig->p[0]) * limit); make_bound_box(poly); PG_RETURN_POLYGON_P(poly); }