Datum LWGEOM_numinteriorrings_polygon(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom = lwgeom_from_gserialized(geom); LWPOLY *poly = NULL; LWCURVEPOLY *curvepoly = NULL; int result = -1; if ( lwgeom->type == POLYGONTYPE ) { poly = lwgeom_as_lwpoly(lwgeom); result = poly->nrings - 1; } else if ( lwgeom->type == CURVEPOLYTYPE ) { curvepoly = lwgeom_as_lwcurvepoly(lwgeom); result = curvepoly->nrings - 1; } lwgeom_free(lwgeom); PG_FREE_IF_COPY(geom, 0); if ( result < 0 ) PG_RETURN_NULL(); PG_RETURN_INT32(result); }
LWGEOM* wkt_parser_curvepolygon_add_ring(LWGEOM *poly, LWGEOM *ring) { LWDEBUG(4,"entered"); /* Toss error on null input */ if( ! (ring && poly) ) { SET_PARSER_ERROR(PARSER_ERROR_OTHER); LWDEBUG(4,"inputs are null"); return NULL; } /* All the elements must agree on dimensionality */ if( FLAGS_NDIMS(poly->flags) != FLAGS_NDIMS(ring->flags) ) { LWDEBUG(4,"dimensionality does not match"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS); return NULL; } /* Apply check for minimum number of points, if requested. */ if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) && (lwgeom_count_vertices(ring) < 4) ) { LWDEBUG(4,"number of points is incorrect"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS); return NULL; } /* Apply check for not closed rings, if requested. */ if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_CLOSURE) ) { int is_closed = 1; LWDEBUG(4,"checking ring closure"); switch ( ring->type ) { case LINETYPE: is_closed = lwline_is_closed(lwgeom_as_lwline(ring)); break; case CIRCSTRINGTYPE: is_closed = lwcircstring_is_closed(lwgeom_as_lwcircstring(ring)); break; case COMPOUNDTYPE: is_closed = lwcompound_is_closed(lwgeom_as_lwcompound(ring)); break; } if ( ! is_closed ) { LWDEBUG(4,"ring is not closed"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_UNCLOSED); return NULL; } } if( LW_FAILURE == lwcurvepoly_add_ring(lwgeom_as_lwcurvepoly(poly), ring) ) { LWDEBUG(4,"failed to add ring"); lwgeom_free(ring); lwgeom_free(poly); SET_PARSER_ERROR(PARSER_ERROR_OTHER); return NULL; } return poly; }
Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS) { GSERIALIZED *geom; int32 wanted_index; LWCURVEPOLY *curvepoly = NULL; LWPOLY *poly = NULL; POINTARRAY *ring; LWLINE *line; LWGEOM *lwgeom; GSERIALIZED *result; GBOX *bbox = NULL; int type; POSTGIS_DEBUG(2, "LWGEOM_interierringn_polygon called."); wanted_index = PG_GETARG_INT32(1); if ( wanted_index < 1 ) { /* elog(ERROR, "InteriorRingN: ring number is 1-based"); */ PG_RETURN_NULL(); /* index out of range */ } geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); type = gserialized_get_type(geom); if ( (type != POLYGONTYPE) && (type != CURVEPOLYTYPE) ) { elog(ERROR, "InteriorRingN: geom is not a polygon"); PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } lwgeom = lwgeom_from_gserialized(geom); if( lwgeom_is_empty(lwgeom) ) { lwpoly_free(poly); PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } if ( type == POLYGONTYPE) { poly = lwgeom_as_lwpoly(lwgeom_from_gserialized(geom)); /* Ok, now we have a polygon. Let's see if it has enough holes */ if ( wanted_index >= poly->nrings ) { lwpoly_free(poly); PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } ring = poly->rings[wanted_index]; /* COMPUTE_BBOX==TAINTING */ if ( poly->bbox ) { bbox = lwalloc(sizeof(GBOX)); ptarray_calculate_gbox_cartesian(ring, bbox); } /* This is a LWLINE constructed by interior ring POINTARRAY */ line = lwline_construct(poly->srid, bbox, ring); result = geometry_serialize((LWGEOM *)line); lwline_release(line); lwpoly_free(poly); } else { curvepoly = lwgeom_as_lwcurvepoly(lwgeom_from_gserialized(geom)); if (wanted_index >= curvepoly->nrings) { PG_FREE_IF_COPY(geom, 0); lwgeom_release((LWGEOM *)curvepoly); PG_RETURN_NULL(); } result = geometry_serialize(curvepoly->rings[wanted_index]); lwgeom_free((LWGEOM*)curvepoly); } PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *result; POINTARRAY *extring; LWGEOM *lwgeom; LWLINE *line; GBOX *bbox=NULL; int type = gserialized_get_type(geom); POSTGIS_DEBUG(2, "LWGEOM_exteriorring_polygon called."); if ( (type != POLYGONTYPE) && (type != CURVEPOLYTYPE) && (type != TRIANGLETYPE)) { elog(ERROR, "ExteriorRing: geom is not a polygon"); PG_RETURN_NULL(); } lwgeom = lwgeom_from_gserialized(geom); if( lwgeom_is_empty(lwgeom) ) { line = lwline_construct_empty(lwgeom->srid, lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom)); result = geometry_serialize(lwline_as_lwgeom(line)); } else if ( lwgeom->type == POLYGONTYPE ) { LWPOLY *poly = lwgeom_as_lwpoly(lwgeom); /* Ok, now we have a polygon. Here is its exterior ring. */ extring = poly->rings[0]; /* * This is a LWLINE constructed by exterior ring POINTARRAY * If the input geom has a bbox, use it for * the output geom, as exterior ring makes it up ! */ if ( poly->bbox ) bbox = gbox_copy(poly->bbox); line = lwline_construct(poly->srid, bbox, extring); result = geometry_serialize((LWGEOM *)line); lwgeom_release((LWGEOM *)line); } else if ( lwgeom->type == TRIANGLETYPE ) { LWTRIANGLE *triangle = lwgeom_as_lwtriangle(lwgeom); /* * This is a LWLINE constructed by exterior ring POINTARRAY * If the input geom has a bbox, use it for * the output geom, as exterior ring makes it up ! */ if ( triangle->bbox ) bbox = gbox_copy(triangle->bbox); line = lwline_construct(triangle->srid, bbox, triangle->points); result = geometry_serialize((LWGEOM *)line); lwgeom_release((LWGEOM *)line); } else { LWCURVEPOLY *curvepoly = lwgeom_as_lwcurvepoly(lwgeom); result = geometry_serialize(curvepoly->rings[0]); } lwgeom_free(lwgeom); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }