]> granicus.if.org Git - postgis/commitdiff
Made asText and asBinary strict OGC conformant, introduced asEWKT and asEWKB
authorSandro Santilli <strk@keybit.net>
Tue, 21 Dec 2004 17:46:44 +0000 (17:46 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 21 Dec 2004 17:46:44 +0000 (17:46 +0000)
for extended version outputs.

git-svn-id: http://svn.osgeo.org/postgis/trunk@1175 b70326c6-7e19-0410-871a-916f4a2858ee

doc/postgis.xml
lwgeom/lwgeom_functions_basic.c
lwgeom/lwgeom_inout.c
lwgeom/lwgeom_ogc.c
lwgeom/lwgeom_pg.h
lwgeom/lwpostgis.sql.in

index b7b5969257e422fde97dfe7847cbf6497c034b9c..7b6cf03e9be551bd2ec31ed9530ee427c6fac34b 100644 (file)
@@ -696,42 +696,67 @@ AND
     <sect1 id="RefObject">
       <title>GIS Objects</title>
 
-      <para>The GIS objects supported by PostGIS are the "Simple Features"
-      defined by the OpenGIS Consortium (OGC). As of version 0.9, PostGIS
-      supports all the objects and functions specified in the OGC "Simple
+      <para>The GIS objects supported by PostGIS are a superset of
+      the "Simple Features" defined by the OpenGIS Consortium (OGC).
+      As of version 0.9, PostGIS supports all the objects and functions
+      specified in the OGC "Simple
       Features for SQL" specification.</para>
 
-      <para>Examples of the text representations of the spatial objects of the
-      features are as follows:</para>
+      <para>Examples of the text representations (WKT) of the spatial
+      objects of the features are as follows:</para>
 
       <itemizedlist>
         <listitem>
-          <para>POINT(0 0) -- XY</para>
+          <para>POINT(0 0)</para>
         </listitem>
 
         <listitem>
-          <para>POINT(0 0 0) -- XYZ</para>
+          <para>LINESTRING(0 0,1 1,1 2)</para>
         </listitem>
 
         <listitem>
-          <para>POINTM(0 0 0) -- XYM</para>
+          <para>POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))</para>
         </listitem>
 
         <listitem>
-          <para>POINT(0 0 0 0) -- XYZM</para>
+          <para>MULTIPOINT(0 0,1 2)</para>
         </listitem>
 
         <listitem>
-          <para>LINESTRING(0 0,1 1,1 2)</para>
+          <para>MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))</para>
         </listitem>
 
         <listitem>
-          <para>POLYGON((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2
-          0,1 1 0))</para>
+          <para>MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)),
+         ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))</para>
         </listitem>
 
         <listitem>
-          <para>MULTIPOINT(0 0 0,1 2 1)</para>
+          <para>GEOMETRYCOLLECTION(POINT(2 3),LINESTRING((2 3,3 4)))</para>
+        </listitem>
+
+      </itemizedlist>
+
+      <para>PostGIS extends the standard with support for 3DZ,3DM and 4D
+      coordinates.  Examples of the text representations (EWKT) of the
+      extended spatial objects of the features are as follows:</para>
+
+      <itemizedlist>
+
+        <listitem>
+          <para>POINT(0 0 0) -- XYZ</para>
+        </listitem>
+
+        <listitem>
+          <para>POINTM(0 0 0) -- XYM</para>
+        </listitem>
+
+        <listitem>
+          <para>POINT(0 0 0 0) -- XYZM</para>
+        </listitem>
+
+        <listitem>
+          <para>MULTIPOINTM(0 0 0,1 2 1)</para>
         </listitem>
 
         <listitem>
@@ -739,28 +764,23 @@ AND
           1))</para>
         </listitem>
 
+        <listitem>
+          <para>POLYGON((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2
+          0,1 1 0))</para>
+        </listitem>
+
         <listitem>
           <para>MULTIPOLYGON(((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2
           0,1 2 0,1 1 0)),((-1 -1 0,-1 -2 0,-2 -2 0,-2 -1 0,-1 -1 0)))</para>
         </listitem>
 
         <listitem>
