]> granicus.if.org Git - postgis/commitdiff
Initial GML output routines.
authorSandro Santilli <strk@keybit.net>
Thu, 23 Sep 2004 11:12:47 +0000 (11:12 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 23 Sep 2004 11:12:47 +0000 (11:12 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@887 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/Makefile
lwgeom/lwgeom_gml.c [new file with mode: 0644]
lwgeom/lwpostgis.sql.in

index 84a505478cfb698c281cae940cfaf9c7ee2fcde6..7f1a0c9342c8fbcf71344a862c5f395ca009b848 100644 (file)
@@ -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 (file)
index 0000000..ab20d35
--- /dev/null
@@ -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("<!-- MULTI geoms not yet supported -->");
+       }
+
+       inspected = lwgeom_inspect(SERIALIZED_FORM(geometry));
+       for(i=0; i<inspected->ngeometries; 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("<point><coordinates>/") * 2;
+
+       output = palloc(size);
+       ptr = output;
+
+       ptr += sprintf(ptr, "<Point><coordinates>");
+       ptr += pointArray_toGML(point->point, version, ptr);
+       ptr += sprintf(ptr, "</coordinates></Point>");
+
+       return output;
+}
+
+static char *
+asgml_line(LWLINE *line, int version)
+{
+       char *output;
+       int size;
+       char *ptr;
+       
+       size = pointArray_GMLsize(line->points, version);
+       size += sizeof("<linestring><coordinates>/") * 2;
+
+       output = palloc(size);
+       ptr = output;
+
+       ptr += sprintf(ptr, "<LineString><coordinates>");
+       ptr += pointArray_toGML(line->points, version, ptr);
+       ptr += sprintf(ptr, "</coordinates></LineString>");
+
+       return output;
+}
+
+static char *
+asgml_poly(LWPOLY *poly, int version)
+{
+       char *output;
+       int size;
+       int i;
+       char *ptr;
+
+       size = sizeof("<polygon></outerboundaryis></linearring>") * 2;
+       size += sizeof("<innerboundaryis><linearring>/") * 2 * poly->nrings;
+
+       for (i=0; i<poly->nrings; i++)
+               size += pointArray_GMLsize(poly->rings[i], version);
+       
+       output = palloc(size);
+       ptr = output;
+
+       ptr += sprintf(ptr, "<Polygon>");
+       ptr += sprintf(ptr, "<OuterBoundaryIs>");
+       ptr += pointArray_toGML(poly->rings[0], version, ptr);
+       ptr += sprintf(ptr, "</OuterBoundaryIs>");
+       for (i=1; i<poly->nrings; i++)
+       {
+               ptr += sprintf(ptr, "<InnerBoundaryIs>");
+               ptr += pointArray_toGML(poly->rings[i], version, ptr);
+               ptr += sprintf(ptr, "</InnerBoundaryIs>");
+       }
+       ptr += sprintf(ptr, "</Polygon>");
+
+       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; i<pa->npoints; 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; i<pa->npoints; 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; i<pa->npoints; 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.
+ *
+ **********************************************************************/
+
index 6baf14407e0b55039134a12afe7eac0b836b4165..04303a1aac55c3337992d6781faff1349766bc9c 100644 (file)
@@ -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