[postgis-commits] svn - r3835 - in trunk: doc postgis

postgis-commits at postgis.refractions.net postgis-commits at postgis.refractions.net
Tue Mar 10 11:20:21 PDT 2009


Author: colivier
Date: 2009-03-10 11:20:20 -0700 (Tue, 10 Mar 2009)
New Revision: 3835

Modified:
   trunk/doc/reference_new.xml
   trunk/postgis/lwgeom_geojson.c
   trunk/postgis/lwgeom_gml.c
   trunk/postgis/postgis.sql.in.c
Log:
Fix GeoJson CRS output format (1.0 spec). Add OGC long CRS format (Cf RFC 5165) as an option. On AsGeoJson it change option order from 1.3.X between Bbox and CRS. On AsGML a new option parameter is added

Modified: trunk/doc/reference_new.xml
===================================================================
--- trunk/doc/reference_new.xml	2009-03-10 18:01:23 UTC (rev 3834)
+++ trunk/doc/reference_new.xml	2009-03-10 18:20:20 UTC (rev 3835)
@@ -7268,19 +7268,17 @@
 				</listitem>
 
 				<listitem>
-				  <para>1: GeoJSON CRS</para>
+				  <para>1: GeoJSON Bbox</para>
 				</listitem>
 
 				<listitem>
-				  <para>2: GeoJSON Bbox</para>
+				  <para>2: GeoJSON Short CRS (e.g EPSG:4326)</para>
 				</listitem>
 
 				<listitem>
-				  <para>3: Both GeoJSON Bbox and CRS</para>
+				  <para>4: GeoJSON Long CRS (e.g urn:ogc:def:crs:EPSG:4326)</para>
 				</listitem>
 			  </itemizedlist>
-			GeoJson CRS pattern is: <literal>auth_name:auth_srid</literal>
-			from spatial_ref_sys table (EPSG:4326 for instance).
 			</para>
 			<para>Version 1: ST_AsGeoJSON(geom) / precision=15 version=1 options=0</para>
 			<para>Version 2: ST_AsGeoJSON(geom, precision) / version=1 options=0</para>
@@ -7343,12 +7341,19 @@
 				<funcdef>text <function>ST_AsGML</function></funcdef>
 				<paramdef><type>integer </type> <parameter>version</parameter></paramdef>
 				<paramdef><type>geometry </type> <parameter>g1</parameter></paramdef>
+			</funcprototype>
+			<funcprototype>
+				<funcdef>text <function>ST_AsGML</function></funcdef>
+				<paramdef><type>integer </type> <parameter>version</parameter></paramdef>
+				<paramdef><type>geometry </type> <parameter>g1</parameter></paramdef>
 				<paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
 			</funcprototype>
 			<funcprototype>
 				<funcdef>text <function>ST_AsGML</function></funcdef>
 				<paramdef><type>integer </type> <parameter>version</parameter></paramdef>
 				<paramdef><type>geometry </type> <parameter>g1</parameter></paramdef>
+				<paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
+				<paramdef><type>integer </type> <parameter>options</parameter></paramdef>
 			</funcprototype>
 		</funcsynopsis>
 	  </refsynopsisdiv>
@@ -7361,7 +7366,20 @@
 			specified then the default is assumed to be 2. The third argument
 			may be used to reduce the maximum number of decimal places
 			used in output (defaults to 15).</para>
+		<para>GML 2 refer to 2.1.2 version, GML 3 to 3.1.1 version</para>
+                <para>The last 'options' argument could be used to define Crs output type
+                        in GML output:
+                          <itemizedlist>
+                                <listitem>
+                                  <para>1: GML Short CRS (e.g EPSG:4326), default value</para>
+                                </listitem>
 
+                                <listitem>
+                                  <para>2: GML Long CRS (e.g urn:ogc:def:crs:EPSG:4326)</para>
+                                </listitem>
+                          </itemizedlist>
+                        </para>
+
 		<!-- TODO: Itemize defaults for each function -->
 
 		<note>
@@ -7494,7 +7512,7 @@
 		<para>Version 1: ST_AsKML(geom) / version=2 precision=15</para>
 		<para>Version 2: ST_AsKML(geom, max_sig_digits) / version=2 </para>
 		<para>Version 3: ST_AsKML(version, geom) / precision=15 </para>
-		<para>Version 4: ST_AsGeoJSON(version, geom, precision) </para>
+		<para>Version 4: ST_AsKML(version, geom, precision) </para>
 
 		<note>
 		  <para>Requires PostGIS be compiled with Proj support.  Use <xref linkend="PostGIS_Full_Version" /> to confirm you have proj support compiled in.</para>

Modified: trunk/postgis/lwgeom_geojson.c
===================================================================
--- trunk/postgis/lwgeom_geojson.c	2009-03-10 18:01:23 UTC (rev 3834)
+++ trunk/postgis/lwgeom_geojson.c	2009-03-10 18:20:20 UTC (rev 3835)
@@ -37,7 +37,7 @@
 
 static size_t pointArray_to_geojson(POINTARRAY *pa, char *buf, int precision);
 static size_t pointArray_geojson_size(POINTARRAY *pa, int precision);