-          <para>GEOMETRYCOLLECTION(POINT(2 3 9),LINESTRING((2 3 4,3 4
+          <para>GEOMETRYCOLLECTIONM(POINT(2 3 9),LINESTRING((2 3 4,3 4
           5)))</para>
         </listitem>
+
       </itemizedlist>
 
-      <para>Note that in the examples above there are features with 
-      2-dimensional, 3-dimensional (XYZ,XYM) and 4-dimensional coordinates.
-      PostGIS supports 2D,3DZ,3DM and 4D coordinates -- if you describe a
-      feature with 2D coordinates when you insert it, the database will
-      return that feature to you with 2D coordinates when you extract it.
-      See the sections on the <link linkend="force_2d">force_2d()</link>,
-      <link linkend="force_3dz">force_3dz()</link>,
-      <link linkend="force_3dm">force_3dm()</link> and
-      <link linkend="force_4d">force_4d()</link> functions for information
-      on converting features to a particular coordinate dimension
-      representation.</para>
 
       <sect2>
         <title>Standard versus Canonical Forms</title>
@@ -793,23 +813,24 @@ VALUES (
         <para>The "canonical form" of the spatial objects in PostgreSQL is a
         text representation which includes all the information necessary to
         construct the object. Unlike the OpenGIS standard forms, it includes
-        the type, coordinate, <emphasis>and</emphasis> SRID information. The
-        canonical form is the default form returned from a SELECT query.
-       Since version 1.0.0 the canonical form is an HEX-encoded WKB with
-       an optional SRID=#; prefix.
+        the type, dimensions, coordinate, <emphasis>and</emphasis> SRID
+       information. The canonical form is the default form returned from a
+       SELECT query.
+       Since version 1.0.0 the canonical form is an HEX-encoded extended
+       WKB (EWKB).
        The example below shows the difference between the OGC standard and
         PostGIS canonical forms:</para>
 
         <programlisting>db=&gt; SELECT AsText(geom) AS OGCGeom FROM SPATIALTABLE;
 OGCGeom
 -------------------------------------------------
-POINT(-126.4 45.32)
+ POINT(-126.4 45.32)
 (1 row)
 
 db=&gt; SELECT geom AS PostGISGeom FROM thetable;
 PostGISGeom
 -------------------------------------------------
-SRID=312;01010000009A99999999995FC0295C8FC2F5A84640
+ 0101000020380100009A99999999995FC0295C8FC2F5A84640
 (1 row)</programlisting>
       </sect2>
     </sect1>
@@ -3934,7 +3955,7 @@ FROM geometry_table;</literallayout>
          <variablelist>
 
                <varlistentry>
-                 <term>asbinary(geometry,'NDR')</term>
+                 <term>asBinary(geometry,'NDR')</term>
 
                  <listitem>
                    <para>Returns the geometry in the OGC "well-known-binary" format,
@@ -3945,7 +3966,7 @@ FROM geometry_table;</literallayout>
                </varlistentry>
 
                <varlistentry>
-                 <term>asbinary(geometry,'XDR')</term>
+                 <term>asBinary(geometry,'XDR')</term>
 
                  <listitem>
                    <para>Returns the geometry in the OGC "well-known-binary" format,
index cbfc0de461c65d3da37fdf17d0c3575600a6e471..b8c24d62e291809d8442d6c1b2ce7137f41eaafd 100644 (file)
@@ -28,12 +28,6 @@ Datum LWGEOM_length2d_linestring(PG_FUNCTION_ARGS);
 Datum LWGEOM_length_linestring(PG_FUNCTION_ARGS);
 Datum LWGEOM_perimeter2d_poly(PG_FUNCTION_ARGS);
 Datum LWGEOM_perimeter_poly(PG_FUNCTION_ARGS);
-Datum LWGEOM_force_2d(PG_FUNCTION_ARGS);
-Datum LWGEOM_force_3dm(PG_FUNCTION_ARGS);
-Datum LWGEOM_force_3dz(PG_FUNCTION_ARGS);
-Datum LWGEOM_force_4d(PG_FUNCTION_ARGS);
-Datum LWGEOM_force_collection(PG_FUNCTION_ARGS);
-Datum LWGEOM_force_multi(PG_FUNCTION_ARGS);
 Datum LWGEOM_mindistance2d(PG_FUNCTION_ARGS);
 Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS);
 Datum LWGEOM_translate(PG_FUNCTION_ARGS);
@@ -2547,3 +2541,36 @@ Datum LWGEOM_addpoint(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 
 }
+
+//convert LWGEOM to wwkt (in TEXT format)
+PG_FUNCTION_INFO_V1(LWGEOM_asEWKT);
+Datum LWGEOM_asEWKT(PG_FUNCTION_ARGS)
+{
+       PG_LWGEOM *lwgeom;
+       PG_LWGEOM *ogclwgeom;
+       char *result_cstring;
+       int len;
+        char *result,*loc_wkt;
+       //char *semicolonLoc;
+
+       init_pg_func();
+
+       lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       result_cstring =  unparse_WKT(SERIALIZED_FORM(lwgeom),lwalloc,lwfree);
+
+       //semicolonLoc = strchr(result_cstring,';');
+
+       ////loc points to start of wkt
+       //if (semicolonLoc == NULL) loc_wkt = result_cstring;
+       //else loc_wkt = semicolonLoc +1;
+       loc_wkt = result_cstring;
+
+       len = strlen(loc_wkt)+4;
+       result = palloc(len);
+       memcpy(result, &len, 4);
+
+       memcpy(result+4,loc_wkt, len-4);
+
+       pfree(result_cstring);
+       PG_RETURN_POINTER(result);
+}
index 0e7699aa75fbc2cab7e5503a8e45119779675543..410c03349e383537f86c01b153d46c0f53f38aae 100644 (file)
 void elog_ERROR(const char* string);
 
 
-// needed for OGC conformance
-Datum LWGEOMFromWKB(PG_FUNCTION_ARGS);
-Datum WKBFromLWGEOM(PG_FUNCTION_ARGS);
-
 Datum LWGEOM_in(PG_FUNCTION_ARGS);
 Datum LWGEOM_out(PG_FUNCTION_ARGS);
 Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS);
index 92cd4c4452f63130b3f61884aba9291e92b9f1f9..1314eb79d68f490dca4dd564ab348e15dd9adfab 100644 (file)
@@ -55,6 +55,8 @@ Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS);
 Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS);
 // ---- AsText(geometry)
 Datum LWGEOM_asText(PG_FUNCTION_ARGS);
