Made asText and asBinary strict OGC conformant, introduced asEWKT and asEWKB

for extended version outputs.


git-svn-id: http://svn.osgeo.org/postgis/trunk@1175 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
Sandro Santilli 2004-12-21 17:46:44 +00:00
parent c02b57d287
commit 5f59c5f1ec
6 changed files with 164 additions and 55 deletions

View file

@ -696,19 +696,53 @@ 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>LINESTRING(0 0,1 1,1 2)</para>
</listitem>
<listitem>
<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>MULTIPOINT(0 0,1 2)</para>
</listitem>
<listitem>
<para>MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))</para>
</listitem>
<listitem>
<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>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>
@ -722,16 +756,7 @@ AND
</listitem>
<listitem>
<para>LINESTRING(0 0,1 1,1 2)</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>MULTIPOINT(0 0 0,1 2 1)</para>
<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,

View 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);
}

View file

@ -31,10 +31,6 @@
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);

View 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;

View 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

View 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
------------------------------------------------------------------------