[postgis-commits] svn - r2747 - in trunk: . lwgeom
postgis-commits at postgis.refractions.net
postgis-commits at postgis.refractions.net
Fri Mar 28 14:04:46 PDT 2008
Author: pramsey
Date: 2008-03-28 14:04:46 -0700 (Fri, 28 Mar 2008)
New Revision: 2747
Modified:
trunk/ChangeLog
trunk/lwgeom/lwgeom_kml.c
trunk/lwgeom/lwpostgis.sql.in
Log:
Added KML patch from Eduin Carillo.
http://code.google.com/p/postgis/issues/detail?id=17
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2008-03-28 20:18:49 UTC (rev 2746)
+++ trunk/ChangeLog 2008-03-28 21:04:46 UTC (rev 2747)
@@ -1,5 +1,12 @@
2008-03-28 Paul Ramsey <pramsey at cleverelephant.ca>
+ * lwgeom/lwgeom_kml.c, lwgeom/lwpostgis.sql.in
+ Added patch from Eduin Carillo to enhance KML
+ support.
+ http://code.google.com/p/postgis/issues/detail?id=17
+
+2008-03-28 Paul Ramsey <pramsey at cleverelephant.ca>
+
* doc/postgis.xml, lwgeom/lwgeom_svn.c,
Added patch from Marco Hugentobler to enhance SVG
support. 2008-February/002883.html
Modified: trunk/lwgeom/lwgeom_kml.c
===================================================================
--- trunk/lwgeom/lwgeom_kml.c 2008-03-28 20:18:49 UTC (rev 2746)
+++ trunk/lwgeom/lwgeom_kml.c 2008-03-28 21:04:46 UTC (rev 2747)
@@ -1,5 +1,5 @@
/**********************************************************************
- * $Id$
+ * $Id: $
*
* PostGIS - Spatial Types for PostgreSQL
* http://postgis.refractions.net
@@ -10,7 +10,7 @@
*
**********************************************************************
*
- * KML output routines based on lwgeom_gml.c
+ * KML output routines based on lwgeom_gml.c
* Written by: Eduin Carrillo <yecarrillo at cas.gov.co>
* © 2006 Corporacion Autonoma Regional de Santander - CAS
*
@@ -24,21 +24,21 @@
#include "liblwgeom.h"
Datum LWGEOM_asKML(PG_FUNCTION_ARGS);
-char *geometry_to_kml(uchar *srl, char *srs);
-static size_t askml_point_size(LWPOINT *point, char *srs);
-static char *askml_point(LWPOINT *point, char *srs);
-static size_t askml_line_size(LWLINE *line, char *srs);
-static char *askml_line(LWLINE *line, char *srs);
-static size_t askml_poly_size(LWPOLY *poly, char *srs);
-static char *askml_poly(LWPOLY *poly, char *srs);
-static size_t askml_inspected_size(LWGEOM_INSPECTED *geom, char *srs);
-static char *askml_inspected(LWGEOM_INSPECTED *geom, char *srs);
+char *geometry_to_kml2(uchar *srl);
+
+static size_t askml2_point_size(LWPOINT *point);
+static char *askml2_point(LWPOINT *point);
+static size_t askml2_line_size(LWLINE *line);
+static char *askml2_line(LWLINE *line);
+static size_t askml2_poly_size(LWPOLY *poly);
+static char *askml2_poly(LWPOLY *poly);
+static size_t askml2_inspected_size(LWGEOM_INSPECTED *geom);
+static char *askml2_inspected(LWGEOM_INSPECTED *geom);
+static size_t pointArray_toKML2(POINTARRAY *pa, char *buf);
+
static size_t pointArray_KMLsize(POINTARRAY *pa);
-static size_t pointArray_toKML(POINTARRAY *pa, char *buf);
-static char *getSRSbySRID(int SRID);
-#define DEF_PRECISION 15
/* Add dot, sign, exponent sign, 'e', exponent digits */
#define SHOW_DIGS (precision + 8)
@@ -56,51 +56,34 @@
char *kml;
text *result;
int len;
- int version = 2;
- char *srs;
- int SRID;
+ int version;
- precision = DEF_PRECISION;
- if ( PG_ARGISNULL(0) ) PG_RETURN_NULL();
-
- geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
-
- /* Get precision (if provided) */
- if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
- precision = PG_GETARG_INT32(1);
-
- if ( precision < 1 || precision > 15 )
+ /* Get the version */
+ version = PG_GETARG_INT32(0);
+ if ( version != 2)
{
- elog(ERROR, "Precision out of range 1..15");
+ elog(ERROR, "Only KML 2 is supported");
PG_RETURN_NULL();
}
- /* Get version (if provided) */
- if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
- version = PG_GETARG_INT32(2);
+ /* Get the geometry */
+ if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
+ geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-
- if ( version != 2 )
+ /* Get precision */
+ precision = PG_GETARG_INT32(2);
+ if ( precision < 1 || precision > 15 )
{
- elog(ERROR, "Only KML 2 is supported");
+ elog(ERROR, "Precision out of range 1..15");
PG_RETURN_NULL();
}
+
+ if (version == 2)
+ kml = geometry_to_kml2(SERIALIZED_FORM(geom));
+
+ PG_FREE_IF_COPY(geom, 1);
- SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
- if ( SRID != -1 ) {
- srs = getSRSbySRID(SRID);
- } else {
- PG_FREE_IF_COPY(geom, 0);
- elog(ERROR,"Input geometry has unknown (-1) SRID");
- PG_RETURN_NULL();
- }
-
- /*elog(NOTICE, "srs=%s", srs); */
-
- kml = geometry_to_kml(SERIALIZED_FORM(geom), srs);
- PG_FREE_IF_COPY(geom, 0);
-
len = strlen(kml) + VARHDRSZ;
result = palloc(len);
@@ -113,9 +96,15 @@
PG_RETURN_POINTER(result);
}
+
+
+/*
+ * VERSION KML 2
+ */
+
/* takes a GEOMETRY and returns a KML representation */
char *
-geometry_to_kml(uchar *geom, char *srs)
+geometry_to_kml2(uchar *geom)
{
int type;
LWPOINT *point;
@@ -130,21 +119,21 @@
case POINTTYPE:
point = lwpoint_deserialize(geom);
- return askml_point(point, srs);
+ return askml2_point(point);
case LINETYPE:
line = lwline_deserialize(geom);
- return askml_line(line, srs);
+ return askml2_line(line);
case POLYGONTYPE:
poly = lwpoly_deserialize(geom);
- return askml_poly(poly, srs);
+ return askml2_poly(poly);
case MULTIPOINTTYPE:
case MULTILINETYPE:
case MULTIPOLYGONTYPE:
inspected = lwgeom_inspect(geom);
- return askml_inspected(inspected, srs);
+ return askml2_inspected(inspected);
default:
lwerror("geometry_to_kml: '%s' geometry type not supported by Google Earth", lwgeom_typename(type));
@@ -153,7 +142,7 @@
}
static size_t
-askml_point_size(LWPOINT *point, char *srs)
+askml2_point_size(LWPOINT *point)
{
int size;
size = pointArray_KMLsize(point->point);
@@ -162,32 +151,32 @@
}
static size_t
-askml_point_buf(LWPOINT *point, char *srs, char *output)
+askml2_point_buf(LWPOINT *point, char *output)
{
char *ptr = output;
ptr += sprintf(ptr, "<Point>");
ptr += sprintf(ptr, "<coordinates>");
- ptr += pointArray_toKML(point->point, ptr);
+ ptr += pointArray_toKML2(point->point, ptr);
ptr += sprintf(ptr, "</coordinates></Point>");
return (ptr-output);
}
static char *
-askml_point(LWPOINT *point, char *srs)
+askml2_point(LWPOINT *point)
{
char *output;
int size;
- size = askml_point_size(point, srs);
+ size = askml2_point_size(point);
output = palloc(size);
- askml_point_buf(point, srs, output);
+ askml2_point_buf(point, output);
return output;
}
static size_t
-askml_line_size(LWLINE *line, char *srs)
+askml2_line_size(LWLINE *line)
{
int size;
size = pointArray_KMLsize(line->points);
@@ -196,32 +185,32 @@
}
static size_t
-askml_line_buf(LWLINE *line, char *srs, char *output)
+askml2_line_buf(LWLINE *line, char *output)
{
char *ptr=output;
ptr += sprintf(ptr, "<LineString>");
ptr += sprintf(ptr, "<coordinates>");
- ptr += pointArray_toKML(line->points, ptr);
+ ptr += pointArray_toKML2(line->points, ptr);
ptr += sprintf(ptr, "</coordinates></LineString>");
return (ptr-output);
}
static char *
-askml_line(LWLINE *line, char *srs)
+askml2_line(LWLINE *line)
{
char *output;
int size;
- size = askml_line_size(line, srs);
+ size = askml2_line_size(line);
output = palloc(size);
- askml_line_buf(line, srs, output);
+ askml2_line_buf(line, output);
return output;
}
static size_t
-askml_poly_size(LWPOLY *poly, char *srs)
+askml2_poly_size(LWPOLY *poly)
{
size_t size;
int i;
@@ -238,19 +227,19 @@
}
static size_t
-askml_poly_buf(LWPOLY *poly, char *srs, char *output)
+askml2_poly_buf(LWPOLY *poly, char *output)
{
int i;
char *ptr=output;
ptr += sprintf(ptr, "<Polygon>");
ptr += sprintf(ptr, "<outerBoundaryIs><LinearRing><coordinates>");
- ptr += pointArray_toKML(poly->rings[0], ptr);
+ ptr += pointArray_toKML2(poly->rings[0], ptr);
ptr += sprintf(ptr, "</coordinates></LinearRing></outerBoundaryIs>");
for (i=1; i<poly->nrings; i++)
{
ptr += sprintf(ptr, "<innerBoundaryIs><LinearRing><coordinates>");
- ptr += pointArray_toKML(poly->rings[i], ptr);
+ ptr += pointArray_toKML2(poly->rings[i], ptr);
ptr += sprintf(ptr, "</coordinates></LinearRing></innerBoundaryIs>");
}
ptr += sprintf(ptr, "</Polygon>");
@@ -259,14 +248,14 @@
}
static char *
-askml_poly(LWPOLY *poly, char *srs)
+askml2_poly(LWPOLY *poly)
{
char *output;
int size;
- size = askml_poly_size(poly, srs);
+ size = askml2_poly_size(poly);
output = palloc(size);
- askml_poly_buf(poly, srs, output);
+ askml2_poly_buf(poly, output);
return output;
}
@@ -276,7 +265,7 @@
* Don't call this with single-geoms inspected.
*/
static size_t
-askml_inspected_size(LWGEOM_INSPECTED *insp, char *srs)
+askml2_inspected_size(LWGEOM_INSPECTED *insp)
{
int i;
size_t size;
@@ -294,24 +283,24 @@
if ((point=lwgeom_getpoint_inspected(insp, i)))
{
- size += askml_point_size(point, 0);
+ size += askml2_point_size(point, 0);
pfree_point(point);
}
else if ((line=lwgeom_getline_inspected(insp, i)))
{
- size += askml_line_size(line, 0);
+ size += askml2_line_size(line, 0);
pfree_line(line);
}
else if ((poly=lwgeom_getpoly_inspected(insp, i)))
{
- size += askml_poly_size(poly, 0);
+ size += askml2_poly_size(poly, 0);
pfree_polygon(poly);
}
else
{
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
subinsp = lwgeom_inspect(subgeom);
- size += askml_inspected_size(subinsp, 0);
+ size += askml2_inspected_size(subinsp, 0);
pfree_inspected(subinsp);
}
}
@@ -323,7 +312,7 @@
* Don't call this with single-geoms inspected!
*/
static size_t
-askml_inspected_buf(LWGEOM_INSPECTED *insp, char *srs, char *output)
+askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output)
{
char *ptr, *kmltype;
int i;
@@ -331,6 +320,7 @@
ptr = output;
kmltype = "MultiGeometry";
+ /* Open outmost tag */
ptr += sprintf(ptr, "<%s>", kmltype);
for (i=0; i<insp->ngeometries; i++)
@@ -343,24 +333,24 @@
if ((point=lwgeom_getpoint_inspected(insp, i)))
{
- ptr += askml_point_buf(point, 0, ptr);
+ ptr += askml2_point_buf(point, 0, ptr);
pfree_point(point);
}
else if ((line=lwgeom_getline_inspected(insp, i)))
{
- ptr += askml_line_buf(line, 0, ptr);
+ ptr += askml2_line_buf(line, 0, ptr);
pfree_line(line);
}
else if ((poly=lwgeom_getpoly_inspected(insp, i)))
{
- ptr += askml_poly_buf(poly, 0, ptr);
+ ptr += askml2_poly_buf(poly, 0, ptr);
pfree_polygon(poly);
}
else
{
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
subinsp = lwgeom_inspect(subgeom);
- ptr += askml_inspected_buf(subinsp, 0, ptr);
+ ptr += askml2_inspected_buf(subinsp, 0, ptr);
pfree_inspected(subinsp);
}
}
@@ -375,29 +365,20 @@
* Don't call this with single-geoms inspected!
*/
static char *
-askml_inspected(LWGEOM_INSPECTED *insp, char *srs)
+askml2_inspected(LWGEOM_INSPECTED *insp)
{
char *kml;
size_t size;
- size = askml_inspected_size(insp, srs);
+ size = askml2_inspected_size(insp);
kml = palloc(size);
- askml_inspected_buf(insp, srs, kml);
+ askml2_inspected_buf(insp, kml);
return kml;
}
-/*
- * Returns maximum size of rendered pointarray in bytes.
- */
static size_t
-pointArray_KMLsize(POINTARRAY *pa)
+pointArray_toKML2(POINTARRAY *pa, char *output)
{
- return TYPE_NDIMS(pa->dims) * pa->npoints * (SHOW_DIGS+(TYPE_NDIMS(pa->dims)-1));
-}
-
-static size_t
-pointArray_toKML(POINTARRAY *pa, char *output)
-{
int i;
char *ptr;
@@ -410,7 +391,7 @@
POINT2D pt;
getPoint2d_p(pa, i, &pt);
if ( i ) ptr += sprintf(ptr, " ");
- ptr += sprintf(ptr, "%.*g,%.*g,0",
+ ptr += sprintf(ptr, "%.*g,%.*g",
precision, pt.x,
precision, pt.y);
}
@@ -432,65 +413,22 @@
return ptr-output;
}
-static char *
-getSRSbySRID(int SRID)
-{
- char query[128];
- char *srs, *srscopy;
- int size, err;
- /* connect to SPI */
- if (SPI_OK_CONNECT != SPI_connect ()) {
- elog(NOTICE, "getSRSbySRID: could not connect to SPI manager");
- SPI_finish();
- return NULL;
- }
- /* write query */
- sprintf(query, "SELECT textcat(auth_name, textcat(':', auth_srid::text)) \
- FROM spatial_ref_sys WHERE srid = '%d'", SRID);
-#ifdef PGIS_DEBUG
- elog(NOTICE, "Query: %s", query);
-#endif
+/*
+ * Common KML routines
+ */
- /* execute query */
- err = SPI_exec(query, 1);
- if ( err < 0 ) {
- elog(NOTICE, "getSRSbySRID: error executing query %d", err);
- SPI_finish();
- return NULL;
- }
-
- /* no entry in spatial_ref_sys */
- if (SPI_processed <= 0) {
- /*elog(NOTICE, "getSRSbySRID: no record for SRID %d", SRID); */
- SPI_finish();
- return NULL;
- }
-
- /* get result */
- srs = SPI_getvalue(SPI_tuptable->vals[0],
- SPI_tuptable->tupdesc, 1);
-
- /* NULL result */
- if ( ! srs ) {
- /*elog(NOTICE, "getSRSbySRID: null result"); */
- SPI_finish();
- return NULL;
- }
-
- /* copy result to upper executor context */
- size = strlen(srs)+1;
- srscopy = SPI_palloc(size);
- memcpy(srscopy, srs, size);
-
- /* disconnect from SPI */
- SPI_finish();
-
- return srscopy;
+/*
+ * Returns maximum size of rendered pointarray in bytes.
+ */
+static size_t
+pointArray_KMLsize(POINTARRAY *pa)
+{
+ return TYPE_NDIMS(pa->dims) * pa->npoints * (SHOW_DIGS+(TYPE_NDIMS(pa->dims)-1));
}
/**********************************************************************
- * $Log$
+ * $Log: $
**********************************************************************/
Modified: trunk/lwgeom/lwpostgis.sql.in
===================================================================
--- trunk/lwgeom/lwpostgis.sql.in 2008-03-28 20:18:49 UTC (rev 2746)
+++ trunk/lwgeom/lwpostgis.sql.in 2008-03-28 21:04:46 UTC (rev 2747)
@@ -4801,83 +4801,53 @@
-----------------------------------------------------------------------
-- KML OUTPUT
-----------------------------------------------------------------------
--- AsUKML(geom, precision, version)
--- Deprecation in 1.2.3
-CREATEFUNCTION AsUKML(geometry, int4, int4)
+-- _ST_AsKML(version, geom, precision)
+CREATEFUNCTION _ST_AsKML(int4, geometry, int4)
RETURNS TEXT
AS '@MODULE_FILENAME@','LWGEOM_asKML'
LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
--- Availability: 1.2.2
-CREATEFUNCTION ST_AsUKML(geometry, int4, int4)
- RETURNS TEXT
- AS '@MODULE_FILENAME@','LWGEOM_asKML'
- LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
-
--- AsUKML(geom, precision) / version=2
+#ifdef USE_PROJ
+-- AsKML(geom, precision) / version=2
-- Deprecation in 1.2.3
-CREATEFUNCTION AsUKML(geometry, int4)
+CREATEFUNCTION AsKML(geometry, int4)
RETURNS TEXT
- AS '@MODULE_FILENAME@','LWGEOM_asKML'
- LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
-
--- Availability: 1.2.2
-CREATEFUNCTION ST_AsUKML(geometry, int4)
- RETURNS TEXT
- AS '@MODULE_FILENAME@','LWGEOM_asKML'
- LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
-
--- AsUKML(geom) / precision=15 version=2
--- Deprecation in 1.2.3
-CREATEFUNCTION AsUKML(geometry)
- RETURNS TEXT
- AS '@MODULE_FILENAME@','LWGEOM_asKML'
- LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
-
--- Availability: 1.2.2
-CREATEFUNCTION ST_AsUKML(geometry)
- RETURNS TEXT
- AS '@MODULE_FILENAME@','LWGEOM_asKML'
- LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
-
--- AsKML(geom, precision, version)
--- Deprecation in 1.2.3
-CREATE OR REPLACE FUNCTION AsKML(geometry, int4, int4)
- RETURNS TEXT
- AS 'SELECT AsUKML(transform($1,4326),$2,$3)'
+ AS 'SELECT _ST_AsKML(2, transform($1,4326), $2)'
LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
-- Availability: 1.2.2
-CREATE OR REPLACE FUNCTION ST_AsKML(geometry, int4, int4)
+CREATEFUNCTION ST_AsKML(geometry, int4)
RETURNS TEXT
- AS 'SELECT AsUKML(transform($1,4326),$2,$3)'
+ AS 'SELECT _ST_AsKML(2, transform($1,4326), $2)'
LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
--- AsKML(geom, precision) / version=2
+-- AsKML(geom) / precision=15 version=2
-- Deprecation in 1.2.3
-CREATE OR REPLACE FUNCTION AsKML(geometry, int4)
+CREATEFUNCTION AsKML(geometry)
RETURNS TEXT
- AS 'SELECT AsUKML(transform($1,4326),$2)'
+ AS 'SELECT _ST_AsKML(2, transform($1,4326), 15)'
LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
--- Availability: 1.2.2
-CREATE OR REPLACE FUNCTION ST_AsKML(geometry, int4)
+-- Availabiltiy: 1.2.2
+CREATEFUNCTION ST_AsKML(geometry)
RETURNS TEXT
- AS 'SELECT AsUKML(transform($1,4326),$2)'
+ AS 'SELECT _ST_AsKML(2, transform($1,4326), 15)'
LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
--- AsKML(geom) / precision=15 version=2
--- Deprecation in 1.2.3
-CREATE OR REPLACE FUNCTION AsKML(geometry)
+-- ST_AsKML(version, geom) / precision=15 version=2
+-- Availabiltiy: 1.3.2
+CREATEFUNCTION ST_AsKML(int4, geometry)
RETURNS TEXT
- AS 'SELECT AsUKML(transform($1,4326))'
+ AS 'SELECT _ST_AsKML($1, transform($2,4326), 15)'
LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
--- Availability: 1.2.2
-CREATE OR REPLACE FUNCTION ST_AsKML(geometry)
+-- ST_AsKML(version, geom, precision)
+-- Availabiltiy: 1.3.2
+CREATEFUNCTION ST_AsKML(int4, geometry, int4)
RETURNS TEXT
- AS 'SELECT AsUKML(transform($1,4326))'
+ AS 'SELECT _ST_AsKML($1, transform($2,4326), $3)'
LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
+#endif
------------------------------------------------------------------------
-- OGC defined
More information about the postgis-commits
mailing list