+// ---- AsBinary(geometry, [XDR|NDR])
+Datum LWGEOM_asBinary(PG_FUNCTION_ARGS);
 // ---- GeometryFromText(text, integer)
 Datum LWGEOM_from_text(PG_FUNCTION_ARGS);
 // ---- IsClosed(geometry)
@@ -733,22 +735,27 @@ PG_FUNCTION_INFO_V1(LWGEOM_asText);
 Datum LWGEOM_asText(PG_FUNCTION_ARGS)
 {
        PG_LWGEOM *lwgeom;
+       PG_LWGEOM *ogclwgeom;
        char *result_cstring;
        int len;
         char *result,*loc_wkt;
-       //char *semicolonLoc;
+       char *semicolonLoc;
 
        init_pg_func();
 
        lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       result_cstring =  unparse_WKT(SERIALIZED_FORM(lwgeom),lwalloc,lwfree);
 
-       //semicolonLoc = strchr(result_cstring,';');
+       /* Force to 2d */
+       ogclwgeom = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
+               LWGEOM_force_2d, PointerGetDatum(lwgeom)));
 
-       ////loc points to start of wkt
-       //if (semicolonLoc == NULL) loc_wkt = result_cstring;
-       //else loc_wkt = semicolonLoc +1;
-       loc_wkt = result_cstring;
+       result_cstring =  unparse_WKT(SERIALIZED_FORM(ogclwgeom),lwalloc,lwfree);
+
+       semicolonLoc = strchr(result_cstring,';');
+
+       //loc points to start of wkt
+       if (semicolonLoc == NULL) loc_wkt = result_cstring;
+       else loc_wkt = semicolonLoc +1;
 
        len = strlen(loc_wkt)+4;
        result = palloc(len);
@@ -760,6 +767,39 @@ Datum LWGEOM_asText(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 }
 