-static char *getSRSbySRID(int SRID);
+static char *getSRSbySRID(int SRID, bool short_crs);
 
 #define SHOW_DIGS_DOUBLE 15
 #define MAX_DOUBLE_PRECISION 15
@@ -82,17 +82,18 @@
 
 	/* Retrieve output option 
 	 * 0 = without option (default)
-	 * 1 = crs 
-	 * 2 = bbox
-	 * 3 = crs & bbox
+	 * 1 = bbox
+	 * 2 = short crs
+	 * 4 = long crs
 	 */
      	if (PG_NARGS() >3 && !PG_ARGISNULL(3)) 
                 option = PG_GETARG_INT32(3);
 
-	if (option & 1) {
+	if (option & 2 || option & 4) {
  		SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
         	if ( SRID != -1 ) {
-			srs = getSRSbySRID(SRID);
+			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();
@@ -100,7 +101,7 @@
 		}
 	}
 
-	if (option & 2) has_bbox = 1;
+	if (option & 1) has_bbox = 1;
 	
 	geojson = geometry_to_geojson(SERIALIZED_FORM(geom), srs, has_bbox, precision);
 	PG_FREE_IF_COPY(geom, 1);
@@ -134,9 +135,7 @@
 
 	type = lwgeom_getType(geom[0]);
 
-	if (has_bbox) {
-		bbox = compute_serialized_box3d(geom);
-	}
+	if (has_bbox) bbox = compute_serialized_box3d(geom);
 
 	switch (type)
 	{
@@ -194,39 +193,20 @@
 asgeojson_srs_size(char *srs) {
 	int size;
 
-	size = sizeof("'crs':{'type':'',");
-	size += sizeof("'properties':{'code':}");
-	size += strlen(srs) * sizeof(char) * 2; /* a bit more than really needed
-						   but avoid to search : separator */
+	size = sizeof("'crs':{'type':'name',");
+	size += sizeof("'properties':{'name':''}},");
+	size += strlen(srs) * sizeof(char);
+
 	return size;
 }
 
 static size_t
 asgeojson_srs_buf(char *output, char *srs) {
-	char *ptr_sep;
-	char buf[256+1];
 	char *ptr = output;
-	int size;
 
-	ptr_sep = strchr(srs, ':');
-	if ( ptr_sep == NULL ) {
-		lwerror("GeoJson: SRS dont't use a valid ':' separator !");
-		return (ptr-output);
-	}
+	ptr += sprintf(ptr, "\"crs\":{\"type\":\"name\",");
+	ptr += sprintf(ptr, "\"properties\":{\"name\":\"%s\"}},", srs);
 
-	size = ptr_sep - srs;
-	if (size > 256) size = 256;
-	memcpy(buf, srs, size);
-	buf[size] = '\0';
-	ptr += sprintf(ptr, "\"crs\":{\"type\":\"%s\",", buf);
-	ptr += sprintf(ptr, "\"properties\":{\"%s\":", buf);
-
-	size = srs + strlen(srs) - ptr_sep;
-	if (size > 256) size = 256;
-	memcpy(buf, ptr_sep + 1, size);
-	buf[size] = '\0';
-	ptr += sprintf(ptr, "%s}},", buf);
-
 	return (ptr-output);
 }
 
@@ -860,24 +840,25 @@
  */
 
 static char *
-getSRSbySRID(int SRID)
+getSRSbySRID(int SRID, bool short_crs)
 {
-	char query[128];
+	char query[256];
 	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);
-
-	/* execute query */
+	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);
+		
 	err = SPI_exec(query, 1);
 	if ( err < 0 ) {
 		elog(NOTICE, "getSRSbySRID: error executing query %d", err);
@@ -896,7 +877,6 @@
 	
 	/* NULL result */
 	if ( ! srs ) {
-		/*elog(NOTICE, "getSRSbySRID: null result"); */
 		SPI_finish();
 		return NULL;
 	}

Modified: trunk/postgis/lwgeom_gml.c
===================================================================
--- trunk/postgis/lwgeom_gml.c	2009-03-10 18:01:23 UTC (rev 3834)
+++ trunk/postgis/lwgeom_gml.c	2009-03-10 18:20:20 UTC (rev 3835)
@@ -48,8 +48,9 @@
 static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision);
 
 static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
-static char *getSRSbySRID(int SRID);
+static char *getSRSbySRID(int SRID, bool short_crs);
 
+
 /* Add dot, sign, exponent sign, 'e', exponent digits */
 #define SHOW_DIGS_DOUBLE 15
 #define MAX_DOUBLE_PRECISION 15
@@ -70,17 +71,18 @@
 	char *srs;
 	int SRID;
 	int precision = MAX_DOUBLE_PRECISION;
+	int option=0;
 
 
-    /* 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));
 
@@ -92,12 +94,15 @@
 		else if ( precision < 0 ) precision = 0;
         }
 
+	/* retrieve option */
+	if (PG_NARGS() >3 && !PG_ARGISNULL(3))
+                option = PG_GETARG_INT32(3);
+
 	SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
-	if ( SRID != -1 ) srs = getSRSbySRID(SRID);
-	else srs = NULL;
+	if (SRID == -1) srs = NULL;
+	else if (option & 1) srs = getSRSbySRID(SRID, false);
+	else srs = getSRSbySRID(SRID, true);
 
-	/*elog(NOTICE, "srs=%s", srs); */
-
 	if (version == 2)
 	  gml = geometry_to_gml2(SERIALIZED_FORM(geom), srs, precision);
 	else
@@ -849,7 +854,7 @@
  */
 
 static char *
-getSRSbySRID(int SRID)
+getSRSbySRID(int SRID, bool short_crs)
 {
 	char query[128];
 	char *srs, *srscopy;
@@ -862,12 +867,13 @@
 		return NULL;
 	}
 
-	/* write query */
-	sprintf(query, "SELECT textcat(auth_name, textcat(':', auth_srid::text)) \
-		FROM spatial_ref_sys WHERE srid = '%d'", SRID);
+	 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);
 
