From 3d09c5e1d51cbca263c780842270727721ec3f09 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Thu, 23 Sep 2004 11:12:47 +0000 Subject: [PATCH] Initial GML output routines. git-svn-id: http://svn.osgeo.org/postgis/trunk@887 b70326c6-7e19-0410-871a-916f4a2858ee --- lwgeom/Makefile | 2 +- lwgeom/lwgeom_gml.c | 235 ++++++++++++++++++++++++++++++++++++++++ lwgeom/lwpostgis.sql.in | 18 ++- 3 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 lwgeom/lwgeom_gml.c diff --git a/lwgeom/Makefile b/lwgeom/Makefile index 84a505478..7f1a0c934 100644 --- a/lwgeom/Makefile +++ b/lwgeom/Makefile @@ -66,7 +66,7 @@ ifeq ($(USE_STATS),1) override CFLAGS += -DUSE_STATS endif -OBJS=lwgeom_pg.o lwgeom_spheroid.o lwgeom_api.o lwgeom_ogc.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box3d.o lwgeom_box2dfloat4.o lwgeom_chip.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o lwgeom_svg.o $(GEOS_WRAPPER) +OBJS=lwgeom_pg.o lwgeom_spheroid.o lwgeom_api.o lwgeom_ogc.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box3d.o lwgeom_box2dfloat4.o lwgeom_chip.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o lwgeom_svg.o lwgeom_gml.o $(GEOS_WRAPPER) OTHERS=y.output lex.yy.c wktparse.tab.c wktparse.tab.h lwpostgis.sql diff --git a/lwgeom/lwgeom_gml.c b/lwgeom/lwgeom_gml.c new file mode 100644 index 000000000..ab20d3591 --- /dev/null +++ b/lwgeom/lwgeom_gml.c @@ -0,0 +1,235 @@ +/********************************************************************** + * $Id$ + * + * PostGIS - Spatial Types for PostgreSQL + * http://postgis.refractions.net + * Copyright 2001-2003 Refractions Research Inc. + * + * 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. + * + **********************************************************************/ + + +#include "postgres.h" +#include "lwgeom.h" + +Datum LWGEOM_asGML(PG_FUNCTION_ARGS); +char *geometry_to_gml(LWGEOM *geometry, int version); +static char *asgml_point(LWPOINT *point, int version); +static char *asgml_line(LWLINE *line, int version); +static char *asgml_poly(LWPOLY *poly, int version); +static size_t pointArray_GMLsize(POINTARRAY *pa, int version); +static size_t pointArray_toGML(POINTARRAY *pa, int version, char *buf); + +#define SHOW_DIGS_DOUBLE 15 +#define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 +1) + +/** + * Encode feature in GML + */ +PG_FUNCTION_INFO_V1(LWGEOM_asGML); +Datum LWGEOM_asGML(PG_FUNCTION_ARGS) +{ + LWGEOM *geom; + char *gml; + char *result; + int len; + int version=0; + + if ( PG_ARGISNULL(0) ) PG_RETURN_NULL(); + + geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + + // check for relative path notation + if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) ) + version = PG_GETARG_INT32(1); + + gml = geometry_to_gml(geom, version); + + len = strlen(gml) + 5; + + result= palloc(len); + *((int *) result) = len; + + memcpy(result +4, gml, len-4); + + pfree(gml); + PG_FREE_IF_COPY(geom, 0); + + PG_RETURN_CSTRING(result); +} + + +// takes a GEOMETRY and returns a GML representation +char *geometry_to_gml(LWGEOM *geometry, int version) +{ + char *result = NULL; + LWGEOM_INSPECTED *inspected; + int i; + + if (lwgeom_getType(geometry->type) >= 4 ) + { + return pstrdup(""); + } + + inspected = lwgeom_inspect(SERIALIZED_FORM(geometry)); + for(i=0; ingeometries; i++) + { + char *subgeom = lwgeom_getsubgeometry_inspected(inspected, i); + LWPOINT *point; + LWLINE *line; + LWPOLY *poly; + + if (lwgeom_getType(subgeom[0]) == POINTTYPE) + { + point = lwpoint_deserialize(subgeom); + return asgml_point(point, version); + } + if (lwgeom_getType(subgeom[0]) == LINETYPE) + { + line = lwline_deserialize(subgeom); + return asgml_line(line, version); + } + if (lwgeom_getType(subgeom[0]) == POLYGONTYPE) + { + poly = lwpoly_deserialize(subgeom); + return asgml_poly(poly, version); + } + } + return(result); +} + +static char * +asgml_point(LWPOINT *point, int version) +{ + char *output; + int size; + char *ptr; + + size = pointArray_GMLsize(point->point, version); + size += sizeof("/") * 2; + + output = palloc(size); + ptr = output; + + ptr += sprintf(ptr, ""); + ptr += pointArray_toGML(point->point, version, ptr); + ptr += sprintf(ptr, ""); + + return output; +} + +static char * +asgml_line(LWLINE *line, int version) +{ + char *output; + int size; + char *ptr; + + size = pointArray_GMLsize(line->points, version); + size += sizeof("/") * 2; + + output = palloc(size); + ptr = output; + + ptr += sprintf(ptr, ""); + ptr += pointArray_toGML(line->points, version, ptr); + ptr += sprintf(ptr, ""); + + return output; +} + +static char * +asgml_poly(LWPOLY *poly, int version) +{ + char *output; + int size; + int i; + char *ptr; + + size = sizeof("") * 2; + size += sizeof("/") * 2 * poly->nrings; + + for (i=0; inrings; i++) + size += pointArray_GMLsize(poly->rings[i], version); + + output = palloc(size); + ptr = output; + + ptr += sprintf(ptr, ""); + ptr += sprintf(ptr, ""); + ptr += pointArray_toGML(poly->rings[0], version, ptr); + ptr += sprintf(ptr, ""); + for (i=1; inrings; i++) + { + ptr += sprintf(ptr, ""); + ptr += pointArray_toGML(poly->rings[i], version, ptr); + ptr += sprintf(ptr, ""); + } + ptr += sprintf(ptr, ""); + + return output; +} + +static size_t +pointArray_GMLsize(POINTARRAY *pa, int version) +{ + return pa->ndims * (MAX_DIGS_DOUBLE+(pa->ndims-1)); +} + +static size_t +pointArray_toGML(POINTARRAY *pa, int version, char *output) +{ + int i; + POINT4D *pt; + char *ptr; + + ptr = output; + + if ( pa->ndims == 2 ) + { + for (i=0; inpoints; i++) + { + pt = (POINT4D *)getPoint(pa, i); + if ( i ) ptr += sprintf(ptr, " "); + ptr += sprintf(ptr, "%g,%g", + pt->x, pt->y); + } + } + else if ( pa->ndims == 3 ) + { + for (i=0; inpoints; i++) + { + pt = (POINT4D *)getPoint(pa, i); + if ( i ) ptr += sprintf(ptr, " "); + ptr += sprintf(ptr, "%g,%g,%g", + pt->x, pt->y, pt->z); + } + } + else if ( pa->ndims == 4 ) + { + for (i=0; inpoints; i++) + { + pt = (POINT4D *)getPoint(pa, i); + if ( i ) ptr += sprintf(ptr, " "); + ptr += sprintf(ptr, "%g,%g,%g,%g", + pt->x, pt->y, pt->z, pt->m); + } + } + + return ptr-output; +} + + +/********************************************************************** + * $Log$ + * Revision 1.1 2004/09/23 11:12:47 strk + * Initial GML output routines. + * + **********************************************************************/ + diff --git a/lwgeom/lwpostgis.sql.in b/lwgeom/lwpostgis.sql.in index 6baf14407..04303a1aa 100644 --- a/lwgeom/lwpostgis.sql.in +++ b/lwgeom/lwpostgis.sql.in @@ -2907,21 +2907,33 @@ CREATEFUNCTION Equals(geometry,geometry) ----------------------------------------------------------------------- -- SVG OUTPUT ----------------------------------------------------------------------- -CREATEFUNCTION AsSvg(geometry,int4,int4) +CREATEFUNCTION AsSVG(geometry,int4,int4) RETURNS TEXT AS '@MODULE_FILENAME@','assvg_geometry' LANGUAGE 'C'; -CREATEFUNCTION AsSvg(geometry,int4) +CREATEFUNCTION AsSVG(geometry,int4) RETURNS TEXT AS '@MODULE_FILENAME@','assvg_geometry' LANGUAGE 'C'; -CREATEFUNCTION AsSvg(geometry) +CREATEFUNCTION AsSVG(geometry) RETURNS TEXT AS '@MODULE_FILENAME@','assvg_geometry' LANGUAGE 'C'; +----------------------------------------------------------------------- +-- GML OUTPUT +----------------------------------------------------------------------- +CREATEFUNCTION AsGML(geometry, int4) + RETURNS TEXT + AS '@MODULE_FILENAME@','LWGEOM_asGML' + LANGUAGE 'C'; + +CREATEFUNCTION AsGML(geometry) + RETURNS TEXT + AS '@MODULE_FILENAME@','LWGEOM_asGML' + LANGUAGE 'C'; --------------------------------------------------------------- -- END -- 2.40.0