+//convert LWGEOM to wkb (in BINARY format)
+PG_FUNCTION_INFO_V1(LWGEOM_asBinary);
+Datum LWGEOM_asBinary(PG_FUNCTION_ARGS)
+{
+       PG_LWGEOM *ogclwgeom;
+       char *result;
+
+       init_pg_func();
+
+       /* 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));
+
+       /* Call WKBFromLWGEOM */
+       if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
+       {
+               result = (char *)DatumGetPointer(DirectFunctionCall2(
+                       WKBFromLWGEOM, PointerGetDatum(ogclwgeom),
+                       PG_GETARG_DATUM(1)));
+       }
+       else
+       {
+               result = (char *)DatumGetPointer(DirectFunctionCall1(
+                       WKBFromLWGEOM, PointerGetDatum(ogclwgeom)));
+       }
+
+       PG_RETURN_POINTER(result);
+}
+
 char line_is_closed(LWLINE *line)
 {
        POINT4D *sp, *ep;
index 62a94a6768c4641056fc48d5bbe5fb22383bfaf2..19621960ff03d09b906fb075f9c07b649a8c47fe 100644 (file)
@@ -43,5 +43,15 @@ Datum LWGEOM_same(PG_FUNCTION_ARGS);
 Datum BOX3D_construct(PG_FUNCTION_ARGS);
 Datum BOX2DFLOAT4_ymin(PG_FUNCTION_ARGS);
 
+Datum LWGEOM_force_2d(PG_FUNCTION_ARGS);
+Datum LWGEOM_force_3dm(PG_FUNCTION_ARGS);
+Datum LWGEOM_force_3dz(PG_FUNCTION_ARGS);
+Datum LWGEOM_force_4d(PG_FUNCTION_ARGS);
+Datum LWGEOM_force_collection(PG_FUNCTION_ARGS);
+Datum LWGEOM_force_multi(PG_FUNCTION_ARGS);
+
+Datum LWGEOMFromWKB(PG_FUNCTION_ARGS);
+Datum WKBFromLWGEOM(PG_FUNCTION_ARGS);
+
 
 #endif // !defined _LWGEOM_PG_H 1
index 62c505a28678f697b10a1a3e7dfe2cd3ba293ce9..5f48a1da8b4ff702da1ff932d10984dd196854d3 100644 (file)
@@ -1119,12 +1119,12 @@ CREATEFUNCTION SetSRID(geometry,int4)
        
 CREATEFUNCTION AsBinary(geometry)
        RETURNS bytea
-       AS '@MODULE_FILENAME@','WKBFromLWGEOM'
+       AS '@MODULE_FILENAME@','LWGEOM_asBinary'
        LANGUAGE 'C' WITH (isstrict,iscachable);
 
 CREATEFUNCTION AsBinary(geometry,text)
        RETURNS bytea
-       AS '@MODULE_FILENAME@','WKBFromLWGEOM'
+       AS '@MODULE_FILENAME@','LWGEOM_asBinary'
        LANGUAGE 'C' WITH (isstrict,iscachable);
 
 CREATEFUNCTION AsText(geometry)
@@ -1703,6 +1703,21 @@ CREATEFUNCTION ndims(geometry)
        AS '@MODULE_FILENAME@', 'LWGEOM_ndims'
        LANGUAGE 'C' WITH (iscachable,isstrict);
 
+CREATEFUNCTION AsEWKT(geometry)
+       RETURNS TEXT
+       AS '@MODULE_FILENAME@','LWGEOM_asEWKT'
+       LANGUAGE 'C' WITH (isstrict,iscachable);
+
+CREATEFUNCTION AsEWKB(geometry)
+       RETURNS BYTEA
+       AS '@MODULE_FILENAME@','WKBFromLWGEOM'
+       LANGUAGE 'C' WITH (isstrict,iscachable);
+
+CREATEFUNCTION AsEWKB(geometry,text)
+       RETURNS bytea
+       AS '@MODULE_FILENAME@','WKBFromLWGEOM'
+       LANGUAGE 'C' WITH (isstrict,iscachable);
+
 ------------------------------------------------------------------------
 -- CONSTRUCTORS
 ------------------------------------------------------------------------