-	POSTGIS_DEBUGF(3, "Query: %s", query);
-
 	/* execute query */
 	err = SPI_exec(query, 1);
 	if ( err < 0 ) {

Modified: trunk/postgis/postgis.sql.in.c
===================================================================
--- trunk/postgis/postgis.sql.in.c	2009-03-10 18:01:23 UTC (rev 3834)
+++ trunk/postgis/postgis.sql.in.c	2009-03-10 18:20:20 UTC (rev 3835)
@@ -4541,8 +4541,8 @@
 -----------------------------------------------------------------------
 -- GML OUTPUT
 -----------------------------------------------------------------------
--- _ST_AsGML(version, geom, precision)
-CREATEFUNCTION _ST_AsGML(int4, geometry, int4)
+-- _ST_AsGML(version, geom, precision, option)
+CREATEFUNCTION _ST_AsGML(int4, geometry, int4, int4)
 	RETURNS TEXT
 	AS 'MODULE_PATHNAME','LWGEOM_asGML'
 	LANGUAGE 'C' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
@@ -4551,42 +4551,56 @@
 -- Deprecation in 1.2.3
 CREATEFUNCTION AsGML(geometry, int4)
 	RETURNS TEXT
-	AS 'SELECT _ST_AsGML(2, $1, $2)'
+	AS 'SELECT _ST_AsGML(2, $1, $2, 0)'
 	LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
 
 -- Availability: 1.2.2
 CREATEFUNCTION ST_AsGML(geometry, int4)
 	RETURNS TEXT
-	AS 'SELECT _ST_AsGML(2, $1, $2)'
+	AS 'SELECT _ST_AsGML(2, $1, $2, 0)'
 	LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
 
 -- AsGML(geom) / precision=15 version=2
 -- Deprecation in 1.2.3
 CREATEFUNCTION AsGML(geometry)
 	RETURNS TEXT
-	AS 'SELECT _ST_AsGML(2, $1, 15)'
+	AS 'SELECT _ST_AsGML(2, $1, 15, 0)'
 	LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
 
 -- Availability: 1.2.2
 CREATEFUNCTION ST_AsGML(geometry)
 	RETURNS TEXT
-	AS 'SELECT _ST_AsGML(2, $1, 15)'
+	AS 'SELECT _ST_AsGML(2, $1, 15, 0)'
 	LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
 
 -- ST_AsGML(version, geom) / precision=15 version=2
 -- Availability: 1.3.2
 CREATEFUNCTION ST_AsGML(int4, geometry)
 	RETURNS TEXT
-	AS 'SELECT _ST_AsGML($1, $2, 15)'
+	AS 'SELECT _ST_AsGML($1, $2, 15, 0)'
 	LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
 
 -- ST_AsGML(version, geom, precision)
 -- Availability: 1.3.2
 CREATEFUNCTION ST_AsGML(int4, geometry, int4)
 	RETURNS TEXT
-	AS 'SELECT _ST_AsGML($1, $2, $3)'
+	AS 'SELECT _ST_AsGML($1, $2, $3, 0)'
 	LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
 
+-- ST_AsGML (geom, precision, option) / version=2
+-- Availability: 1.4.0
+CREATEFUNCTION ST_AsGML(geometry, int4, int4)
+        RETURNS TEXT
+        AS 'SELECT _ST_AsGML(2, $1, $2, $3)'
+        LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
+
+-- ST_AsGML(version, geom, precision, option)
+-- Availability: 1.4.0
+CREATEFUNCTION ST_AsGML(int4, geometry, int4, int4)
+	RETURNS TEXT
+	AS 'SELECT _ST_AsGML($1, $2, $3, $4)'
+	LANGUAGE 'SQL' _IMMUTABLE_STRICT; -- WITH (isstrict,iscachable);
+
 -----------------------------------------------------------------------
 -- KML OUTPUT
 -----------------------------------------------------------------------



More information about the postgis-commits mailing list