Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS);
-/*
-** Versions of PostgreSQL < 8.4 perform array accumulation internally using
+/** @file
+** Versions of PostgreSQL < 8.4 perform array accumulation internally using
** pass by value, which is very slow working with large/many geometries.
** Hence PostGIS currently implements its own aggregate for building
** geometry arrays using pass by reference, which is significantly faster and
** similar to the method used in PostgreSQL 8.4.
**
** Hence we can revert this to the original aggregate functions from 1.3 at
-** whatever point PostgreSQL 8.4 becomes the minimum version we support :)
+** whatever point PostgreSQL 8.4 becomes the minimum version we support :)
*/
-/*
-** To pass the internal ArrayBuildState pointer between the
+/**
+** To pass the internal ArrayBuildState pointer between the
** transfn and finalfn we need to wrap it into a custom type first,
-** the pgis_abs type in our case.
+** the pgis_abs type in our case.
*/
typedef struct {
ArrayBuildState *a;
} pgis_abs;
-/*
-** We're never going to use this type externally so the in/out
+/**
+** We're never going to use this type externally so the in/out
** functions are dummies.
*/
PG_FUNCTION_INFO_V1(pgis_abs_in);
pgis_abs_in(PG_FUNCTION_ARGS)
{
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("function pgis_abs_in not implemented")));
+ errmsg("function pgis_abs_in not implemented")));
PG_RETURN_POINTER(NULL);
}
PG_FUNCTION_INFO_V1(pgis_abs_out);
pgis_abs_out(PG_FUNCTION_ARGS)
{
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("function pgis_abs_out not implemented")));
+ errmsg("function pgis_abs_out not implemented")));
PG_RETURN_POINTER(NULL);
}
-/*
+/**
** The transfer function hooks into the PostgreSQL accumArrayResult()
** function (present since 8.0) to build an array in a side memory
** context.
Datum pgis_accum_finalfn(pgis_abs *p, MemoryContext mctx, FunctionCallInfo fcinfo);
-/*
+/**
** The final function rescues the built array from the side memory context
** using the PostgreSQL built-in function makeMdArrayResult
*/
-Datum
+Datum
pgis_accum_finalfn(pgis_abs *p, MemoryContext mctx, FunctionCallInfo fcinfo)
{
int dims[1];
int lbs[1];
ArrayBuildState *state;
Datum result;
-
+
/* cannot be called directly because of internal-type argument */
Assert(fcinfo->context &&
- (IsA(fcinfo->context, AggState)
+ (IsA(fcinfo->context, AggState)
#if POSTGIS_PGSQL_VERSION >= 84
|| IsA(fcinfo->context, WindowAggState)
#endif
));
-
+
state = p->a;
dims[0] = state->nelems;
lbs[0] = 1;
#if POSTGIS_PGSQL_VERSION < 84
- result = makeMdArrayResult(state, 1, dims, lbs, mctx);
+ result = makeMdArrayResult(state, 1, dims, lbs, mctx);
#else
/* Release working state if regular aggregate, but not if window agg */
- result = makeMdArrayResult(state, 1, dims, lbs, mctx,
- IsA(fcinfo->context, AggState));
+ result = makeMdArrayResult(state, 1, dims, lbs, mctx,
+ IsA(fcinfo->context, AggState));
#endif
return result;
}
-/*
+/**
** The "accum" final function just returns the geometry[]
*/
PG_FUNCTION_INFO_V1(pgis_geometry_accum_finalfn);
}
-/*
-** The "accum" final function passes the geometry[] to a union
-** conversion before returning the result.
+/**
+* The "accum" final function passes the geometry[] to a union
+* conversion before returning the result.
*/
PG_FUNCTION_INFO_V1(pgis_geometry_union_finalfn);
Datum
PG_RETURN_DATUM(result);
}
-/*
-** The "collect" final function passes the geometry[] to a geometrycollection
-** conversion before returning the result.
+/**
+* The "collect" final function passes the geometry[] to a geometrycollection
+* conversion before returning the result.
*/
PG_FUNCTION_INFO_V1(pgis_geometry_collect_finalfn);
Datum
PG_RETURN_DATUM(result);
}
-/*
-** The "polygonize" final function passes the geometry[] to a polygonization
-** before returning the result.
+/**
+* The "polygonize" final function passes the geometry[] to a polygonization
+* before returning the result.
*/
PG_FUNCTION_INFO_V1(pgis_geometry_polygonize_finalfn);
Datum
PG_RETURN_DATUM(result);
}
-/*
-** The "makeline" final function passes the geometry[] to a line builder
-** before returning the result.
+/**
+* The "makeline" final function passes the geometry[] to a line builder
+* before returning the result.
*/
PG_FUNCTION_INFO_V1(pgis_geometry_makeline_finalfn);
Datum
* This is free software; you can redistribute and/or modify it under
* the terms of hte GNU General Public Licence. See the COPYING file.
*
- **********************************************************************
- *
+ **********************************************************************/
+ /** @file
* GeoJSON output routines.
* Originally written by Olivier Courtin (Camptocamp)
*
/**
- * Encode Feature in GeoJson
+ * Encode Feature in GeoJson
*/
PG_FUNCTION_INFO_V1(LWGEOM_asGeoJson);
Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS)
int precision = MAX_DOUBLE_PRECISION;
char * srs = NULL;
- /* Get the version */
- version = PG_GETARG_INT32(0);
- if ( version != 1) {
- elog(ERROR, "Only GeoJSON 1 is supported");
- PG_RETURN_NULL();
- }
+ /* Get the version */
+ version = PG_GETARG_INT32(0);
+ if ( version != 1) {
+ elog(ERROR, "Only GeoJSON 1 is supported");
+ PG_RETURN_NULL();
+ }
/* Get the geometry */
if (PG_ARGISNULL(1) ) PG_RETURN_NULL();
geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
/* Retrieve precision if any (default is max) */
- if (PG_NARGS() >2 && !PG_ARGISNULL(2)) {
- precision = PG_GETARG_INT32(2);
- if ( precision > MAX_DOUBLE_PRECISION )
- precision = MAX_DOUBLE_PRECISION;
- else if ( precision < 0 ) precision = 0;
- }
-
- /* Retrieve output option
+ if (PG_NARGS() >2 && !PG_ARGISNULL(2)) {
+ precision = PG_GETARG_INT32(2);
+ if ( precision > MAX_DOUBLE_PRECISION )
+ precision = MAX_DOUBLE_PRECISION;
+ else if ( precision < 0 ) precision = 0;
+ }
+
+ /* Retrieve output option
* 0 = without option (default)
* 1 = bbox
* 2 = short crs
* 4 = long crs
*/
- if (PG_NARGS() >3 && !PG_ARGISNULL(3))
- option = PG_GETARG_INT32(3);
+ if (PG_NARGS() >3 && !PG_ARGISNULL(3))
+ option = PG_GETARG_INT32(3);
if (option & 2 || option & 4) {
- SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
- if ( SRID != -1 ) {
+ SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
+ if ( SRID != -1 ) {
if (option & 2) srs = getSRSbySRID(SRID, true);
if (option & 4) srs = getSRSbySRID(SRID, false);
if (!srs) {
- elog(ERROR, "SRID %i unknown in spatial_ref_sys table", SRID);
- PG_RETURN_NULL();
+ elog(ERROR, "SRID %i unknown in spatial_ref_sys table", SRID);
+ PG_RETURN_NULL();
}
}
}
if (option & 1) has_bbox = 1;
-
+
geojson = geometry_to_geojson(SERIALIZED_FORM(geom), srs, has_bbox, precision);
PG_FREE_IF_COPY(geom, 1);
if (srs) pfree(srs);
-/*
- * Takes a GEOMETRY and returns a GeoJson representation
+/*
+ * Takes a GEOMETRY and returns a GeoJson representation
*/
char *
geometry_to_geojson(uchar *geom, char *srs, bool has_bbox, int precision)
}
-/*
- * Handle SRS
+/**
+ * Handle SRS
*/
static size_t
asgeojson_srs_size(char *srs) {
}
-/*
- * Handle Bbox
+/**
+ * Handle Bbox
*/
static size_t
asgeojson_bbox_size(bool hasz, int precision) {
if (!hasz) {
size = sizeof("\"bbox\":[,,,],");
- size += 2 * 2 * (MAX_DIGS_DOUBLE + precision);
+ size += 2 * 2 * (MAX_DIGS_DOUBLE + precision);
} else {
size = sizeof("\"bbox\":[,,,,,],");
- size += 2 * 3 * (MAX_DIGS_DOUBLE + precision);
+ size += 2 * 3 * (MAX_DIGS_DOUBLE + precision);
}
return size;
ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f],",
precision, bbox->xmin, precision, bbox->ymin,
precision, bbox->xmax, precision, bbox->ymax);
- else
+ else
ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f,%.*f,%.*f],",
precision, bbox->xmin, precision, bbox->ymin, precision, bbox->zmin,
precision, bbox->xmax, precision, bbox->ymax, precision, bbox->zmax);
-/*
+/**
* Point Geometry
*/
ptr += sprintf(ptr, "{\"type\":\"Point\",");
if (srs) ptr += asgeojson_srs_buf(ptr, srs);
if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(point->type), precision);
-
+
ptr += sprintf(ptr, "\"coordinates\":");
ptr += pointArray_to_geojson(point->point, ptr, precision);
ptr += sprintf(ptr, "}");
-/*
+/**
* Line Geometry
*/
-/*
+/**
* Polygon Geometry
*/
ptr += sprintf(ptr, "\"coordinates\":[");
for (i=0; i<poly->nrings; i++)
{
- if (i) ptr += sprintf(ptr, ",");
+ if (i) ptr += sprintf(ptr, ",");
ptr += sprintf(ptr, "[");
ptr += pointArray_to_geojson(poly->rings[i], ptr, precision);
ptr += sprintf(ptr, "]");
-/*
+/**
* Multipoint Geometry
*/
for (i=0; i<insp->ngeometries; i++) {
point = lwgeom_getpoint_inspected(insp, i);
- size += pointArray_geojson_size(point->point, precision);
- lwpoint_release(point);
+ size += pointArray_geojson_size(point->point, precision);
+ lwpoint_release(point);
}
size += sizeof(",") * i;
ptr += sprintf(ptr, "\"coordinates\":[");
for (i=0; i<insp->ngeometries; i++)
- {
- if (i) ptr += sprintf(ptr, ",");
- point=lwgeom_getpoint_inspected(insp, i);
+ {
+ if (i) ptr += sprintf(ptr, ",");
+ point=lwgeom_getpoint_inspected(insp, i);
ptr += pointArray_to_geojson(point->point, ptr, precision);
- lwpoint_release(point);
+ lwpoint_release(point);
}
ptr += sprintf(ptr, "]}");
-/*
+/**
* Multiline Geometry
*/
for (i=0 ; i<insp->ngeometries; i++) {
line = lwgeom_getline_inspected(insp, i);
- size += pointArray_geojson_size(line->points, precision);
+ size += pointArray_geojson_size(line->points, precision);
size += sizeof("[]");
- lwline_release(line);
+ lwline_release(line);
}
size += sizeof(",") * i;
ptr += sprintf(ptr, "\"coordinates\":[");
for (i=0; i<insp->ngeometries; i++)
- {
- if (i) ptr += sprintf(ptr, ",");
- ptr += sprintf(ptr, "[");
- line = lwgeom_getline_inspected(insp, i);
+ {
+ if (i) ptr += sprintf(ptr, ",");
+ ptr += sprintf(ptr, "[");
+ line = lwgeom_getline_inspected(insp, i);
ptr += pointArray_to_geojson(line->points, ptr, precision);
- ptr += sprintf(ptr, "]");
-
- lwline_release(line);
+ ptr += sprintf(ptr, "]");
+
+ lwline_release(line);
}
ptr += sprintf(ptr, "]}");
-/*
+/**
* MultiPolygon Geometry
*/
for (i=0; i < insp->ngeometries; i++) {
poly = lwgeom_getpoly_inspected(insp, i);
for (j=0 ; j <poly->nrings ; j++) {
- size += pointArray_geojson_size(poly->rings[j], precision);
+ size += pointArray_geojson_size(poly->rings[j], precision);
size += sizeof("[]");
}
- lwpoly_release(poly);
+ lwpoly_release(poly);
size += sizeof("[]");
}
size += sizeof(",") * i;
if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(insp->type), precision);
ptr += sprintf(ptr, "\"coordinates\":[");
for (i=0; i<insp->ngeometries; i++)
- {
- if (i) ptr += sprintf(ptr, ",");
- ptr += sprintf(ptr, "[");
- poly = lwgeom_getpoly_inspected(insp, i);
+ {
+ if (i) ptr += sprintf(ptr, ",");
+ ptr += sprintf(ptr, "[");
+ poly = lwgeom_getpoly_inspected(insp, i);
for (j=0 ; j < poly->nrings ; j++) {
if (j) ptr += sprintf(ptr, ",");
- ptr += sprintf(ptr, "[");
+ ptr += sprintf(ptr, "[");
ptr += pointArray_to_geojson(poly->rings[j], ptr, precision);
- ptr += sprintf(ptr, "]");
+ ptr += sprintf(ptr, "]");
}
- ptr += sprintf(ptr, "]");
- lwpoly_release(poly);
+ ptr += sprintf(ptr, "]");
+ lwpoly_release(poly);
}
ptr += sprintf(ptr, "]}");
-/*
+/**
* Collection Geometry
*/
size += sizeof("'geometries':");
for (i=0; i<insp->ngeometries; i++)
- {
+ {
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
subinsp = lwgeom_inspect(subgeom);
size += asgeojson_inspected_size(subinsp, bbox, precision);
ptr += sprintf(ptr, "\"geometries\":[");
for (i=0; i<insp->ngeometries; i++)
- {
+ {
if (i) ptr += sprintf(ptr, ",");
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
subinsp = lwgeom_inspect(subgeom);
{
int type = lwgeom_getType(insp->serialized_form[0]);
size_t size = 0;
- LWPOINT *point;
- LWLINE *line;
- LWPOLY *poly;
+ LWPOINT *point;
+ LWLINE *line;
+ LWPOLY *poly;
switch(type) {
case POINTTYPE:
point=lwgeom_getpoint_inspected(insp, 0);
- size = asgeojson_point_size(point, NULL, bbox, precision);
- lwpoint_release(point);
+ size = asgeojson_point_size(point, NULL, bbox, precision);
+ lwpoint_release(point);
break;
case LINETYPE:
line=lwgeom_getline_inspected(insp, 0);
- size = asgeojson_line_size(line, NULL, bbox, precision);
- lwline_release(line);
+ size = asgeojson_line_size(line, NULL, bbox, precision);
+ lwline_release(line);
break;
-
+
case POLYGONTYPE:
poly=lwgeom_getpoly_inspected(insp, 0);
- size = asgeojson_poly_size(poly, NULL, bbox, precision);
+ size = asgeojson_poly_size(poly, NULL, bbox, precision);
lwpoly_release(poly);
break;
case MULTIPOINTTYPE:
- size = asgeojson_multipoint_size(insp, NULL, bbox, precision);
+ size = asgeojson_multipoint_size(insp, NULL, bbox, precision);
break;
case MULTILINETYPE:
- size = asgeojson_multiline_size(insp, NULL, bbox, precision);
+ size = asgeojson_multiline_size(insp, NULL, bbox, precision);
break;
case MULTIPOLYGONTYPE:
- size = asgeojson_multipolygon_size(insp, NULL, bbox, precision);
+ size = asgeojson_multipolygon_size(insp, NULL, bbox, precision);
break;
default: lwerror("GeoJson: geometry not supported.");
- }
+ }
return size;
}
static size_t
asgeojson_inspected_buf(LWGEOM_INSPECTED *insp, char *output, BOX3D *bbox, int precision)
{
- LWPOINT *point;
- LWLINE *line;
- LWPOLY *poly;
+ LWPOINT *point;
+ LWLINE *line;
+ LWPOLY *poly;
int type = lwgeom_getType(insp->serialized_form[0]);
char *ptr=output;
switch(type) {
case POINTTYPE:
point=lwgeom_getpoint_inspected(insp, 0);
- ptr += asgeojson_point_buf(point, NULL, ptr, bbox, precision);
- lwpoint_release(point);
+ ptr += asgeojson_point_buf(point, NULL, ptr, bbox, precision);
+ lwpoint_release(point);
break;
case LINETYPE:
line=lwgeom_getline_inspected(insp, 0);
- ptr += asgeojson_line_buf(line, NULL, ptr, bbox, precision);
- lwline_release(line);
+ ptr += asgeojson_line_buf(line, NULL, ptr, bbox, precision);
+ lwline_release(line);
break;
-
+
case POLYGONTYPE:
poly=lwgeom_getpoly_inspected(insp, 0);
ptr += asgeojson_poly_buf(poly, NULL, ptr, bbox, precision);
/*
- * Common geojson routines
+ * Common geojson routines
*/
static char *
else
sprintf(query, "SELECT 'urn:ogc:def:crs:'||auth_name||':'||auth_srid \
FROM spatial_ref_sys WHERE srid='%d'", SRID);
-
+
err = SPI_exec(query, 1);
if ( err < 0 ) {
elog(NOTICE, "getSRSbySRID: error executing query %d", err);
/* get result */
srs = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
-
+
/* NULL result */
if ( ! srs ) {
SPI_finish();
}
-/*
+/**
* Returns maximum size of rendered pointarray in bytes.
*/
static size_t
* This is free software; you can redistribute and/or modify it under
* the terms of hte GNU General Public Licence. See the COPYING file.
*
- **********************************************************************
- *
- * GML output routines.
+ **********************************************************************/
+
+ /**
+ * @file GML output routines.
*
**********************************************************************/
/**
- * Encode feature in GML
+ * Encode feature in GML
*/
PG_FUNCTION_INFO_V1(LWGEOM_asGML);
Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
int option=0;
bool is_deegree = false;
- /* Get the version */
- version = PG_GETARG_INT32(0);
+ /* Get the version */
+ version = PG_GETARG_INT32(0);
if ( version != 2 && version != 3 )
{
elog(ERROR, "Only GML 2 and GML 3 are supported");
PG_RETURN_NULL();
}
- /* Get the geometry */
+ /* Get the geometry */
if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
if ( precision > MAX_DOUBLE_PRECISION )
precision = MAX_DOUBLE_PRECISION;
else if ( precision < 0 ) precision = 0;
- }
+ }
/* retrieve option */
if (PG_NARGS() >3 && !PG_ARGISNULL(3))
- option = PG_GETARG_INT32(3);
+ option = PG_GETARG_INT32(3);
SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
if (SRID == -1) srs = NULL;
gml = geometry_to_gml2(SERIALIZED_FORM(geom), srs, precision);
else
gml = geometry_to_gml3(SERIALIZED_FORM(geom), srs, precision, is_deegree);
-
+
PG_FREE_IF_COPY(geom, 1);
len = strlen(gml) + VARHDRSZ;
-/*
- * VERSION GML 2
+/**
+ * @brief VERSION GML 2
+ * takes a GEOMETRY and returns a GML@ representation
*/
-
-/* takes a GEOMETRY and returns a GML representation */
char *
geometry_to_gml2(uchar *geom, char *srs, int precision)
{
case MULTIPOINTTYPE:
case MULTILINETYPE:
- case MULTIPOLYGONTYPE:
+ case MULTIPOLYGONTYPE:
case COLLECTIONTYPE:
inspected = lwgeom_inspect(geom);
return asgml2_inspected(inspected, srs, precision);
default:
- lwerror("geometry_to_gml2: '%s' geometry type not supported", lwgeom_typename(type));
- return NULL;
+ lwerror("geometry_to_gml2: '%s' geometry type not supported", lwgeom_typename(type));
+ return NULL;
}
}
{
char *output;
int size;
-
+
size = asgml2_point_size(point, srs, precision);
output = palloc(size);
asgml2_point_buf(point, srs, output, precision);
char *ptr=output;
if ( srs ) {
- ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
+ ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
} else {
- ptr += sprintf(ptr, "<gml:Polygon>");
+ ptr += sprintf(ptr, "<gml:Polygon>");
}
- ptr += sprintf(ptr, "<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>");
+ ptr += sprintf(ptr, "<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>");
ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
- ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>");
+ ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>");
for (i=1; i<poly->nrings; i++)
{
- ptr += sprintf(ptr, "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>");
+ ptr += sprintf(ptr, "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>");
ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
- ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>");
+ ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>");
}
ptr += sprintf(ptr, "</gml:Polygon>");
}
/*
- * Compute max size required for GML version of this
+ * Compute max size required for GML version of this
* inspected geometry. Will recurse when needed.
* Don't call this with single-geoms inspected.
*/
ptr += sprintf(ptr, "%s,%s", x, y);
}
}
- else
+ else
{
for (i=0; i<pa->npoints; i++)
{
/*
- * VERSION GML 3.1.1
+ * VERSION GML 3.1.1
*/
{
char *output;
int size;
-
+
size = asgml3_point_size(point, srs, precision);
output = palloc(size);
asgml3_point_buf(point, srs, output, precision, is_deegree);
char *ptr=output;
if ( srs ) {
- ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
+ ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
} else {
- ptr += sprintf(ptr, "<gml:Polygon>");
+ ptr += sprintf(ptr, "<gml:Polygon>");
}
- ptr += sprintf(ptr, "<gml:exterior><gml:LinearRing><gml:posList>");
+ ptr += sprintf(ptr, "<gml:exterior><gml:LinearRing><gml:posList>");
ptr += pointArray_toGML3(poly->rings[0], ptr, precision, is_deegree);
- ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:exterior>");
+ ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:exterior>");
for (i=1; i<poly->nrings; i++)
{
- ptr += sprintf(ptr, "<gml:interior><gml:LinearRing><gml:posList>");
+ ptr += sprintf(ptr, "<gml:interior><gml:LinearRing><gml:posList>");
ptr += pointArray_toGML3(poly->rings[i], ptr, precision, is_deegree);
- ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:interior>");
+ ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:interior>");
}
ptr += sprintf(ptr, "</gml:Polygon>");
}
/*
- * Compute max size required for GML version of this
+ * Compute max size required for GML version of this
* inspected geometry. Will recurse when needed.
* Don't call this with single-geoms inspected.
*/
trim_trailing_zeros(y);
if ( i ) ptr += sprintf(ptr, " ");
if (is_deegree)
- ptr += sprintf(ptr, "%s %s", y, x);
- else
- ptr += sprintf(ptr, "%s %s", x, y);
+ ptr += sprintf(ptr, "%s %s", y, x);
+ else
+ ptr += sprintf(ptr, "%s %s", x, y);
}
}
- else
+ else
{
for (i=0; i<pa->npoints; i++)
{
/*
- * Common GML routines
+ * Common GML routines
*/
static char *
}
if (short_crs)
- sprintf(query, "SELECT auth_name||':'||auth_srid \
- FROM spatial_ref_sys WHERE srid='%d'", SRID);
- else
- sprintf(query, "SELECT 'urn:ogc:def:crs:'||auth_name||':'||auth_srid \
- FROM spatial_ref_sys WHERE srid='%d'", SRID);
+ sprintf(query, "SELECT auth_name||':'||auth_srid \
+ FROM spatial_ref_sys WHERE srid='%d'", SRID);
+ else
+ sprintf(query, "SELECT 'urn:ogc:def:crs:'||auth_name||':'||auth_srid \
+ FROM spatial_ref_sys WHERE srid='%d'", SRID);
/* execute query */
err = SPI_exec(query, 1);
/* get result */
srs = SPI_getvalue(SPI_tuptable->vals[0],
SPI_tuptable->tupdesc, 1);
-
+
/* NULL result */
if ( ! srs ) {
/*elog(NOTICE, "getSRSbySRID: null result"); */
pointArray_GMLsize(POINTARRAY *pa, int precision)
{
if (TYPE_NDIMS(pa->dims) == 2)
- return (MAX_DIGS_DOUBLE + precision + sizeof(", "))
- * 2 * pa->npoints;
+ return (MAX_DIGS_DOUBLE + precision + sizeof(", "))
+ * 2 * pa->npoints;
- return (MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;
+ return (MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;
}
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
- *
+ *
**********************************************************************/
#include "postgres.h"
strcpy(result,"MULTIPOINT");
else if (type == LINETYPE)
strcpy(result,"LINESTRING");
- else if (type == CIRCSTRINGTYPE)
- strcpy(result,"CIRCULARSTRING");
- else if (type == COMPOUNDTYPE)
- strcpy(result, "COMPOUNDCURVE");
+ else if (type == CIRCSTRINGTYPE)
+ strcpy(result,"CIRCULARSTRING");
+ else if (type == COMPOUNDTYPE)
+ strcpy(result, "COMPOUNDCURVE");
else if (type == MULTILINETYPE)
strcpy(result,"MULTILINESTRING");
- else if (type == MULTICURVETYPE)
- strcpy(result, "MULTICURVE");
+ else if (type == MULTICURVETYPE)
+ strcpy(result, "MULTICURVE");
else if (type == POLYGONTYPE)
strcpy(result,"POLYGON");
- else if (type == CURVEPOLYTYPE)
- strcpy(result,"CURVEPOLYGON");
+ else if (type == CURVEPOLYTYPE)
+ strcpy(result,"CURVEPOLYGON");
else if (type == MULTIPOLYGONTYPE)
strcpy(result,"MULTIPOLYGON");
- else if (type == MULTISURFACETYPE)
- strcpy(result, "MULTISURFACE");
+ else if (type == MULTISURFACETYPE)
+ strcpy(result, "MULTISURFACE");
else if (type == COLLECTIONTYPE)
strcpy(result,"GEOMETRYCOLLECTION");
else
PG_RETURN_POINTER(text_ob);
}
-/*
+/**
* Find first linestring in serialized geometry and return
* the number of points in it. If no linestrings are found
* return -1.
LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized);
int i;
- LWDEBUG(2, "lwgeom_numpoints_linestring_recursive called.");
+ LWDEBUG(2, "lwgeom_numpoints_linestring_recursive called.");
for (i=0; i<inspected->ngeometries; i++)
{
int32 npoints;
int type;
- LWGEOM *geom=NULL;
+ LWGEOM *geom=NULL;
uchar *subgeom;
- geom = lwgeom_getgeom_inspected(inspected, i);
+ geom = lwgeom_getgeom_inspected(inspected, i);
- LWDEBUGF(3, "numpoints_recursive: type=%d", lwgeom_getType(geom->type));
+ LWDEBUGF(3, "numpoints_recursive: type=%d", lwgeom_getType(geom->type));
- if(lwgeom_getType(geom->type) == LINETYPE)
- {
- return ((LWLINE *)geom)->points->npoints;
- }
+ if(lwgeom_getType(geom->type) == LINETYPE)
+ {
+ return ((LWLINE *)geom)->points->npoints;
+ }
subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
if ( subgeom == NULL )
npoints = lwgeom_numpoints_linestring_recursive(subgeom);
if ( npoints == -1 ) continue;
- lwinspected_release(inspected);
+ lwinspected_release(inspected);
return npoints;
}
- lwinspected_release(inspected);
+ lwinspected_release(inspected);
return -1;
}
-/*
+/**
* numpoints(GEOMETRY) -- find the first linestring in GEOMETRY, return
* the number of points in it. Return NULL if there is no LINESTRING(..)
* in GEOMETRY
PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
int32 ret;
- POSTGIS_DEBUG(2, "LWGEOM_numpoints_linestring called.");
+ POSTGIS_DEBUG(2, "LWGEOM_numpoints_linestring called.");
ret = lwgeom_numpoints_linestring_recursive(SERIALIZED_FORM(geom));
if ( ret == -1 )
uchar *serialized = SERIALIZED_FORM(geom);
type = lwgeom_getType(geom->type);
- if (type==MULTIPOINTTYPE || type==MULTILINETYPE ||
- type==MULTICURVETYPE || type==MULTIPOLYGONTYPE ||
- type==MULTISURFACETYPE || type==COLLECTIONTYPE)
+ if (type==MULTIPOINTTYPE || type==MULTILINETYPE ||
+ type==MULTICURVETYPE || type==MULTIPOLYGONTYPE ||
+ type==MULTISURFACETYPE || type==COLLECTIONTYPE)
{
ret = lwgeom_getnumgeometries(serialized);
PG_FREE_IF_COPY(geom, 0);
PG_RETURN_NULL();
}
-/* 1-based offset */
+/** 1-based offset */
PG_FUNCTION_INFO_V1(LWGEOM_geometryn_collection);
Datum LWGEOM_geometryn_collection(PG_FUNCTION_ARGS)
{
LWCOLLECTION *coll;
LWGEOM *subgeom;
- POSTGIS_DEBUG(2, "LWGEOM_geometryn_collection called.");
+ 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)
+ type==COMPOUNDTYPE || type==POLYGONTYPE || type==CURVEPOLYTYPE)
{
/* elog(NOTICE, "geometryn: geom is of type %d, requires >=4", type); */
PG_RETURN_NULL();
}
-/*
- * returns 0 for points, 1 for lines, 2 for polygons.
- * returns max dimension for a collection.
- * returns -1 for the empty geometry (TODO)
- * returns -2 on error
+/**
+ * @brief returns 0 for points, 1 for lines, 2 for polygons.
+ * returns max dimension for a collection.
+ * returns -1 for the empty geometry (TODO)
+ * returns -2 on error
*/
static int32
lwgeom_dimension_recursive(const uchar *serialized)
int ret = -1;
int i;
- /*
- * This has the unfortunate habit of traversing the CURVEPOLYTYPe
- * geoms and returning 1, as all contained geoms are linear.
- * Here we preempt this problem.
- * TODO: This should handle things a bit better. Only
- * GEOMETRYCOLLECTION should ever need to be traversed.
- */
+ /** @todo
+ * This has the unfortunate habit of traversing the CURVEPOLYTYPe
+ * geoms and returning 1, as all contained geoms are linear.
+ * Here we preempt this problem.
+ * TODO: This should handle things a bit better. Only
+ * GEOMETRYCOLLECTION should ever need to be traversed.
+ */
if(lwgeom_getType(serialized[0]) == CURVEPOLYTYPE) return 2;
inspected = lwgeom_inspect(serialized);
int type = lwgeom_getType(typeflags);
int dims=-1;
- LWDEBUGF(3, "lwgeom_dimension_recursive: type %d", type);
+ LWDEBUGF(3, "lwgeom_dimension_recursive: type %d", type);
if ( type == POINTTYPE ) dims = 0;
else if ( type == MULTIPOINTTYPE ) dims=0;
else if ( type == LINETYPE ) dims=1;
- else if ( type == CIRCSTRINGTYPE ) dims=1;
- else if ( type == COMPOUNDTYPE ) dims=1;
+ else if ( type == CIRCSTRINGTYPE ) dims=1;
+ else if ( type == COMPOUNDTYPE ) dims=1;
else if ( type == MULTILINETYPE ) dims=1;
- else if ( type == MULTICURVETYPE ) dims=1;
+ else if ( type == MULTICURVETYPE ) dims=1;
else if ( type == POLYGONTYPE ) dims=2;
- else if ( type == CURVEPOLYTYPE ) dims=2;
+ else if ( type == CURVEPOLYTYPE ) dims=2;
else if ( type == MULTIPOLYGONTYPE ) dims=2;
- else if ( type == MULTISURFACETYPE ) dims=2;
- else if ( type == COLLECTIONTYPE )
+ else if ( type == MULTISURFACETYPE ) dims=2;
+ else if ( type == COLLECTIONTYPE )
{
subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
if ( subgeom == NULL ) {
return ret;
}
-/*
- * returns 0 for points, 1 for lines, 2 for polygons.
- * returns max dimension for a collection.
- * returns -1 for the empty geometry (TODO)
+/** @brief
+ * returns 0 for points, 1 for lines, 2 for polygons.
+ * returns max dimension for a collection.
+ * TODO: @todo return -1 for the empty geometry (TODO)
*/
PG_FUNCTION_INFO_V1(LWGEOM_dimension);
Datum LWGEOM_dimension(PG_FUNCTION_ARGS)
PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
int dimension;
- POSTGIS_DEBUG(2, "LWGEOM_dimension called");
+ POSTGIS_DEBUG(2, "LWGEOM_dimension called");
dimension = lwgeom_dimension_recursive(SERIALIZED_FORM(geom));
if ( dimension == -1 )
}
-/*
- * exteriorRing(GEOMETRY) -- find the first polygon in GEOMETRY, return
- * its exterior ring (as a linestring).
- * Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
+/**
+ * exteriorRing(GEOMETRY) -- find the first polygon in GEOMETRY
+ * @return its exterior ring (as a linestring).
+ * Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
*/
PG_FUNCTION_INFO_V1(LWGEOM_exteriorring_polygon);
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;
+ LWCURVEPOLY *curvepoly = NULL;
POINTARRAY *extring;
- LWGEOM *ring;
+ LWGEOM *ring;
LWLINE *line;
PG_LWGEOM *result;
BOX2DFLOAT4 *bbox=NULL;
- POSTGIS_DEBUG(2, "LWGEOM_exteriorring_polygon called.");
+ POSTGIS_DEBUG(2, "LWGEOM_exteriorring_polygon called.");
- if ( TYPE_GETTYPE(geom->type) != POLYGONTYPE &&
- TYPE_GETTYPE(geom->type) != CURVEPOLYTYPE)
+ 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);
- }
+ 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);
}
-/*
- * NumInteriorRings(GEOMETRY) -- find the first polygon in GEOMETRY, return
- * the number of its interior rings (holes).
- * Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
+/**
+ * NumInteriorRings(GEOMETRY) -- find the first polygon in GEOMETRY,
+ * @return the number of its interior rings (holes).
+ * Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
*/
PG_FUNCTION_INFO_V1(LWGEOM_numinteriorrings_polygon);
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;
+ LWGEOM *tmp = NULL;
LWPOLY *poly = NULL;
- LWCURVEPOLY *curvepoly = NULL;
+ LWCURVEPOLY *curvepoly = NULL;
int32 result;
int i;
- POSTGIS_DEBUG(2, "LWGEOM_numinteriorrings called.");
+ 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));
+ 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);
+ tmp = lwgeom_getgeom_inspected(inspected, i);
if (lwgeom_getType(tmp->type) == POLYGONTYPE ||
- lwgeom_getType(tmp->type) == CURVEPOLYTYPE) break;
+ lwgeom_getType(tmp->type) == CURVEPOLYTYPE) break;
}
- }
+ }
if ( tmp == NULL ) {
PG_FREE_IF_COPY(geom, 0);
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
- {
+ 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);
+ if(inspected != NULL) lwinspected_release(inspected);
lwgeom_release((LWGEOM *)tmp);
PG_RETURN_INT32(result);
}
-/*
- * InteriorRingN(GEOMETRY) -- find the first polygon in GEOMETRY, return
- * its Nth interior ring (as a linestring).
- * Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
- * Index is 1-based
+/**
+ * InteriorRingN(GEOMETRY) -- find the first polygon in GEOMETRY, Index is 1-based.
+ * @return its Nth interior ring (as a linestring).
+ * Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
+ *
*/
PG_FUNCTION_INFO_V1(LWGEOM_interiorringn_polygon);
Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS)
{
PG_LWGEOM *geom;
int32 wanted_index;
- LWCURVEPOLY *curvepoly = NULL;
+ LWCURVEPOLY *curvepoly = NULL;
LWPOLY *poly = NULL;
POINTARRAY *ring;
LWLINE *line;
PG_LWGEOM *result;
BOX2DFLOAT4 *bbox = NULL;
- POSTGIS_DEBUG(2, "LWGEOM_interierringn_polygon called.");
+ POSTGIS_DEBUG(2, "LWGEOM_interierringn_polygon called.");
wanted_index = PG_GETARG_INT32(1);
if ( wanted_index < 1 )
geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
if ( TYPE_GETTYPE(geom->type) != POLYGONTYPE &&
- TYPE_GETTYPE(geom->type) != CURVEPOLYTYPE )
+ 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);
- }
+ 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);
}
-/*
+/**
* PointN(GEOMETRY,INTEGER) -- find the first linestring in GEOMETRY,
- * return the point at index INTEGER (1 is 1st point). Return NULL if
- * there is no LINESTRING(..) in GEOMETRY or INTEGER is out of bounds.
+ * @return the point at index INTEGER (1 is 1st point). Return NULL if
+ * there is no LINESTRING(..) in GEOMETRY or INTEGER is out of bounds.
*/
PG_FUNCTION_INFO_V1(LWGEOM_pointn_linestring);
Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS)
int32 wanted_index;
LWGEOM_INSPECTED *inspected;
LWLINE *line = NULL;
- LWCIRCSTRING *curve = NULL;
- LWGEOM *tmp = NULL;
+ LWCIRCSTRING *curve = NULL;
+ LWGEOM *tmp = NULL;
POINTARRAY *pts;
LWPOINT *point;
uchar *serializedpoint;
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();
- }
- }
+ 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),
PG_RETURN_POINTER(result);
}
-/*
+/**
* X(GEOMETRY) -- return X value of the point.
- * Raise an error if input is not a point.
+ * @return an error if input is not a point.
*/
PG_FUNCTION_INFO_V1(LWGEOM_x_point);
Datum LWGEOM_x_point(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(p.x);
}
-/*
+/**
* Y(GEOMETRY) -- return Y value of the point.
- * Raise an error if input is not a point.
+ * Raise an error if input is not a point.
*/
PG_FUNCTION_INFO_V1(LWGEOM_y_point);
Datum LWGEOM_y_point(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(p.y);
}
-/*
+/**
* Z(GEOMETRY) -- return Z value of the point.
- * Return NULL if there is no Z in the point.
- * Raise an error if input is not a point.
+ * @return NULL if there is no Z in the point.
+ * Raise an error if input is not a point.
*/
PG_FUNCTION_INFO_V1(LWGEOM_z_point);
Datum LWGEOM_z_point(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(p.z);
}
-/* M(GEOMETRY) -- find the first POINT(..) in GEOMETRY, returns its M value.
- * Return NULL if there is no POINT(..) in GEOMETRY.
- * Return NULL if there is no M in this geometry.
+/** M(GEOMETRY) -- find the first POINT(..) in GEOMETRY, returns its M value.
+ * @return NULL if there is no POINT(..) in GEOMETRY.
+ * Return NULL if there is no M in this geometry.
*/
PG_FUNCTION_INFO_V1(LWGEOM_m_point);
Datum LWGEOM_m_point(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(p.m);
}
-/* StartPoint(GEOMETRY) -- find the first linestring in GEOMETRY,
- * return the first point.
- * Return NULL if there is no LINESTRING(..) in GEOMETRY
+/** StartPoint(GEOMETRY) -- find the first linestring in GEOMETRY,
+ * @return the first point.
+ * Return NULL if there is no LINESTRING(..) in GEOMETRY
*/
PG_FUNCTION_INFO_V1(LWGEOM_startpoint_linestring);
Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS)
PG_LWGEOM *result;
int i, type;
- POSTGIS_DEBUG(2, "LWGEOM_startpoint_linestring called.");
+ POSTGIS_DEBUG(2, "LWGEOM_startpoint_linestring called.");
geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
PG_RETURN_NULL();
}
- inspected = lwgeom_inspect(SERIALIZED_FORM(geom));
+ inspected = lwgeom_inspect(SERIALIZED_FORM(geom));
- for (i=0; i<inspected->ngeometries; i++)
- {
- line = lwgeom_getline_inspected(inspected, i);
- if ( line ) break;
- }
+ 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. */
+ /* 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 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);
PG_RETURN_POINTER(result);
}
-/* EndPoint(GEOMETRY) -- find the first linestring in GEOMETRY,
- * return the last point.
- * Return NULL if there is no LINESTRING(..) in GEOMETRY
+/** EndPoint(GEOMETRY) -- find the first linestring in GEOMETRY,
+ * @return the last point.
+ * Return NULL if there is no LINESTRING(..) in GEOMETRY
*/
PG_FUNCTION_INFO_V1(LWGEOM_endpoint_linestring);
Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS)
PG_LWGEOM *result;
int i, type;
- POSTGIS_DEBUG(2, "LWGEOM_endpoint_linestring called.");
+ 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]);
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);
+ 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. */
+ /* 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 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);
}
-/*
- * Given an OGC WKT (and optionally a SRID)
- * return a geometry.
- * Note that this is a a stricter version
- * of geometry_in, where we refuse to
- * accept (HEX)WKB or EWKT.
+/**
+ * @brief Returns a geometry Given an OGC WKT (and optionally a SRID)
+ * @return a geometry.
+ * @note Note that this is a a stricter version
+ * of geometry_in, where we refuse to
+ * accept (HEX)WKB or EWKT.
*/
PG_FUNCTION_INFO_V1(LWGEOM_from_text);
Datum LWGEOM_from_text(PG_FUNCTION_ARGS)
LWGEOM *lwgeom;
int result;
- POSTGIS_DEBUG(2, "LWGEOM_from_text");
+ POSTGIS_DEBUG(2, "LWGEOM_from_text");
size = VARSIZE(wkttext)-VARHDRSZ;
- POSTGIS_DEBUGF(3, "size: %d", (int)size);
+ POSTGIS_DEBUGF(3, "size: %d", (int)size);
if ( size < 10 )
{
PG_RETURN_POINTER(geom_result);
}
-/*
+/**
* Given an OGC WKB (and optionally a SRID)
- * return a geometry.
+ * return a geometry.
*
- * Note that this is a wrapper around
- * LWGEOMFromWKB, where we refuse to
- * accept EWKB.
+ * @note that this is a wrapper around
+ * LWGEOMFromWKB, where we refuse to
+ * accept EWKB.
*/
PG_FUNCTION_INFO_V1(LWGEOM_from_WKB);
Datum LWGEOM_from_WKB(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(result);
}
-/* convert LWGEOM to wkt (in TEXT format) */
+/** convert LWGEOM to wkt (in TEXT format) */
PG_FUNCTION_INFO_V1(LWGEOM_asText);
Datum LWGEOM_asText(PG_FUNCTION_ARGS)
{
int len, result;
char *lwgeom_result,*loc_wkt;
char *semicolonLoc;
-
+
POSTGIS_DEBUG(2, "LWGEOM_asText called.");
lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
PG_RETURN_POINTER(lwgeom_result);
}
-/* convert LWGEOM to wkb (in BINARY format) */
+/** convert LWGEOM to wkb (in BINARY format) */
PG_FUNCTION_INFO_V1(LWGEOM_asBinary);
Datum LWGEOM_asBinary(PG_FUNCTION_ARGS)
{
/* Force to 2d */
ogclwgeom = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
LWGEOM_force_2d, PG_GETARG_DATUM(0)));
-
+
/* Drop SRID */
ogclwgeom = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall2(
LWGEOM_setSRID, PointerGetDatum(ogclwgeom), -1));
{
POINT3DZ sp, ep;
- LWDEBUG(2, "line_is_closed called.");
+ LWDEBUG(2, "line_is_closed called.");
getPoint3dz_p(line->points, 0, &sp);
getPoint3dz_p(line->points, line->points->npoints-1, &ep);
char circstring_is_closed(LWCIRCSTRING *curve)
{
- POINT3DZ sp, ep;
+ POINT3DZ sp, ep;
- LWDEBUG(2, "circstring_is_closed called.");
+ LWDEBUG(2, "circstring_is_closed called.");
- getPoint3dz_p(curve->points, 0, &sp);
- getPoint3dz_p(curve->points, curve->points->npoints-1, &ep);
+ getPoint3dz_p(curve->points, 0, &sp);
+ getPoint3dz_p(curve->points, curve->points->npoints-1, &ep);
- if(sp.x != ep.x) return 0;
- if(sp.y != ep.y) return 0;
- if(TYPE_HASZ(curve->type))
- {
- if(sp.z != ep.z) return 0;
- }
- return 1;
-}
+ if(sp.x != ep.x) return 0;
+ if(sp.y != ep.y) return 0;
+ if(TYPE_HASZ(curve->type))
+ {
+ if(sp.z != ep.z) return 0;
+ }
+ return 1;
+}
char compound_is_closed(LWCOMPOUND *compound)
{
- POINT3DZ sp, ep;
- LWGEOM *tmp;
-
- LWDEBUG(2, "compound_is_closed called.");
-
- tmp = compound->geoms[0];
- if(lwgeom_getType(tmp->type) == LINETYPE)
- {
- getPoint3dz_p(((LWLINE *)tmp)->points, 0, &sp);
- }
- else
- {
- getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, 0, &sp);
- }
-
- tmp = compound->geoms[compound->ngeoms - 1];
- if(lwgeom_getType(tmp->type) == LINETYPE)
- {
- getPoint3dz_p(((LWLINE *)tmp)->points, ((LWLINE *)tmp)->points->npoints - 1, &ep);
- }
- else
- {
- getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, ((LWCIRCSTRING *)tmp)->points->npoints - 1, &ep);
- }
-
- if(sp.x != ep.x) return 0;
- if(sp.y != ep.y) return 0;
- if(TYPE_HASZ(compound->type))
- {
- if(sp.z != ep.z) return 0;
- }
- return 1;
+ POINT3DZ sp, ep;
+ LWGEOM *tmp;
+
+ LWDEBUG(2, "compound_is_closed called.");
+
+ tmp = compound->geoms[0];
+ if(lwgeom_getType(tmp->type) == LINETYPE)
+ {
+ getPoint3dz_p(((LWLINE *)tmp)->points, 0, &sp);
+ }
+ else
+ {
+ getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, 0, &sp);
+ }
+
+ tmp = compound->geoms[compound->ngeoms - 1];
+ if(lwgeom_getType(tmp->type) == LINETYPE)
+ {
+ getPoint3dz_p(((LWLINE *)tmp)->points, ((LWLINE *)tmp)->points->npoints - 1, &ep);
+ }
+ else
+ {
+ getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, ((LWCIRCSTRING *)tmp)->points->npoints - 1, &ep);
+ }
+
+ if(sp.x != ep.x) return 0;
+ if(sp.y != ep.y) return 0;
+ if(TYPE_HASZ(compound->type))
+ {
+ if(sp.z != ep.z) return 0;
+ }
+ return 1;
}
-/*
- * IsClosed(GEOMETRY) if geometry is a linestring then returns
- * startpoint == endpoint. If its not a linestring then return NULL.
- * If it's a collection containing multiple linestrings,
- * return true only if all the linestrings have startpoint=endpoint.
+/**
+ * @brief IsClosed(GEOMETRY) if geometry is a linestring then returns
+ * startpoint == endpoint. If its not a linestring then return NULL.
+ * If it's a collection containing multiple linestrings,
+ * @return true only if all the linestrings have startpoint=endpoint.
*/
PG_FUNCTION_INFO_V1(LWGEOM_isclosed_linestring);
Datum LWGEOM_isclosed_linestring(PG_FUNCTION_ARGS)
{
PG_LWGEOM *geom;
LWGEOM_INSPECTED *inspected;
- LWGEOM *sub = NULL;
- LWCOMPOUND *compound = NULL;
+ LWGEOM *sub = NULL;
+ LWCOMPOUND *compound = NULL;
int linesfound=0;
int i;
- POSTGIS_DEBUG(2, "LWGEOM_isclosed_linestring called.");
+ 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);
- }
- }
+ 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);
+ 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);
- }
+ 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++;
}
* This is free software; you can redistribute and/or modify it under
* the terms of hte GNU General Public Licence. See the COPYING file.
*
- **********************************************************************
+ **********************************************************************/
+
+ /** @file
*
* SVG output routines.
* Originally written by: Klaus Förster <klaus@svg.cc>
precision = MAX_DOUBLE_PRECISION;
else if ( precision < 0 ) precision = 0;
}
-
+
svg = geometry_to_svg(SERIALIZED_FORM(geom), relative, precision);
PG_FREE_IF_COPY(geom, 0);
}
-/*takes a GEOMETRY and returns a SVG representation */
+/** takes a GEOMETRY and returns a SVG representation */
char *
geometry_to_svg(uchar *geom, bool relative, int precision)
{
type = lwgeom_getType(geom[0]);
switch (type)
- {
- case POINTTYPE:
- ret = assvg_point(lwpoint_deserialize(geom), relative, precision);
- break;
+ {
+ case POINTTYPE:
+ ret = assvg_point(lwpoint_deserialize(geom), relative, precision);
+ break;
case LINETYPE:
- ret = assvg_line(lwline_deserialize(geom), relative, precision);
- break;
+ ret = assvg_line(lwline_deserialize(geom), relative, precision);
+ break;
case POLYGONTYPE:
- ret = assvg_polygon(lwpoly_deserialize(geom), relative, precision);
- break;
+ ret = assvg_polygon(lwpoly_deserialize(geom), relative, precision);
+ break;
case MULTIPOINTTYPE:
- ret = assvg_multipoint(lwgeom_inspect(geom), relative, precision);
+ ret = assvg_multipoint(lwgeom_inspect(geom), relative, precision);
break;
case MULTILINETYPE:
- ret = assvg_multiline(lwgeom_inspect(geom), relative, precision);
+ ret = assvg_multiline(lwgeom_inspect(geom), relative, precision);
break;
case MULTIPOLYGONTYPE:
- ret = assvg_multipolygon(lwgeom_inspect(geom), relative, precision);
+ ret = assvg_multipolygon(lwgeom_inspect(geom), relative, precision);
break;
case COLLECTIONTYPE:
- ret = assvg_collection(lwgeom_inspect(geom), relative, precision);
- break;
+ ret = assvg_collection(lwgeom_inspect(geom), relative, precision);
+ break;
default: lwerror("ST_AsSVG: '%s' geometry type not supported.",
- lwgeom_typename(type));
+ lwgeom_typename(type));
}
return ret;
}
-/*
+/**
* Point Geometry
*/
static size_t
assvg_point_size(LWPOINT *point, bool circle, int precision)
{
- size_t size;
+ size_t size;
size = (MAX_DIGS_DOUBLE + precision) * 2;
- if (circle) size += sizeof("cx='' cy=''");
- else size += sizeof("x='' y=''");
+ if (circle) size += sizeof("cx='' cy=''");
+ else size += sizeof("x='' y=''");
- return size;
+ return size;
}
static size_t
assvg_point_buf(LWPOINT *point, char * output, bool circle, int precision)
{
- char *ptr=output;
+ char *ptr=output;
char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
- char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
- POINT2D pt;
+ char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
+ POINT2D pt;
- getPoint2d_p(point->point, 0, &pt);
+ getPoint2d_p(point->point, 0, &pt);
sprintf(x, "%.*f", precision, pt.x);
- trim_trailing_zeros(x);
+ trim_trailing_zeros(x);
/* SVG Y axis is reversed, an no need to transform 0 into -0 */
- sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1 : pt.y);
- trim_trailing_zeros(y);
+ sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1 : pt.y);
+ trim_trailing_zeros(y);
if (circle) ptr += sprintf(ptr, "x=\"%s\" y=\"%s\"", x, y);
else ptr += sprintf(ptr, "cx=\"%s\" cy=\"%s\"", x, y);
- return (ptr-output);
+ return (ptr-output);
}
static char *
assvg_point(LWPOINT *point, bool circle, int precision)
{
- char *output;
- int size;
+ char *output;
+ int size;
- size = assvg_point_size(point, circle, precision);
- output = palloc(size);
- assvg_point_buf(point, output, circle, precision);
+ size = assvg_point_size(point, circle, precision);
+ output = palloc(size);
+ assvg_point_buf(point, output, circle, precision);
- return output;
+ return output;
}
-/*
+/**
* Line Geometry
*/
static size_t
assvg_line_size(LWLINE *line, bool relative, int precision)
{
- size_t size;
+ size_t size;
- size = sizeof("M ");
+ size = sizeof("M ");
size += pointArray_svg_size(line->points, precision);
- return size;
+ return size;
}
static size_t
assvg_line_buf(LWLINE *line, char * output, bool relative, int precision)
{
- char *ptr=output;
+ char *ptr=output;
/* Start path with SVG MoveTo */
- ptr += sprintf(ptr, "M ");
- if (relative)
+ ptr += sprintf(ptr, "M ");
+ if (relative)
ptr += pointArray_svg_rel(line->points, ptr, true, precision);
- else
+ else
ptr += pointArray_svg_abs(line->points, ptr, true, precision);
- return (ptr-output);
+ return (ptr-output);
}
static char *
assvg_line(LWLINE *line, bool relative, int precision)
{
- char *output;
- int size;
+ char *output;
+ int size;
- size = assvg_line_size(line, relative, precision);
- output = palloc(size);
- assvg_line_buf(line, output, relative, precision);
+ size = assvg_line_size(line, relative, precision);
+ output = palloc(size);
+ assvg_line_buf(line, output, relative, precision);
- return output;
+ return output;
}
-/*
+/**
* Polygon Geometry
*/
assvg_polygon_size(LWPOLY *poly, bool relative, int precision)
{
int i;
- size_t size=0;
+ size_t size=0;
for (i=0; i<poly->nrings; i++)
size += pointArray_svg_size(poly->rings[i], precision) + sizeof(" ");
size += sizeof("M Z") * poly->nrings;
- return size;
+ return size;
}
static size_t
assvg_polygon_buf(LWPOLY *poly, char * output, bool relative, int precision)
{
int i;
- char *ptr=output;
+ char *ptr=output;
for (i=0; i<poly->nrings; i++) {
if (i) ptr += sprintf(ptr, " "); /* Space beetween each ring */
- ptr += sprintf(ptr, "M "); /* Start path with SVG MoveTo */
+ ptr += sprintf(ptr, "M "); /* Start path with SVG MoveTo */
- if (relative) {
+ if (relative) {
ptr += pointArray_svg_rel(poly->rings[i], ptr, false, precision);
- ptr += sprintf(ptr, " z"); /* SVG closepath */
+ ptr += sprintf(ptr, " z"); /* SVG closepath */
} else {
ptr += pointArray_svg_abs(poly->rings[i], ptr, false, precision);
- ptr += sprintf(ptr, " Z"); /* SVG closepath */
- }
+ ptr += sprintf(ptr, " Z"); /* SVG closepath */
+ }
}
- return (ptr-output);
+ return (ptr-output);
}
static char *
assvg_polygon(LWPOLY *poly, bool relative, int precision)
{
- char *output;
- int size;
+ char *output;
+ int size;
- size = assvg_polygon_size(poly, relative, precision);
- output = palloc(size);
- assvg_polygon_buf(poly, output, relative, precision);
+ size = assvg_polygon_size(poly, relative, precision);
+ output = palloc(size);
+ assvg_polygon_buf(poly, output, relative, precision);
- return output;
+ return output;
}
-/*
+/**
* Multipoint Geometry
*/
{
LWPOINT *point;
size_t size=0;
- int i;
+ int i;
- for (i=0 ; i<insp->ngeometries ; i++) {
- point = lwgeom_getpoint_inspected(insp, i);
- size += assvg_point_size(point, relative, precision);
- if (point) lwpoint_release(point);
+ for (i=0 ; i<insp->ngeometries ; i++) {
+ point = lwgeom_getpoint_inspected(insp, i);
+ size += assvg_point_size(point, relative, precision);
+ if (point) lwpoint_release(point);
}
- size += sizeof(",") * --i; /* Arbitrary comma separator */
+ size += sizeof(",") * --i; /* Arbitrary comma separator */
return size;
}
assvg_multipoint_buf(LWGEOM_INSPECTED *insp, char *output, bool relative, int precision)
{
LWPOINT *point;
- int i;
- char *ptr=output;
+ int i;
+ char *ptr=output;
- for (i=0 ; i<insp->ngeometries ; i++)
- {
- if (i) ptr += sprintf(ptr, ","); /* Arbitrary comma separator */
- point = lwgeom_getpoint_inspected(insp, i);
- ptr += assvg_point_buf(point, ptr, relative, precision);
- if (point) lwpoint_release(point);
- }
+ for (i=0 ; i<insp->ngeometries ; i++)
+ {
+ if (i) ptr += sprintf(ptr, ","); /* Arbitrary comma separator */
+ point = lwgeom_getpoint_inspected(insp, i);
+ ptr += assvg_point_buf(point, ptr, relative, precision);
+ if (point) lwpoint_release(point);
+ }
return (ptr-output);
}
static char *
assvg_multipoint(LWGEOM_INSPECTED *point, bool relative, int precision)
{
- char *output;
- int size;
+ char *output;
+ int size;
- size = assvg_multipoint_size(point, relative, precision);
- output = palloc(size);
- assvg_multipoint_buf(point, output, relative, precision);
+ size = assvg_multipoint_size(point, relative, precision);
+ output = palloc(size);
+ assvg_multipoint_buf(point, output, relative, precision);
- return output;
+ return output;
}
-/*
+/**
* Multiline Geometry
*/
{
LWLINE *line;
size_t size=0;
- int i;
+ int i;
- for (i=0 ; i<insp->ngeometries ; i++) {
- line = lwgeom_getline_inspected(insp, i);
- size += assvg_line_size(line, relative, precision);
- if (line) lwline_release(line);
+ for (i=0 ; i<insp->ngeometries ; i++) {
+ line = lwgeom_getline_inspected(insp, i);
+ size += assvg_line_size(line, relative, precision);
+ if (line) lwline_release(line);
}
- size += sizeof(" ") * --i; /* SVG whitespace Separator */
+ size += sizeof(" ") * --i; /* SVG whitespace Separator */
return size;
}
assvg_multiline_buf(LWGEOM_INSPECTED *insp, char *output, bool relative, int precision)
{
LWLINE *line;
- int i;
- char *ptr=output;
+ int i;
+ char *ptr=output;
- for (i=0 ; i<insp->ngeometries ; i++)
- {
- if (i) ptr += sprintf(ptr, " "); /* SVG whitespace Separator */
- line = lwgeom_getline_inspected(insp, i);
- ptr += assvg_line_buf(line, ptr, relative, precision);
- if (line) lwline_release(line);
- }
+ for (i=0 ; i<insp->ngeometries ; i++)
+ {
+ if (i) ptr += sprintf(ptr, " "); /* SVG whitespace Separator */
+ line = lwgeom_getline_inspected(insp, i);
+ ptr += assvg_line_buf(line, ptr, relative, precision);
+ if (line) lwline_release(line);
+ }
return (ptr-output);
}
static char *
assvg_multiline(LWGEOM_INSPECTED *line, bool relative, int precision)
{
- char *output;
- int size;
+ char *output;
+ int size;
- size = assvg_multiline_size(line, relative, precision);
- output = palloc(size);
- assvg_multiline_buf(line, output, relative, precision);
+ size = assvg_multiline_size(line, relative, precision);
+ output = palloc(size);
+ assvg_multiline_buf(line, output, relative, precision);
- return output;
+ return output;
}
-/*
+/*
* Multipolygon Geometry
*/
{
LWPOLY *poly;
size_t size=0;
- int i;
+ int i;
- for (i=0 ; i<insp->ngeometries ; i++) {
- poly = lwgeom_getpoly_inspected(insp, i);
- size += assvg_polygon_size(poly, relative, precision);
- if (poly) lwpoly_release(poly);
+ for (i=0 ; i<insp->ngeometries ; i++) {
+ poly = lwgeom_getpoly_inspected(insp, i);
+ size += assvg_polygon_size(poly, relative, precision);
+ if (poly) lwpoly_release(poly);
}
- size += sizeof(" ") * --i; /* SVG whitespace Separator */
+ size += sizeof(" ") * --i; /* SVG whitespace Separator */
return size;
}
assvg_multipolygon_buf(LWGEOM_INSPECTED *insp, char *output, bool relative, int precision)
{
LWPOLY *poly;
- int i;
- char *ptr=output;
+ int i;
+ char *ptr=output;
- for (i=0 ; i<insp->ngeometries ; i++)
- {
- if (i) ptr += sprintf(ptr, " "); /* SVG whitespace Separator */
- poly = lwgeom_getpoly_inspected(insp, i);
- ptr += assvg_polygon_buf(poly, ptr, relative, precision);
- if (poly) lwpoly_release(poly);
- }
+ for (i=0 ; i<insp->ngeometries ; i++)
+ {
+ if (i) ptr += sprintf(ptr, " "); /* SVG whitespace Separator */
+ poly = lwgeom_getpoly_inspected(insp, i);
+ ptr += assvg_polygon_buf(poly, ptr, relative, precision);
+ if (poly) lwpoly_release(poly);
+ }
return (ptr-output);
}
static char *
assvg_multipolygon(LWGEOM_INSPECTED *poly, bool relative, int precision)
{
- char *output;
- int size;
+ char *output;
+ int size;
- size = assvg_multipolygon_size(poly, relative, precision);
- output = palloc(size);
- assvg_multipolygon_buf(poly, output, relative, precision);
+ size = assvg_multipolygon_size(poly, relative, precision);
+ output = palloc(size);
+ assvg_multipolygon_buf(poly, output, relative, precision);
- return output;
+ return output;
}
- /*
+ /**
* Collection Geometry
*/
static size_t
assvg_collection_size(LWGEOM_INSPECTED *insp, bool relative, int precision)
{
- int i;
- size_t size=0;
- LWGEOM_INSPECTED *subinsp;
- uchar *subgeom;
-
- for (i=0; i<insp->ngeometries; i++)
- {
- subgeom = lwgeom_getsubgeometry_inspected(insp, i);
- subinsp = lwgeom_inspect(subgeom);
- size += assvg_inspected_size(subinsp, relative, precision);
- lwinspected_release(subinsp);
- }
- size += sizeof(";") * --i;
-
- return size;
+ int i;
+ size_t size=0;
+ LWGEOM_INSPECTED *subinsp;
+ uchar *subgeom;
+
+ for (i=0; i<insp->ngeometries; i++)
+ {
+ subgeom = lwgeom_getsubgeometry_inspected(insp, i);
+ subinsp = lwgeom_inspect(subgeom);
+ size += assvg_inspected_size(subinsp, relative, precision);
+ lwinspected_release(subinsp);
+ }
+ size += sizeof(";") * --i;
+
+ return size;
}
static size_t
assvg_collection_buf(LWGEOM_INSPECTED *insp, char *output, bool relative, int precision)
{
- int i;
- char *ptr=output;
- LWGEOM_INSPECTED *subinsp;
- uchar *subgeom;
-
- for (i=0; i<insp->ngeometries; i++)
- {
- if (i) ptr += sprintf(ptr, ";");
- subgeom = lwgeom_getsubgeometry_inspected(insp, i);
- subinsp = lwgeom_inspect(subgeom);
- ptr += assvg_inspected_buf(subinsp, ptr, relative, precision);
- lwinspected_release(subinsp);
- }
-
- return (ptr - output);
+ int i;
+ char *ptr=output;
+ LWGEOM_INSPECTED *subinsp;
+ uchar *subgeom;
+
+ for (i=0; i<insp->ngeometries; i++)
+ {
+ if (i) ptr += sprintf(ptr, ";");
+ subgeom = lwgeom_getsubgeometry_inspected(insp, i);
+ subinsp = lwgeom_inspect(subgeom);
+ ptr += assvg_inspected_buf(subinsp, ptr, relative, precision);
+ lwinspected_release(subinsp);
+ }
+
+ return (ptr - output);
}
static char *
assvg_collection(LWGEOM_INSPECTED *insp, bool relative, int precision)
{
- char *output;
- int size;
+ char *output;
+ int size;
- size = assvg_collection_size(insp, relative, precision);
- output = palloc(size);
- assvg_collection_buf(insp, output, relative, precision);
+ size = assvg_collection_size(insp, relative, precision);
+ output = palloc(size);
+ assvg_collection_buf(insp, output, relative, precision);
- return output;
+ return output;
}
static size_t
assvg_inspected_buf(LWGEOM_INSPECTED *insp, char *output, bool relative, int precision)
{
- LWPOINT *point;
- LWLINE *line;
- LWPOLY *poly;
- int type = lwgeom_getType(insp->serialized_form[0]);
- char *ptr=output;
+ LWPOINT *point;
+ LWLINE *line;
+ LWPOLY *poly;
+ int type = lwgeom_getType(insp->serialized_form[0]);
+ char *ptr=output;
switch(type) {
- case POINTTYPE:
- point=lwgeom_getpoint_inspected(insp, 0);
- ptr += assvg_point_buf(point, ptr, relative, precision);
- lwpoint_release(point);
- break;
-
- case LINETYPE:
- line=lwgeom_getline_inspected(insp, 0);
- ptr += assvg_line_buf(line, ptr, relative, precision);
- lwline_release(line);
- break;
-
- case POLYGONTYPE:
- poly=lwgeom_getpoly_inspected(insp, 0);
- ptr += assvg_polygon_buf(poly, ptr, relative, precision);
- lwpoly_release(poly);
- break;
-
- case MULTIPOINTTYPE:
- ptr += assvg_multipoint_buf(insp, ptr, relative, precision);
- break;
-
- case MULTILINETYPE:
- ptr += assvg_multiline_buf(insp, ptr, relative, precision);
- break;
-
- case MULTIPOLYGONTYPE:
+ case POINTTYPE:
+ point=lwgeom_getpoint_inspected(insp, 0);
+ ptr += assvg_point_buf(point, ptr, relative, precision);
+ lwpoint_release(point);
+ break;
+
+ case LINETYPE:
+ line=lwgeom_getline_inspected(insp, 0);
+ ptr += assvg_line_buf(line, ptr, relative, precision);
+ lwline_release(line);
+ break;
+
+ case POLYGONTYPE:
+ poly=lwgeom_getpoly_inspected(insp, 0);
+ ptr += assvg_polygon_buf(poly, ptr, relative, precision);
+ lwpoly_release(poly);
+ break;
+
+ case MULTIPOINTTYPE:
+ ptr += assvg_multipoint_buf(insp, ptr, relative, precision);
+ break;
+
+ case MULTILINETYPE:
+ ptr += assvg_multiline_buf(insp, ptr, relative, precision);
+ break;
+
+ case MULTIPOLYGONTYPE:
ptr += assvg_multipolygon_buf(insp, ptr, relative, precision);
- break;
+ break;
default: lwerror("ST_AsSVG: '%s' geometry type not supported.",
- lwgeom_typename(type));
- }
+ lwgeom_typename(type));
+ }
- return (ptr-output);
+ return (ptr-output);
}
static size_t
assvg_inspected_size(LWGEOM_INSPECTED *insp, bool relative, int precision)
{
- int type = lwgeom_getType(insp->serialized_form[0]);
- size_t size = 0;
- LWPOINT *point;
- LWLINE *line;
- LWPOLY *poly;
-
- switch(type) {
- case POINTTYPE:
- point=lwgeom_getpoint_inspected(insp, 0);
- size = assvg_point_size(point, relative, precision);
- lwpoint_release(point);
- break;
-
- case LINETYPE:
- line=lwgeom_getline_inspected(insp, 0);
- size = assvg_line_size(line, relative, precision);
- lwline_release(line);
- break;
-
- case POLYGONTYPE:
- poly=lwgeom_getpoly_inspected(insp, 0);
- size = assvg_polygon_size(poly, relative, precision);
- lwpoly_release(poly);
-
- case MULTIPOINTTYPE:
- size = assvg_multipoint_size(insp, relative, precision);
- break;
-
- case MULTILINETYPE:
- size = assvg_multiline_size(insp, relative, precision);
- break;
-
- case MULTIPOLYGONTYPE:
- size = assvg_multipolygon_size(insp, relative, precision);
- break;
-
- default: lwerror("ST_AsSVG: geometry not supported.");
- }
-
- return size;
+ int type = lwgeom_getType(insp->serialized_form[0]);
+ size_t size = 0;
+ LWPOINT *point;
+ LWLINE *line;
+ LWPOLY *poly;
+
+ switch(type) {
+ case POINTTYPE:
+ point=lwgeom_getpoint_inspected(insp, 0);
+ size = assvg_point_size(point, relative, precision);
+ lwpoint_release(point);
+ break;
+
+ case LINETYPE:
+ line=lwgeom_getline_inspected(insp, 0);
+ size = assvg_line_size(line, relative, precision);
+ lwline_release(line);
+ break;
+
+ case POLYGONTYPE:
+ poly=lwgeom_getpoly_inspected(insp, 0);
+ size = assvg_polygon_size(poly, relative, precision);
+ lwpoly_release(poly);
+
+ case MULTIPOINTTYPE:
+ size = assvg_multipoint_size(insp, relative, precision);
+ break;
+
+ case MULTILINETYPE:
+ size = assvg_multiline_size(insp, relative, precision);
+ break;
+
+ case MULTIPOLYGONTYPE:
+ size = assvg_multipolygon_size(insp, relative, precision);
+ break;
+
+ default: lwerror("ST_AsSVG: geometry not supported.");
+ }
+
+ return size;
}
static size_t
pointArray_svg_rel(POINTARRAY *pa, char *output, bool close_ring, int precision)
{
- int i, end;
- char *ptr;
- char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
- char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
- POINT2D pt, lpt;
-
- ptr = output;
-
+ int i, end;
+ char *ptr;
+ char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
+ char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
+ POINT2D pt, lpt;
+
+ ptr = output;
+
if (close_ring) end = pa->npoints;
else end = pa->npoints - 1;
/* Starting point */
getPoint2d_p(pa, 0, &pt);
- sprintf(x, "%.*f", precision, pt.x);
- trim_trailing_zeros(x);
- sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1 : pt.y);
- trim_trailing_zeros(y);
- ptr += sprintf(ptr,"%s %s l", x, y);
+ sprintf(x, "%.*f", precision, pt.x);
+ trim_trailing_zeros(x);
+ sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1 : pt.y);
+ trim_trailing_zeros(y);
+ ptr += sprintf(ptr,"%s %s l", x, y);
/* All the following ones */
- for (i=1 ; i < end ; i++) {
- lpt = pt;
- getPoint2d_p(pa, i, &pt);
+ for (i=1 ; i < end ; i++) {
+ lpt = pt;
+ getPoint2d_p(pa, i, &pt);
sprintf(x, "%.*f", precision, pt.x -lpt.x);
- trim_trailing_zeros(x);
+ trim_trailing_zeros(x);
/* SVG Y axis is reversed, an no need to transform 0 into -0 */
- sprintf(y, "%.*f", precision,
+ sprintf(y, "%.*f", precision,
fabs(pt.y -lpt.y) ? (pt.y - lpt.y) * -1: (pt.y - lpt.y));
- trim_trailing_zeros(y);
- ptr += sprintf(ptr," %s %s", x, y);
- }
+ trim_trailing_zeros(y);
+ ptr += sprintf(ptr," %s %s", x, y);
+ }
return (ptr-output);
}
-/*
+/**
* Returns maximum size of rendered pointarray in bytes.
*/
static size_t
pointArray_svg_abs(POINTARRAY *pa, char *output, bool close_ring, int precision)
{
- int i, end;
- char *ptr;
- char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
- char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
- POINT2D pt;
+ int i, end;
+ char *ptr;
+ char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
+ char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
+ POINT2D pt;
- ptr = output;
+ ptr = output;
if (close_ring) end = pa->npoints;
else end = pa->npoints - 1;
- for (i=0 ; i < end ; i++) {
- getPoint2d_p(pa, i, &pt);
+ for (i=0 ; i < end ; i++) {
+ getPoint2d_p(pa, i, &pt);
sprintf(x, "%.*f", precision, pt.x);
- trim_trailing_zeros(x);
+ trim_trailing_zeros(x);
/* SVG Y axis is reversed, an no need to transform 0 into -0 */
- sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1:pt.y);
- trim_trailing_zeros(y);
+ sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1:pt.y);
+ trim_trailing_zeros(y);
if (i == 1) ptr += sprintf(ptr, " L ");
else if (i) ptr += sprintf(ptr, " ");
- ptr += sprintf(ptr,"%s %s", x, y);
- }
+ ptr += sprintf(ptr,"%s %s", x, y);
+ }
return (ptr-output);
}
-/*
+/**
* Returns maximum size of rendered pointarray in bytes.
*/
static size_t
pointArray_svg_size(POINTARRAY *pa, int precision)
{
- return (MAX_DIGS_DOUBLE + precision + sizeof(" "))
- * 2 * pa->npoints + sizeof(" L ");
+ return (MAX_DIGS_DOUBLE + precision + sizeof(" "))
+ * 2 * pa->npoints + sizeof(" L ");
}
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
- *
+ *
**********************************************************************/
#include "postgres.h"
* typically have 2 entries per portal
* then we shall use a default size of 32)
*/
-#define PROJ4_BACKEND_HASH_SIZE 32
+#define PROJ4_BACKEND_HASH_SIZE 32
/* An entry in the PROJ4 SRS cache */
typedef struct struct_PROJ4SRSCacheItem
{
int srid;
- projPJ projection;
+ projPJ projection;
MemoryContext projection_mcxt;
} PROJ4SRSCacheItem;
-/* The portal cache: it's contents and cache context */
+/** The portal cache: it's contents and cache context
+ */
typedef struct struct_PROJ4PortalCache
{
PROJ4SRSCacheItem PROJ4SRSCache[PROJ4_CACHE_ITEMS];
} PROJ4PortalCache;
-/*
+/**
* Backend projPJ hash table
*
* This hash table stores a key/value pair of MemoryContext/projPJ objects.
LWDEBUGF(3, "deleting projection object (%p) with MemoryContext key (%p)", projection, context);
/* Free it */
- pj_free(projection);
+ pj_free(projection);
/* Remove the hash entry as it is no longer needed */
DeletePJHashEntry(context);
{
/*
* Always return false since this call is mandatory according to tgl
- * (see postgis-devel archives July 2007)
+ * (see postgis-devel archives July 2007)
*/
- return FALSE;
+ return FALSE;
}
static void
* Simple stats display function - we must supply a function since this call is mandatory according to tgl
* (see postgis-devel archives July 2007)
*/
-
- fprintf(stderr, "%s: PROJ4 context\n", context->name);
+
+ fprintf(stderr, "%s: PROJ4 context\n", context->name);
}
#ifdef MEMORY_CONTEXT_CHECKING
*/
-/*
+/**
* A version of tag_hash - we specify this here as the implementation
* has changed over the years....
*/
/* The hash key is the MemoryContext pointer */
key = (void *)&mcxt;
-
+
he = (PJHashEntry *) hash_search(PJHash, key, HASH_ENTER, &found);
if (!found)
{
static void DeletePJHashEntry(MemoryContext mcxt)
{
void **key;
- PJHashEntry *he;
+ PJHashEntry *he;
/* The hash key is the MemoryContext pointer */
key = (void *)&mcxt;
* Return true/false depending upon whether the item
* is in the SRS cache.
*/
-
+
int i;
for (i = 0; i < PROJ4_CACHE_ITEMS; i++)
}
-/*
+/**
* Return the projection object from the cache (we should
* already have checked it exists using IsInPROJ4SRSCache first)
*/
-projPJ
+projPJ
GetProjectionFromPROJ4SRSCache(PROJ4PortalCache *PROJ4Cache, int srid)
{
int i;
}
-/*
+/**
* Add an entry to the local PROJ4 SRS cache. If we need to wrap around then
* we must make sure the entry we choose to delete does not contain other_srid
* which is the definition for the other half of the transformation.
/* Connect */
spi_result = SPI_connect();
- if (spi_result != SPI_OK_CONNECT)
- {
- elog(ERROR, "AddToPROJ4SRSCache: Could not connect to database using SPI");
- }
-
- /* Execute the lookup query */
- snprintf(proj4_spi_buffer, 255, "SELECT proj4text FROM spatial_ref_sys WHERE srid = %d LIMIT 1", srid);
- spi_result = SPI_exec(proj4_spi_buffer, 1);
-
- /* Read back the PROJ4 text */
- if (spi_result == SPI_OK_SELECT && SPI_processed > 0)
- {
- /* Select the first (and only tuple) */
- TupleDesc tupdesc = SPI_tuptable->tupdesc;
- SPITupleTable *tuptable = SPI_tuptable;
- HeapTuple tuple = tuptable->vals[0];
+ if (spi_result != SPI_OK_CONNECT)
+ {
+ elog(ERROR, "AddToPROJ4SRSCache: Could not connect to database using SPI");
+ }
+
+ /* Execute the lookup query */
+ snprintf(proj4_spi_buffer, 255, "SELECT proj4text FROM spatial_ref_sys WHERE srid = %d LIMIT 1", srid);
+ spi_result = SPI_exec(proj4_spi_buffer, 1);
+
+ /* Read back the PROJ4 text */
+ if (spi_result == SPI_OK_SELECT && SPI_processed > 0)
+ {
+ /* Select the first (and only tuple) */
+ TupleDesc tupdesc = SPI_tuptable->tupdesc;
+ SPITupleTable *tuptable = SPI_tuptable;
+ HeapTuple tuple = tuptable->vals[0];
/* Make a projection object out of it */
proj_str = palloc(strlen(SPI_getvalue(tuple, tupdesc, 1)) + 1);
if (PROJ4Cache->PROJ4SRSCache[i].srid != other_srid && found == false)
{
LWDEBUGF(3, "choosing to remove item from query cache with SRID %d and index %d", PROJ4Cache->PROJ4SRSCache[i].srid, i);
-
+
DeleteFromPROJ4SRSCache(PROJ4Cache, PROJ4Cache->PROJ4SRSCache[i].srid);
PROJ4Cache->PROJ4SRSCacheCount = i;
LWDEBUGF(3, "adding projection object (%p) to hash table with MemoryContext key (%p)", projection, PJMemoryContext);
AddPJHashEntry(PJMemoryContext, projection);
-
+
PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].srid = srid;
PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].projection = projection;
PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].projection_mcxt = PJMemoryContext;
/* Free the projection string */
pfree(proj_str);
}
- else
- {
- elog(ERROR, "AddToPROJ4SRSCache: Cannot find SRID (%d) in spatial_ref_sys", srid);
- }
-
- /* Close the connection */
- spi_result = SPI_finish();
- if (spi_result != SPI_OK_FINISH)
- {
- elog(ERROR, "AddToPROJ4SRSCache: Could not disconnect from database using SPI");
- }
+ else
+ {
+ elog(ERROR, "AddToPROJ4SRSCache: Cannot find SRID (%d) in spatial_ref_sys", srid);
+ }
+
+ /* Close the connection */
+ spi_result = SPI_finish();
+ if (spi_result != SPI_OK_FINISH)
+ {
+ elog(ERROR, "AddToPROJ4SRSCache: Could not disconnect from database using SPI");
+ }
}
}
-/*
+/**
* Specify an alternate directory for the PROJ.4 grid files
* (this should augment the PROJ.4 compile-time path)
*
*
* Note that we currently ignore this on PostgreSQL < 8.0
* since the method of determining the current installation
- * path are different on older PostgreSQL versions.
+ * path are different on older PostgreSQL versions.
*/
void SetPROJ4LibPath(void)
{
char *path;
const char **proj_lib_path;
- /*
+ /*
* Get the sharepath and append /contrib/postgis/proj to form a suitable
* directory in which to store the grid shift files
- */
+ */
proj_lib_path = palloc(sizeof(char *));
path = palloc(MAXPGPATH);
*proj_lib_path = path;
}
-/* convert decimal degress to radians */
+/** convert decimal degress to radians */
void
to_rad(POINT4D *pt)
{
pt->y *= M_PI/180.0;
}
-/* convert radians to decimal degress */
+/** convert radians to decimal degress */
void
to_dec(POINT4D *pt)
{
pt->y *= 180.0/M_PI;
}
-/* given a string, make a PJ object */
-projPJ
+/** given a string, make a PJ object */
+projPJ
make_project(char *str1)
{
int t;
return result;
}
-/*
+/**
* Transform given SERIALIZED geometry
* from inpj projection to outpj projection
*/
-/*
+/**
* transform( GEOMETRY, INT (output srid) )
* tmpPts - if there is a nadgrid error (-38), we re-try the transform
* on a copy of points. The transformed points
if (fcinfo->flinfo->fn_extra == NULL)
{
MemoryContext old_context;
-
+
old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
- PROJ4Cache = palloc(sizeof(PROJ4PortalCache));
+ PROJ4Cache = palloc(sizeof(PROJ4PortalCache));
MemoryContextSwitchTo(old_context);
if (PROJ4Cache)
/* Add the input srid to the cache if it's not already there */
if (!IsInPROJ4SRSCache(PROJ4Cache, pglwgeom_getSRID(geom)))
AddToPROJ4SRSCache(PROJ4Cache, pglwgeom_getSRID(geom), result_srid);
-
+
/* Get the input projection */
input_pj = GetProjectionFromPROJ4SRSCache(PROJ4Cache, pglwgeom_getSRID(geom));
-
+
/* now we have a geometry, and input/output PJ structs. */
lwgeom_transform_recursive(SERIALIZED_FORM(geom),
input_pj, output_pj);
}
-/*
+/**
* Transform_geom( GEOMETRY, TEXT (input proj4), TEXT (output proj4),
* INT (output srid)
*
/* make input and output projection objects */
input_pj = make_project(input_proj4);
-
+
pj_errno_ref = pj_get_errno_ref();
- if ( (input_pj == NULL) || (*pj_errno_ref))
+ if ( (input_pj == NULL) || (*pj_errno_ref))
{
/* we need this for error reporting */
/* pfree(input_proj4); */
pfree(input_proj4);
output_pj = make_project(output_proj4);
-
+
pj_errno_ref = pj_get_errno_ref();
if ((output_pj == NULL)|| (*pj_errno_ref))
{
{
int* pj_errno_ref;
POINT4D orig_pt;
-
+
/* Make a copy of the input point so we can report the original should an error occur */
orig_pt.x = pt->x;
orig_pt.y = pt->y;
/* Perform the transform */
pj_transform(srcpj, dstpj, 1, 0, &(pt->x), &(pt->y), &(pt->z));
-
+
/* For NAD grid-shift errors, display an error message with an additional hint */
pj_errno_ref = pj_get_errno_ref();
{
if (*pj_errno_ref == -38)
{
- ereport(ERROR, (
+ ereport(ERROR, (
errmsg_internal("transform: couldn't project point (%g %g %g): %s (%d)",
orig_pt.x, orig_pt.y, orig_pt.z, pj_strerrno(*pj_errno_ref), *pj_errno_ref),
errhint("PostGIS was unable to transform the point because either no grid shift files were found, or the point does not lie within the range for which the grid shift is defined. Refer to the ST_Transform() section of the PostGIS manual for details on how to configure PostGIS to alter this behaviour.")
Datum cache_bbox(PG_FUNCTION_ARGS);
-/*
- * The intended use for this trigger function is making
- * a geometry field cache it's bbox. Use like this:
+/** @file
+ * The intended use for this trigger function is making
+ * a geometry field cache it's bbox. Use like this:
*
- * CREATE TRIGGER <name> BEFORE INSERT OR UPDATE
- * ON <table> FOR EACH ROW EXECUTE PROCEDURE
- * cache_bbox(<field>);
+ * CREATE TRIGGER <name> BEFORE INSERT OR UPDATE
+ * ON <table> FOR EACH ROW EXECUTE PROCEDURE
+ * cache_bbox(<field>);
*
*/
PG_FUNCTION_INFO_V1(cache_bbox);
tupdesc = trigdata->tg_relation->rd_att;
- /* Connect to SPI manager */
- if ((ret = SPI_connect()) < 0)
- elog(ERROR, "cache_bbox: SPI_connect returned %d", ret);
+ /* Connect to SPI manager */
+ if ((ret = SPI_connect()) < 0)
+ elog(ERROR, "cache_bbox: SPI_connect returned %d", ret);
/* Find number of requested argument */
attno = SPI_fnumber(tupdesc, trigger->tgargs[0]);
if ( attno == SPI_ERROR_NOATTRIBUTE )
- elog(ERROR, "trigger %s can't find attribute %s",
+ elog(ERROR, "trigger %s can't find attribute %s",
trigger->tgname, trigger->tgargs[0]);
/* Find number of requested argument */
if ( strcmp(SPI_gettype(tupdesc, attno), "geometry") )
- elog(ERROR, "trigger %s requested to apply to a non-geometry field (%s)", trigger->tgname, trigger->tgargs[0]);
-
+ elog(ERROR, "trigger %s requested to apply to a non-geometry field (%s)", trigger->tgname, trigger->tgargs[0]);
+
/* Get input lwgeom */
in = SPI_getbinval(rettuple, tupdesc, attno, &isnull);