<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
- <funcdef>box3d_extent <function>ST_Extent</function></funcdef>
+ <funcdef>box2d <function>ST_Extent</function></funcdef>
<paramdef><type>geometry set</type> <parameter>geomfield</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</note>
<note>
- <para>Availability: 1.4.0 As of 1.4.0 now returns a box3d_extent instead of box2d object.</para>
+ <para>Availability: 1.4.0</para>
</note>
<para>Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced.</para>
</refsection>
</refentry>
- <refentry id="box3d_extent">
- <refnamediv>
- <refname>box3d_extent</refname>
- <refpurpose>A box composed of x min, ymin, zmin, xmax, ymax, zmax. Often used to return the extent of a geometry.</refpurpose>
- </refnamediv>
-
- <refsection>
- <title>Description</title>
- <para>box3d_extent is a data type returned by ST_Extent. In versions prior to PostGIS 1.4, ST_Extent would return a box2d.</para>
- </refsection>
-
- <refsection>
- <title>Casting Behavior</title>
- <para>This section lists the automatic as well as explicit casts allowed for this data type</para>
- <informaltable rowsep="1" frame="all">
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>Cast To</entry>
- <entry>Behavior</entry>
- </row>
- <row>
- <entry>box2d</entry>
- <entry>automatic</entry>
- </row>
- <row>
- <entry>box3d</entry>
- <entry>automatic</entry>
- </row>
- <row>
- <entry>geometry</entry>
- <entry>automatic</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- </refsection>
-
- <refsection>
- <title>See Also</title>
- <para><xref linkend="PostGIS_BoxFunctions" /> </para>
- </refsection>
- </refentry>
-
<refentry id="geometry">
<refnamediv>
<refname>geometry</refname>
<sect1 id="PostGIS_BoxFunctions">
<title>PostGIS Box Functions</title>
<para>The functions given below are PostGIS functions that take as input or return as output the box* family of PostGIS spatial types.
- The box family of types consists of <link linkend="box2d">box2d</link>, <link linkend="box3d">box3d</link>, <link linkend="box3d_extent">box3d_extent</link> </para>
+ The box family of types consists of <link linkend="box2d">box2d</link>, and <link linkend="box3d">box3d</link></para>
<itemizedlist>
<!-- Pull out the purpose section for each ref entry and strip whitespace and put in a variable to be tagged unto each function comment -->
<xsl:for-each select='//refentry'>
AS 'MODULE_PATHNAME','LWGEOM_to_bytea'
LANGUAGE 'C' IMMUTABLE STRICT;
---- Deprecation in 1.5.0
-CREATE OR REPLACE FUNCTION st_box3d_extent(box3d_extent)
- RETURNS box3d
- AS 'MODULE_PATHNAME', 'BOX3D_extent_to_BOX3D'
- LANGUAGE 'C' IMMUTABLE STRICT;
-
---- Deprecation in 1.5.0
-CREATE OR REPLACE FUNCTION st_box2d(box3d_extent)
- RETURNS box2d
- AS 'MODULE_PATHNAME', 'BOX3D_to_BOX2DFLOAT4'
- LANGUAGE 'C' IMMUTABLE STRICT;
-
-- Deprecation in 1.5.0
CREATE OR REPLACE FUNCTION st_box3d_in(cstring)
RETURNS box3d
AS 'MODULE_PATHNAME', 'BOX3D_out'
LANGUAGE 'C' IMMUTABLE STRICT;
---- Deprecation in 1.5.0
-CREATE OR REPLACE FUNCTION st_geometry(box3d_extent)
- RETURNS geometry
- AS 'MODULE_PATHNAME','BOX3D_to_LWGEOM'
- LANGUAGE 'C' IMMUTABLE STRICT;
-
-- START MANAGEMENT FUNCTIONS
-- These are legacy management functions with no place in our 2.0 world
-----------------------------------------------------------------------
RETURNS geometry
AS 'MODULE_PATHNAME', 'LWGEOM_expand'
LANGUAGE 'C' IMMUTABLE STRICT;
-
--- Deprecation in 1.2.3
--- Temporary hack function
-CREATE OR REPLACE FUNCTION Combine_Bbox(box3d_extent,geometry)
- RETURNS box3d_extent
- AS 'MODULE_PATHNAME', 'BOX3D_combine'
- LANGUAGE 'C' IMMUTABLE;
-
+
CREATE AGGREGATE Extent(
sfunc = ST_combine_bbox,
basetype = geometry,
- stype = box3d_extent
+ finalfunc = box2d,
+ stype = box3d
);
-- Deprecation in 1.2.3
/* forward defs */
Datum BOX3D_in(PG_FUNCTION_ARGS);
Datum BOX3D_out(PG_FUNCTION_ARGS);
-Datum BOX3D_extent_out(PG_FUNCTION_ARGS);
-Datum BOX3D_extent_to_BOX3D(PG_FUNCTION_ARGS);
Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS);
Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS);
Datum BOX3D_expand(PG_FUNCTION_ARGS);
PG_RETURN_CSTRING(result);
}
-/**
- * Takes an internal rep of a BOX3D and returns a string rep.
- * but beginning with BOX(...) and with only 2 dimensions. This
- * is a temporary hack to allow ST_Extent() to return a result
- * with the precision of BOX2DFLOAT4 but with the BOX2DFLOAT4
- * output format.
- *
- * example:
- * "BOX(xmin ymin, xmax ymax)"
- */
-PG_FUNCTION_INFO_V1(BOX3D_extent_out);
-Datum BOX3D_extent_out(PG_FUNCTION_ARGS)
-{
- BOX3D *bbox = (BOX3D *) PG_GETARG_POINTER(0);
- int size;
- char *result;
-
- if (bbox == NULL)
- {
- result = palloc(5);
- strcat(result,"NULL");
- PG_RETURN_CSTRING(result);
- }
-
-
- /*double digits+ "BOX3D"+ "()" + commas +null */
- size = MAX_DIGS_DOUBLE*6+5+2+4+5+1;
-
- result = (char *) palloc(size);
-
- sprintf(result, "BOX(%.15g %.15g,%.15g %.15g)",
- bbox->xmin, bbox->ymin,
- bbox->xmax,bbox->ymax);
-
- PG_RETURN_CSTRING(result);
-}
-
-PG_FUNCTION_INFO_V1(BOX3D_extent_to_BOX3D);
-Datum BOX3D_extent_to_BOX3D(PG_FUNCTION_ARGS)
-{
- BOX3D *in = (BOX3D *)PG_GETARG_POINTER(0);
- BOX3D *out = palloc(sizeof(BOX3D));
- out->xmin = in->xmin;
- out->xmax = in->xmax;
- out->ymin = in->ymin;
- out->ymax = in->ymax;
-
- PG_RETURN_POINTER(out);
-}
PG_FUNCTION_INFO_V1(BOX3D_to_BOX2DFLOAT4);
Datum BOX3D_to_BOX2DFLOAT4(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(Max(box->zmin, box->zmax));
}
-
+/**
+* Used in the ST_Extent and ST_Extent3D aggregates, does not read the
+* serialized cached bounding box (since that is floating point)
+* but calculates the box in full from the underlying geometry.
+*/
PG_FUNCTION_INFO_V1(BOX3D_combine);
Datum BOX3D_combine(PG_FUNCTION_ARGS)
{
- Pointer box3d_ptr = PG_GETARG_POINTER(0);
- Pointer geom_ptr = PG_GETARG_POINTER(1);
- BOX3D *a,*b;
- GSERIALIZED *geom;
- LWGEOM *lwgeom;
- BOX3D *result;
+ BOX3D *box = (BOX3D*)PG_GETARG_POINTER(0);
+ GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_POINTER(1));
+ LWGEOM *lwgeom = NULL;
+ BOX3D *result = NULL;
GBOX gbox;
int rv;
- if ( (box3d_ptr == NULL) && (geom_ptr == NULL) )
- {
+ /* Can't do anything with null inputs */
+ if ( (box == NULL) && (geom == NULL) )
PG_RETURN_NULL();
- }
-
- if (box3d_ptr == NULL)
- {
- geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
- lwgeom = lwgeom_from_gserialized(geom);
- rv = lwgeom_calculate_gbox(lwgeom, &gbox);
- if ( rv == LW_FAILURE )
- {
- lwgeom_free(lwgeom);
- PG_FREE_IF_COPY(geom, 1);
- PG_RETURN_NULL(); /* must be the empty geom */
- }
- result = box3d_from_gbox(&gbox);
- PG_RETURN_POINTER(result);
- }
-
- /* combine_bbox(BOX3D, null) => BOX3D */
- if (geom_ptr == NULL)
+ /* Null geometry but non-null box, return the box */
+ if (geom == NULL)
{
result = palloc(sizeof(BOX3D));
- memcpy(result, (char *)PG_GETARG_DATUM(0), sizeof(BOX3D));
+ memcpy(result, box, sizeof(BOX3D));
PG_RETURN_POINTER(result);
}
- geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+ /* Deserialize geometry and *calculate( the box */
+ /* We can't use the cached box because it's fload, we *must* calculate */
lwgeom = lwgeom_from_gserialized(geom);
rv = lwgeom_calculate_gbox(lwgeom, &gbox);
- result = palloc(sizeof(BOX3D));
+ lwgeom_free(lwgeom);
+
+ /* If we couldn't calculate the box, return what we know */
if ( rv == LW_FAILURE )
{
- lwgeom_free(lwgeom);
PG_FREE_IF_COPY(geom, 1);
- memcpy(result, (char *)PG_GETARG_DATUM(0), sizeof(BOX3D));
+ /* No geom box, no input box, so null return */
+ if ( box == NULL )
+ PG_RETURN_NULL();
+ result = palloc(sizeof(BOX3D));
+ memcpy(result, box, sizeof(BOX3D));
PG_RETURN_POINTER(result);
}
- a = (BOX3D *)PG_GETARG_POINTER(0);
- b = box3d_from_gbox(&gbox);
- result->xmax = Max(a->xmax, b->xmax);
- result->ymax = Max(a->ymax, b->ymax);
- result->zmax = Max(a->zmax, b->zmax);
- result->xmin = Min(a->xmin, b->xmin);
- result->ymin = Min(a->ymin, b->ymin);
- result->zmin = Min(a->zmin, b->zmin);
+ /* Null box and non-null geometry, just return the geometry box */
+ if ( box == NULL )
+ {
+ PG_FREE_IF_COPY(geom, 1);
+ result = box3d_from_gbox(&gbox);
+ PG_RETURN_POINTER(result);
+ }
+ result = palloc(sizeof(BOX3D));
+ result->xmax = Max(box->xmax, gbox.xmax);
+ result->ymax = Max(box->ymax, gbox.ymax);
+ result->zmax = Max(box->zmax, gbox.zmax);
+ result->xmin = Min(box->xmin, gbox.xmin);
+ result->ymin = Min(box->ymin, gbox.ymin);
+ result->zmin = Min(box->zmin, gbox.zmin);
+
+ PG_FREE_IF_COPY(geom, 1);
PG_RETURN_POINTER(result);
}
output = box3d_out\r
);\r
\r
--- Temporary box3d aggregate type to retain full double precision\r
--- for ST_Extent(). Should be removed when we change the output\r
--- type of ST_Extent() to return something other than BOX2DFLOAT4.\r
-CREATE OR REPLACE FUNCTION box3d_extent_in(cstring)\r
- RETURNS box3d_extent\r
- AS 'MODULE_PATHNAME', 'BOX3D_in'\r
- LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
-CREATE OR REPLACE FUNCTION box3d_extent_out(box3d_extent)\r
- RETURNS cstring\r
- AS 'MODULE_PATHNAME', 'BOX3D_extent_out'\r
- LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
-CREATE TYPE box3d_extent (\r
- alignment = double,\r
- internallength = 48,\r
- input = box3d_extent_in,\r
- output = box3d_extent_out\r
-);\r
-\r
--- Availability: 1.4.0\r
-CREATE OR REPLACE FUNCTION box3d_extent(box3d_extent)\r
- RETURNS box3d\r
- AS 'MODULE_PATHNAME', 'BOX3D_extent_to_BOX3D'\r
- LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
-CREATE OR REPLACE FUNCTION geometry(box3d_extent)\r
- RETURNS geometry\r
- AS 'MODULE_PATHNAME','BOX3D_to_LWGEOM'\r
- LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
--- End of temporary hack\r
-\r
-- Availability: 1.2.2\r
CREATE OR REPLACE FUNCTION ST_XMin(box3d)\r
RETURNS FLOAT8\r
AS 'MODULE_PATHNAME','LWGEOM_to_BOX2DFLOAT4'\r
LANGUAGE 'C' IMMUTABLE STRICT;\r
\r
-CREATE OR REPLACE FUNCTION box2d(box3d_extent)\r
- RETURNS box2d\r
- AS 'MODULE_PATHNAME', 'BOX3D_to_BOX2DFLOAT4'\r
- LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
-- Availability: 1.2.2\r
CREATE OR REPLACE FUNCTION ST_MakeBox2d(geometry, geometry)\r
RETURNS box2d\r
$$ LANGUAGE SQL STRICT;\r
\r
\r
-------------------------------------------------------------------------\r
-\r
---\r
--- Aggregate functions\r
---\r
--- Temporary hack function\r
-CREATE OR REPLACE FUNCTION ST_Combine_BBox(box3d_extent,geometry)\r
- RETURNS box3d_extent\r
- AS 'MODULE_PATHNAME', 'BOX3D_combine'\r
- LANGUAGE 'C' IMMUTABLE;\r
-\r
--- Availability: 1.2.2\r
-CREATE AGGREGATE ST_Extent(\r
- sfunc = ST_combine_bbox,\r
- basetype = geometry,\r
- stype = box3d_extent\r
- );\r
-\r
--- Availability: 1.2.2\r
-CREATE OR REPLACE FUNCTION ST_Combine_BBox(box3d,geometry)\r
- RETURNS box3d\r
- AS 'MODULE_PATHNAME', 'BOX3D_combine'\r
- LANGUAGE 'C' IMMUTABLE;\r
-\r
--- Availability: 2.0.0\r
-CREATE AGGREGATE ST_3DExtent(\r
- sfunc = ST_combine_bbox,\r
- basetype = geometry,\r
- stype = box3d\r
- );\r
-\r
-\r
\r
-------------------------------------------------------------------\r
-- SPATIAL_REF_SYS\r
CREATE CAST (bytea AS geometry) WITH FUNCTION geometry(bytea) AS IMPLICIT;\r
CREATE CAST (geometry AS bytea) WITH FUNCTION bytea(geometry) AS IMPLICIT;\r
\r
--- Casts to allow the box3d_extent type to automatically cast to box3d/box2d in queries\r
-CREATE CAST (box3d_extent AS box3d) WITH FUNCTION box3d_extent(box3d_extent) AS IMPLICIT;\r
-CREATE CAST (box3d_extent AS box2d) WITH FUNCTION box2d(box3d_extent) AS IMPLICIT;\r
-CREATE CAST (box3d_extent AS geometry) WITH FUNCTION geometry(box3d_extent) AS IMPLICIT;\r
\r
---------------------------------------------------------------\r
-- Algorithms\r
-- Aggregates and their supporting functions\r
--------------------------------------------------------------------------------\r
\r
+------------------------------------------------------------------------\r
+-- Availability: 1.2.2\r
+CREATE OR REPLACE FUNCTION ST_Combine_BBox(box3d,geometry)\r
+ RETURNS box3d\r
+ AS 'MODULE_PATHNAME', 'BOX3D_combine'\r
+ LANGUAGE 'C' IMMUTABLE;\r
+\r
+-- Availability: 1.2.2\r
+CREATE AGGREGATE ST_Extent(\r
+ sfunc = ST_combine_bbox,\r
+ finalfunc = box2d,\r
+ basetype = geometry,\r
+ stype = box3d\r
+ );\r
+\r
+-- Availability: 2.0.0\r
+CREATE AGGREGATE ST_3DExtent(\r
+ sfunc = ST_combine_bbox,\r
+ basetype = geometry,\r
+ stype = box3d\r
+ );\r
+\r
-- Availability: 1.2.2\r
CREATE OR REPLACE FUNCTION ST_Collect(geometry, geometry)\r
RETURNS geometry\r
DROP FUNCTION IF EXISTS st_box2d_out(box2d);
DROP FUNCTION IF EXISTS st_box2d(geometry);
DROP FUNCTION IF EXISTS st_box2d(box3d);
-DROP FUNCTION IF EXISTS st_box2d(box3d_extent);
DROP FUNCTION IF EXISTS st_box3d(box2d);
DROP FUNCTION IF EXISTS st_box(box3d);
DROP FUNCTION IF EXISTS st_box3d(geometry);
DROP FUNCTION IF EXISTS st_geometry(text);
DROP FUNCTION IF EXISTS st_geometry(bytea);
DROP FUNCTION IF EXISTS st_bytea(geometry);
-DROP FUNCTION IF EXISTS st_box3d_extent(box3d_extent);
-DROP FUNCTION IF EXISTS st_geometry(box3d_extent);
DROP FUNCTION IF EXISTS st_addbbox(geometry);
DROP FUNCTION IF EXISTS st_dropbbox(geometry);
DROP FUNCTION IF EXISTS st_hasbbox(geometry);
DROP FUNCTION IF EXISTS Buffer(geometry,float8);
DROP FUNCTION IF EXISTS BuildArea(geometry);
DROP FUNCTION IF EXISTS Centroid(geometry);
-DROP FUNCTION IF EXISTS Combine_Bbox(box3d_extent,geometry);
DROP FUNCTION IF EXISTS Contains(geometry,geometry);
DROP FUNCTION IF EXISTS ConvexHull(geometry);
DROP FUNCTION IF EXISTS Crosses(geometry,geometry);
-- CASTS
---------------------------------------------------------------
-DROP CAST (box3d_extent AS geometry);
-DROP CAST (box3d_extent AS box2d);
-DROP CAST (box3d_extent AS box3d);
-
DROP CAST (geometry AS bytea);
DROP CAST (bytea AS geometry);
DROP CAST (chip AS geometry);
DROP FUNCTION combine_bbox(box3d,geometry);
DROP AGGREGATE ST_Extent(geometry);
DROP AGGREGATE Extent(geometry);
-DROP FUNCTION ST_Combine_BBox(box3d_extent,geometry);
-DROP FUNCTION combine_bbox(box3d_extent,geometry);
DROP FUNCTION ST_Combine_BBox(box2d,geometry);
DROP FUNCTION combine_bbox(box2d,geometry);
DROP FUNCTION ST_XMin(box3d);
DROP FUNCTION xmin(box3d);
--- This drops box3d_extent_in, box3d_extent_out and the type in an atomic fashion
-DROP TYPE box3d_extent CASCADE;
-
-- This drops ST_box3d_in, ST_box3d_out, box3d_in, box3d_out and the type in an atomic fashion
DROP TYPE box3d CASCADE;