<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>
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>
<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=> SELECT AsText(geom) AS OGCGeom FROM SPATIALTABLE;
OGCGeom
-------------------------------------------------
-POINT(-126.4 45.32)
+ POINT(-126.4 45.32)
(1 row)
db=> SELECT geom AS PostGISGeom FROM thetable;
PostGISGeom
-------------------------------------------------
-SRID=312;01010000009A99999999995FC0295C8FC2F5A84640
+ 0101000020380100009A99999999995FC0295C8FC2F5A84640
(1 row)</programlisting>
</sect2>
</sect1>
<variablelist>
<varlistentry>
- <term>asbinary(geometry,'NDR')</term>
+ <term>asBinary(geometry,'NDR')</term>
<listitem>
<para>Returns the geometry in the OGC "well-known-binary" format,
</varlistentry>
<varlistentry>
- <term>asbinary(geometry,'XDR')</term>
+ <term>asBinary(geometry,'XDR')</term>
<listitem>
<para>Returns the geometry in the OGC "well-known-binary" format,
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);
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);
+}
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)
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);
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;
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)
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
------------------------------------------------------------------------