Datum ST_AddMeasure(PG_FUNCTION_ARGS) { GSERIALIZED *gin = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *gout; double start_measure = PG_GETARG_FLOAT8(1); double end_measure = PG_GETARG_FLOAT8(2); LWGEOM *lwin, *lwout; int type = gserialized_get_type(gin); /* Raise an error if input is not a linestring or multilinestring */ if ( type != LINETYPE && type != MULTILINETYPE ) { lwerror("Only LINESTRING and MULTILINESTRING are supported"); PG_RETURN_NULL(); } lwin = lwgeom_from_gserialized(gin); if ( type == LINETYPE ) lwout = (LWGEOM*)lwline_measured_from_lwline((LWLINE*)lwin, start_measure, end_measure); else lwout = (LWGEOM*)lwmline_measured_from_lwmline((LWMLINE*)lwin, start_measure, end_measure); lwgeom_release(lwin); if ( lwout == NULL ) PG_RETURN_NULL(); gout = geometry_serialize(lwout); lwgeom_release(lwout); PG_RETURN_POINTER(gout); }
Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; LWGEOM_INSPECTED *inspected; LWLINE *line = NULL; POINTARRAY *pts; LWPOINT *point; PG_LWGEOM *result; int i, type; POSTGIS_DEBUG(2, "LWGEOM_startpoint_linestring called."); geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); /* * Curved polygons and compound curves are both collections * that should not be traversed looking for linestrings. */ type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]); if (type == CURVEPOLYTYPE || type == COMPOUNDTYPE) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { line = lwgeom_getline_inspected(inspected, i); if ( line ) break; } if ( line == NULL ) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } /* Ok, now we have a line. */ /* Construct a point array */ pts = pointArray_construct(getPoint_internal(line->points, 0), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); lwgeom_release((LWGEOM *)line); /* Construct an LWPOINT */ point = lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts); /* Construct a PG_LWGEOM */ result = pglwgeom_serialize((LWGEOM *)point); lwgeom_release((LWGEOM *)point); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum LWGEOM_locate_between_m(PG_FUNCTION_ARGS) { GSERIALIZED *gin = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *gout; double start_measure = PG_GETARG_FLOAT8(1); double end_measure = PG_GETARG_FLOAT8(2); LWGEOM *lwin, *lwout; int hasz = gserialized_has_z(gin); int hasm = gserialized_has_m(gin); int type; if ( end_measure < start_measure ) { lwerror("locate_between_m: 2nd arg must be bigger then 1st arg"); PG_RETURN_NULL(); } /* * Return error if input doesn't have a measure */ if ( ! hasm ) { lwerror("Geometry argument does not have an 'M' ordinate"); PG_RETURN_NULL(); } /* * Raise an error if input is a polygon, a multipolygon * or a collection */ type = gserialized_get_type(gin); if ( type == POLYGONTYPE || type == MULTIPOLYGONTYPE || type == COLLECTIONTYPE ) { lwerror("Areal or Collection types are not supported"); PG_RETURN_NULL(); } lwin = lwgeom_from_gserialized(gin); lwout = lwgeom_locate_between_m(lwin, start_measure, end_measure); lwgeom_release(lwin); if ( lwout == NULL ) { lwout = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, gserialized_get_srid(gin), hasz, hasm); } gout = geometry_serialize(lwout); lwgeom_release(lwout); PG_RETURN_POINTER(gout); }
Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; LWGEOM_INSPECTED *inspected; LWLINE *line = NULL; POINTARRAY *pts; LWGEOM *point; PG_LWGEOM *result; int i, type; POSTGIS_DEBUG(2, "LWGEOM_endpoint_linestring called."); geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]); if (type == CURVEPOLYTYPE || type == COMPOUNDTYPE) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { line = lwgeom_getline_inspected(inspected, i); if ( line ) break; } lwinspected_release(inspected); if ( line == NULL ) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } /* Ok, now we have a line. */ /* Construct a point array */ pts = pointArray_construct( getPoint_internal(line->points, line->points->npoints-1), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); lwgeom_release((LWGEOM *)line); /* Construct an LWPOINT */ point = (LWGEOM *)lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts); /* Serialize an PG_LWGEOM */ result = pglwgeom_serialize(point); lwgeom_release(point); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWPOLY *poly = NULL; LWCURVEPOLY *curvepoly = NULL; POINTARRAY *extring; LWGEOM *ring; LWLINE *line; PG_LWGEOM *result; BOX2DFLOAT4 *bbox=NULL; POSTGIS_DEBUG(2, "LWGEOM_exteriorring_polygon called."); if ( TYPE_GETTYPE(geom->type) != POLYGONTYPE && TYPE_GETTYPE(geom->type) != CURVEPOLYTYPE) { elog(ERROR, "ExteriorRing: geom is not a polygon"); PG_RETURN_NULL(); } if (lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]) == POLYGONTYPE) { poly = lwpoly_deserialize(SERIALIZED_FORM(geom)); /* 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=box2d_clone(poly->bbox); line = lwline_construct(poly->SRID, bbox, extring); result = pglwgeom_serialize((LWGEOM *)line); lwgeom_release((LWGEOM *)line); lwgeom_release((LWGEOM *)poly); } else { curvepoly = lwcurvepoly_deserialize(SERIALIZED_FORM(geom)); ring = curvepoly->rings[0]; result = pglwgeom_serialize(ring); lwgeom_release(ring); } PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum LWGEOM_from_text(PG_FUNCTION_ARGS) { text *wkttext = PG_GETARG_TEXT_P(0); char *wkt, fc; size_t size; LWGEOM_PARSER_RESULT lwg_parser_result; PG_LWGEOM *geom_result = NULL; LWGEOM *lwgeom; int result; POSTGIS_DEBUG(2, "LWGEOM_from_text"); size = VARSIZE(wkttext)-VARHDRSZ; POSTGIS_DEBUGF(3, "size: %d", (int)size); if ( size < 10 ) { lwerror("Invalid OGC WKT (too short)"); PG_RETURN_NULL(); } fc=*(VARDATA(wkttext)); wkt = lwalloc(size+1); memcpy(wkt, VARDATA(wkttext), size); wkt[size]='\0'; POSTGIS_DEBUGF(3, "wkt: [%s]", wkt); result = serialized_lwgeom_from_ewkt(&lwg_parser_result, wkt, PARSER_CHECK_ALL); if (result) PG_PARSER_ERROR(lwg_parser_result); lwgeom = lwgeom_deserialize(lwg_parser_result.serialized_lwgeom); if ( lwgeom->SRID != -1 || TYPE_GETZM(lwgeom->type) != 0 ) { elog(WARNING, "OGC WKT expected, EWKT provided - use GeomFromEWKT() for this"); } /* read user-requested SRID if any */ if ( PG_NARGS() > 1 ) lwgeom->SRID = PG_GETARG_INT32(1); geom_result = pglwgeom_serialize(lwgeom); lwgeom_release(lwgeom); PG_RETURN_POINTER(geom_result); }
Datum LWGEOM_geometryn_collection(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); PG_LWGEOM *result; int type = lwgeom_getType(geom->type); int32 idx; LWCOLLECTION *coll; LWGEOM *subgeom; POSTGIS_DEBUG(2, "LWGEOM_geometryn_collection called."); /* elog(NOTICE, "GeometryN called"); */ /* call is valid on multi* geoms only */ if (type==POINTTYPE || type==LINETYPE || type==CIRCSTRINGTYPE || type==COMPOUNDTYPE || type==POLYGONTYPE || type==CURVEPOLYTYPE) { /* elog(NOTICE, "geometryn: geom is of type %d, requires >=4", type); */ PG_RETURN_NULL(); } idx = PG_GETARG_INT32(1); idx -= 1; /* index is 1-based */ coll = (LWCOLLECTION *)lwgeom_deserialize(SERIALIZED_FORM(geom)); if ( idx < 0 ) PG_RETURN_NULL(); if ( idx >= coll->ngeoms ) PG_RETURN_NULL(); subgeom = coll->geoms[idx]; subgeom->SRID = coll->SRID; /* COMPUTE_BBOX==TAINTING */ if ( coll->bbox ) lwgeom_add_bbox(subgeom); result = pglwgeom_serialize(subgeom); lwgeom_release((LWGEOM *)coll); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; int32 wanted_index; LWGEOM_INSPECTED *inspected; LWLINE *line = NULL; LWCIRCSTRING *curve = NULL; LWGEOM *tmp = NULL; POINTARRAY *pts; LWPOINT *point; uchar *serializedpoint; PG_LWGEOM *result; int i, type; wanted_index = PG_GETARG_INT32(1); if ( wanted_index < 1 ) PG_RETURN_NULL(); /* index out of range */ geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]); if (type == COMPOUNDTYPE || type == CURVEPOLYTYPE) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } else { inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { tmp = lwgeom_getgeom_inspected(inspected, i); if (lwgeom_getType(tmp->type) == LINETYPE || lwgeom_getType(tmp->type) == CIRCSTRINGTYPE) break; } if ( tmp == NULL ) { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } if (lwgeom_getType(tmp->type) == CIRCSTRINGTYPE) { curve = (LWCIRCSTRING *)tmp; if (wanted_index > curve->points->npoints) { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_NULL(); } lwinspected_release(inspected); pts = pointArray_construct(getPoint_internal( curve->points, wanted_index-1), TYPE_HASZ(curve->type), TYPE_HASM(curve->type), 1); } else if (lwgeom_getType(tmp->type) == LINETYPE) { line = (LWLINE *)tmp; /* Ok, now we have a line. Let's see if it has enough points. */ if ( wanted_index > line->points->npoints ) { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_NULL(); } lwinspected_release(inspected); /* Construct a point array */ pts = pointArray_construct(getPoint_internal(line->points, wanted_index-1), TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); } else { lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_NULL(); } } /* Construct an LWPOINT */ point = lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts); /* Serialized the point */ serializedpoint = lwpoint_serialize(point); /* And we construct the line * TODO: use serialize_buf above, instead .. */ result = PG_LWGEOM_construct(serializedpoint, pglwgeom_getSRID(geom), 0); pfree(point); pfree(serializedpoint); PG_FREE_IF_COPY(geom, 0); lwgeom_release(tmp); PG_RETURN_POINTER(result); }
Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; int32 wanted_index; LWCURVEPOLY *curvepoly = NULL; LWPOLY *poly = NULL; POINTARRAY *ring; LWLINE *line; PG_LWGEOM *result; BOX2DFLOAT4 *bbox = NULL; 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 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); if ( TYPE_GETTYPE(geom->type) != POLYGONTYPE && TYPE_GETTYPE(geom->type) != CURVEPOLYTYPE ) { PG_FREE_IF_COPY(geom, 0); elog(ERROR, "InteriorRingN: geom is not a polygon"); PG_RETURN_NULL(); } if ( TYPE_GETTYPE(geom->type) == POLYGONTYPE) { poly = lwpoly_deserialize(SERIALIZED_FORM(geom)); /* Ok, now we have a polygon. Let's see if it has enough holes */ if ( wanted_index >= poly->nrings ) { PG_FREE_IF_COPY(geom, 0); lwgeom_release((LWGEOM *)poly); PG_RETURN_NULL(); } ring = poly->rings[wanted_index]; /* COMPUTE_BBOX==TAINTING */ if ( poly->bbox ) bbox = ptarray_compute_box2d(ring); /* This is a LWLINE constructed by interior ring POINTARRAY */ line = lwline_construct(poly->SRID, bbox, ring); /* Copy SRID from polygon */ line->SRID = poly->SRID; result = pglwgeom_serialize((LWGEOM *)line); lwgeom_release((LWGEOM *)line); lwgeom_release((LWGEOM *)poly); } else { curvepoly = lwcurvepoly_deserialize(SERIALIZED_FORM(geom)); if (wanted_index >= curvepoly->nrings) { PG_FREE_IF_COPY(geom, 0); lwgeom_release((LWGEOM *)curvepoly); PG_RETURN_NULL(); } result = pglwgeom_serialize(curvepoly->rings[wanted_index]); lwgeom_release((LWGEOM *)curvepoly); } PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum LWGEOM_numinteriorrings_polygon(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM_INSPECTED *inspected = NULL; LWGEOM *tmp = NULL; LWPOLY *poly = NULL; LWCURVEPOLY *curvepoly = NULL; int32 result; int i; POSTGIS_DEBUG(2, "LWGEOM_numinteriorrings called."); if (lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]) == CURVEPOLYTYPE) { tmp = (LWGEOM *)lwcurvepoly_deserialize(SERIALIZED_FORM(geom)); } else { inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { tmp = lwgeom_getgeom_inspected(inspected, i); if (lwgeom_getType(tmp->type) == POLYGONTYPE || lwgeom_getType(tmp->type) == CURVEPOLYTYPE) break; } } if ( tmp == NULL ) { PG_FREE_IF_COPY(geom, 0); lwinspected_release(inspected); PG_RETURN_NULL(); } POSTGIS_DEBUGF(3, "Geometry of type %d found.", lwgeom_getType(tmp->type)); if (lwgeom_getType(tmp->type) == POLYGONTYPE) { poly = (LWPOLY *)tmp; /* Ok, now we have a polygon. Here is its number of holes */ result = poly->nrings-1; } else if (lwgeom_getType(tmp->type) == CURVEPOLYTYPE) { POSTGIS_DEBUG(3, "CurvePolygon found."); curvepoly = (LWCURVEPOLY *)tmp; result = curvepoly->nrings-1; } else { PG_FREE_IF_COPY(geom, 0); lwinspected_release(inspected); PG_RETURN_NULL(); } PG_FREE_IF_COPY(geom, 0); if (inspected != NULL) lwinspected_release(inspected); lwgeom_release((LWGEOM *)tmp); PG_RETURN_INT32(result); }
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); }
void lwmpoint_release(LWMPOINT *lwmpoint) { lwgeom_release(lwmpoint_as_lwgeom(lwmpoint)); }
void lwcollection_release(LWCOLLECTION *lwcollection) { lwgeom_release(lwcollection_as_lwgeom(lwcollection)); }
void lwcircstring_release(LWCIRCSTRING *lwcirc) { lwgeom_release(lwcircstring_as_lwgeom(lwcirc)); }
Datum geom_from_kml(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom, *hlwgeom; xmlDocPtr xmldoc; text *xml_input; int xml_size; char *xml; bool hasz=true; xmlNodePtr xmlroot=NULL; /* Get the KML stream */ if (PG_ARGISNULL(0)) PG_RETURN_NULL(); xml_input = PG_GETARG_TEXT_P(0); xml = text2cstring(xml_input); xml_size = VARSIZE(xml_input) - VARHDRSZ; /* Begin to Parse XML doc */ xmlInitParser(); xmldoc = xmlParseMemory(xml, xml_size); if (!xmldoc || (xmlroot = xmlDocGetRootElement(xmldoc)) == NULL) { xmlFreeDoc(xmldoc); xmlCleanupParser(); lwerror("invalid KML representation"); } lwgeom = parse_kml(xmlroot, &hasz); /* Homogenize geometry result if needed */ if (lwgeom->type == COLLECTIONTYPE) { hlwgeom = lwgeom_homogenize(lwgeom); lwgeom_release(lwgeom); lwgeom = hlwgeom; } lwgeom_add_bbox(lwgeom); /* KML geometries could be either 2 or 3D * * So we deal with 3D in all structures allocation, and flag hasz * to false if we met once a missing Z dimension * In this case, we force recursive 2D. */ if (!hasz) { LWGEOM *tmp = lwgeom_force_2d(lwgeom); lwgeom_free(lwgeom); lwgeom = tmp; } geom = geometry_serialize(lwgeom); lwgeom_free(lwgeom); xmlFreeDoc(xmldoc); xmlCleanupParser(); PG_RETURN_POINTER(geom); }
void lwtriangle_release(LWTRIANGLE *lwtriangle) { lwgeom_release(lwtriangle_as_lwgeom(lwtriangle)); }
void lwpoly_release(LWPOLY *lwpoly) { lwgeom_release(lwpoly_as_lwgeom(lwpoly)); }
Datum LWGEOM_isclosed_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; LWGEOM_INSPECTED *inspected; LWGEOM *sub = NULL; LWCOMPOUND *compound = NULL; int linesfound=0; int i; POSTGIS_DEBUG(2, "LWGEOM_isclosed_linestring called."); geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); if (lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]) == COMPOUNDTYPE) { compound = lwcompound_deserialize(SERIALIZED_FORM(geom)); if (compound_is_closed(compound)) { lwgeom_release((LWGEOM *)compound); PG_FREE_IF_COPY(geom, 0); PG_RETURN_BOOL(TRUE); } else { lwgeom_release((LWGEOM *)compound); PG_FREE_IF_COPY(geom, 0); PG_RETURN_BOOL(FALSE); } } inspected = lwgeom_inspect(SERIALIZED_FORM(geom)); for (i=0; i<inspected->ngeometries; i++) { sub = lwgeom_getgeom_inspected(inspected, i); if ( sub == NULL ) continue; else if (lwgeom_getType(sub->type) == LINETYPE && !line_is_closed((LWLINE *)sub)) { lwgeom_release(sub); lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); PG_RETURN_BOOL(FALSE); } else if (lwgeom_getType(sub->type) == CIRCSTRINGTYPE && !circstring_is_closed((LWCIRCSTRING *)sub)) { lwgeom_release(sub); lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); PG_RETURN_BOOL(FALSE); } else if (lwgeom_getType(sub->type) == COMPOUNDTYPE && !compound_is_closed((LWCOMPOUND *)sub)) { lwgeom_release(sub); lwinspected_release(inspected); PG_FREE_IF_COPY(geom, 0); PG_RETURN_BOOL(FALSE); } lwgeom_release(sub); linesfound++; } lwinspected_release(inspected); if ( ! linesfound ) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } PG_FREE_IF_COPY(geom, 0); PG_RETURN_BOOL(TRUE); }
void lwmline_release(LWMLINE *lwmline) { lwgeom_release(lwmline_as_lwgeom(lwmline)); }
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); }