[postgis-tickets] r14930 - #3059, Allow passing per-dimension parameters in ST_Expand (remaining changes)

Daniel Baston dbaston at gmail.com
Thu Jun 2 15:47:06 PDT 2016


Author: dbaston
Date: 2016-06-02 15:47:05 -0700 (Thu, 02 Jun 2016)
New Revision: 14930

Modified:
   trunk/NEWS
   trunk/liblwgeom/g_box.c
   trunk/liblwgeom/liblwgeom.h.in
   trunk/postgis/lwgeom_box.c
   trunk/postgis/lwgeom_box3d.c
   trunk/postgis/lwgeom_functions_basic.c
   trunk/postgis/postgis.sql.in
   trunk/regress/regress.sql
   trunk/regress/regress_expected
Log:
#3059, Allow passing per-dimension parameters in ST_Expand (remaining changes)

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/NEWS	2016-06-02 22:47:05 UTC (rev 14930)
@@ -15,15 +15,16 @@
   - Add support for negative indexing in ST_PointN and ST_SetPoint
     (RĂ©mi Cura)
   - Add parameters for geography ST_Buffer (Thomas Bonfort)
-  - #3391, Add table inheritance support in ST_EstimatedExtent
-           (Alessandro Pasotti)
   - TopoGeom_addElement, TopoGeom_remElement (Sandro Santilli)
   - populate_topology_layer (Sandro Santilli)
   - #2259, ST_Voronoi (Dan Baston)
   - #2991, Enable ST_Transform to use PROJ.4 text (Mike Toews)
+  - #3059, Allow passing per-dimension parameters in ST_Expand (Dan Baston)
   - #3339, ST_GeneratePoints (Paul Ramsey)
   - #3362, ST_ClusterDBSCAN (Dan Baston)
   - #3364, ST_GeometricMedian (Dan Baston)
+  - #3391, Add table inheritance support in ST_EstimatedExtent
+           (Alessandro Pasotti)
   - #3424, ST_MinimumClearance (Dan Baston)
   - #3428, ST_Points (Dan Baston)
   - #3465, ST_ClusterKMeans (Paul Ramsey)

Modified: trunk/liblwgeom/g_box.c
===================================================================
--- trunk/liblwgeom/g_box.c	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/liblwgeom/g_box.c	2016-06-02 22:47:05 UTC (rev 14930)
@@ -123,6 +123,26 @@
 	}
 }
 
+void gbox_expand_xyzm(GBOX *g, double dx, double dy, double dz, double dm)
+{
+	g->xmin -= dx;
+	g->xmax += dx;
+	g->ymin -= dy;
+	g->ymax += dy;
+
+	if (FLAGS_GET_Z(g->flags))
+	{
+		g->zmin -= dz;
+		g->zmax += dz;
+	}
+
+	if (FLAGS_GET_M(g->flags))
+	{
+		g->mmin -= dm;
+		g->mmax += dm;
+	}
+}
+
 int gbox_union(const GBOX *g1, const GBOX *g2, GBOX *gout)
 {
 	if ( ( ! g1 ) && ( ! g2 ) )

Modified: trunk/liblwgeom/liblwgeom.h.in
===================================================================
--- trunk/liblwgeom/liblwgeom.h.in	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/liblwgeom/liblwgeom.h.in	2016-06-02 22:47:05 UTC (rev 14930)
@@ -1825,6 +1825,11 @@
 extern void gbox_expand(GBOX *g, double d);
 
 /**
+* Move the box minimums down and the maximums up by the distances provided.
+*/
+extern void gbox_expand_xyzm(GBOX *g, double dx, double dy, double dz, double dm);
+
+/**
 * Initialize a #GBOX using the values of the point.
 */
 extern int gbox_init_point3d(const POINT3D *p, GBOX *gbox);

Modified: trunk/postgis/lwgeom_box.c
===================================================================
--- trunk/postgis/lwgeom_box.c	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/postgis/lwgeom_box.c	2016-06-02 22:47:05 UTC (rev 14930)
@@ -378,12 +378,22 @@
 Datum BOX2D_expand(PG_FUNCTION_ARGS)
 {
 	GBOX *box = (GBOX *)PG_GETARG_POINTER(0);
-	double d = PG_GETARG_FLOAT8(1);
 	GBOX *result = (GBOX *)palloc(sizeof(GBOX));
-
 	memcpy(result, box, sizeof(GBOX));
-    gbox_expand(result, d);
 
+	if (PG_NARGS() == 2)
+	{
+		double d = PG_GETARG_FLOAT8(1);
+		gbox_expand(result, d);
+	}
+	else
+	{
+		double dx = PG_GETARG_FLOAT8(1);
+		double dy = PG_GETARG_FLOAT8(2);
+
+		gbox_expand_xyzm(result, dx, dy, 0, 0);
+	}
+
 	PG_RETURN_POINTER(result);
 }
 

Modified: trunk/postgis/lwgeom_box3d.c
===================================================================
--- trunk/postgis/lwgeom_box3d.c	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/postgis/lwgeom_box3d.c	2016-06-02 22:47:05 UTC (rev 14930)
@@ -369,16 +369,38 @@
 	box->zmax += d;
 }
 
+static void
+expand_box3d_xyz(BOX3D *box, double dx, double dy, double dz)
+{
+	box->xmin -= dx;
+	box->xmax += dx;
+	box->ymin -= dy;
+	box->ymax += dy;
+	box->zmin -= dz;
+	box->zmax += dz;
+}
+
 PG_FUNCTION_INFO_V1(BOX3D_expand);
 Datum BOX3D_expand(PG_FUNCTION_ARGS)
 {
 	BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
-	double d = PG_GETARG_FLOAT8(1);
 	BOX3D *result = (BOX3D *)palloc(sizeof(BOX3D));
-
 	memcpy(result, box, sizeof(BOX3D));
-	expand_box3d(result, d);
 
+	if (PG_NARGS() == 2) {
+		/* Expand the box the same amount in all directions */
+		double d = PG_GETARG_FLOAT8(1);
+		expand_box3d(result, d);
+	}
+	else
+	{
+		double dx = PG_GETARG_FLOAT8(1);
+		double dy = PG_GETARG_FLOAT8(2);
+		double dz = PG_GETARG_FLOAT8(3);
+
+		expand_box3d_xyz(result, dx, dy, dz);
+	}
+
 	PG_RETURN_POINTER(result);
 }
 

Modified: trunk/postgis/lwgeom_functions_basic.c
===================================================================
--- trunk/postgis/lwgeom_functions_basic.c	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/postgis/lwgeom_functions_basic.c	2016-06-02 22:47:05 UTC (rev 14930)
@@ -1564,10 +1564,6 @@
 {
 	GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
 	LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
-	double d = PG_GETARG_FLOAT8(1);
-	POINT4D pt;
-	POINTARRAY *pa;
-	POINTARRAY **ppa;
 	LWPOLY *poly;
 	GSERIALIZED *result;
 	GBOX gbox;
@@ -1588,43 +1584,31 @@
 		PG_RETURN_POINTER(geom);
 	}
 
-	gbox_expand(&gbox, d);
+	if (PG_NARGS() == 2)
+	{
+		/* Expand the box the same amount in all directions */
+		double d = PG_GETARG_FLOAT8(1);
+		gbox_expand(&gbox, d);
+	}
+	else
+	{
+		double dx = PG_GETARG_FLOAT8(1);
+		double dy = PG_GETARG_FLOAT8(2);
+		double dz = PG_GETARG_FLOAT8(3);
+		double dm = PG_GETARG_FLOAT8(4);
 
-	pa = ptarray_construct_empty(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 5);
-	
-	/* Assign coordinates to POINT2D array */
-	pt.x = gbox.xmin;
-	pt.y = gbox.ymin;
-	pt.z = gbox.zmin;
-	pt.m = gbox.mmin;
-	ptarray_append_point(pa, &pt, LW_TRUE);
-	pt.x = gbox.xmin;
-	pt.y = gbox.ymax;
-	pt.z = gbox.zmin;
-	pt.m = gbox.mmin;
-	ptarray_append_point(pa, &pt, LW_TRUE);
-	pt.x = gbox.xmax;
-	pt.y = gbox.ymax;
-	pt.z = gbox.zmax;
-	pt.m = gbox.mmax;
-	ptarray_append_point(pa, &pt, LW_TRUE);
-	pt.x = gbox.xmax;
-	pt.y = gbox.ymin;
-	pt.z = gbox.zmax;
-	pt.m = gbox.mmax;
-	ptarray_append_point(pa, &pt, LW_TRUE);
-	pt.x = gbox.xmin;
-	pt.y = gbox.ymin;
-	pt.z = gbox.zmin;
-	pt.m = gbox.mmin;
-	ptarray_append_point(pa, &pt, LW_TRUE);
+		gbox_expand_xyzm(&gbox, dx, dy, dz, dm);
+	}
 
-	/* Construct point array */
-	ppa = lwalloc(sizeof(POINTARRAY*));
-	ppa[0] = pa;
+	{
+		POINT4D p1 = { gbox.xmin, gbox.ymin, gbox.zmin, gbox.mmin };
+		POINT4D p2 = { gbox.xmin, gbox.ymax, gbox.zmin, gbox.mmin };
+		POINT4D p3 = { gbox.xmax, gbox.ymax, gbox.zmax, gbox.mmax };
+		POINT4D p4 = { gbox.xmax, gbox.ymin, gbox.zmax, gbox.mmax };
 
-	/* Construct polygon  */
-	poly = lwpoly_construct(lwgeom->srid, NULL, 1, ppa);
+		poly = lwpoly_construct_rectangle(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), &p1, &p2, &p3, &p4);
+	}
+
 	lwgeom_add_bbox(lwpoly_as_lwgeom(poly));
 
 	/* Construct GSERIALIZED  */

Modified: trunk/postgis/postgis.sql.in
===================================================================
--- trunk/postgis/postgis.sql.in	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/postgis/postgis.sql.in	2016-06-02 22:47:05 UTC (rev 14930)
@@ -941,11 +941,17 @@
 -----------------------------------------------------------------------------
 
 -- Availability: 1.2.2
-CREATE OR REPLACE FUNCTION ST_expand(box2d,float8)
+CREATE OR REPLACE FUNCTION ST_Expand(box2d,float8)
 	RETURNS box2d
 	AS 'MODULE_PATHNAME', 'BOX2D_expand'
 	LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL;
 
+-- Availability: 2.3.0
+CREATE OR REPLACE FUNCTION ST_Expand(box box2d, dx float8, dy float8)
+	RETURNS box2d
+	AS 'MODULE_PATHNAME', 'BOX2D_expand'
+	LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL;
+
 -- Availability: 1.5.0
 CREATE OR REPLACE FUNCTION postgis_getbbox(geometry)
 	RETURNS box2d
@@ -1416,6 +1422,13 @@
 	LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
 	COST 25;
 
+-- Availability: 2.3.0
+CREATE OR REPLACE FUNCTION ST_Expand(box box3d, dx float8, dy float8, dz float8 DEFAULT 0)
+	RETURNS box3d
+	AS 'MODULE_PATHNAME', 'BOX3D_expand'
+	LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
+	COST 25;
+
 -- Availability: 1.2.2
 CREATE OR REPLACE FUNCTION ST_Expand(geometry,float8)
 	RETURNS geometry
@@ -1423,6 +1436,13 @@
 	LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
 	COST 25;
 
+-- Availability: 2.3.0
+CREATE OR REPLACE FUNCTION ST_Expand(geom geometry, dx float8, dy float8, dz float8 DEFAULT 0, dm float8 DEFAULT 0)
+	RETURNS geometry
+	AS 'MODULE_PATHNAME', 'LWGEOM_expand'
+	LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
+	COST 25;
+
 -- PostGIS equivalent function: envelope(geometry)
 CREATE OR REPLACE FUNCTION ST_Envelope(geometry)
 	RETURNS geometry

Modified: trunk/regress/regress.sql
===================================================================
--- trunk/regress/regress.sql	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/regress/regress.sql	2016-06-02 22:47:05 UTC (rev 14930)
@@ -260,6 +260,22 @@
 select '209', ST_AsText(ST_Expand('LINESTRING (0 0, 10 10)'::geometry, -4));
 select '210', ST_Expand(null::box3d, 1);
 select '211', ST_Expand('BOX3D(-1 3 5, -1 6 8)'::BOX3D, 1);
+select '212', ST_Expand(null::box2d, 1);
+select '213', ST_Expand('BOX(-2 3, -1 6'::BOX2D, 4);
 
+select '214', ST_Expand(null::geometry, 1, 1, 1, 1);
+select '215', ST_AsText(ST_Expand('LINESTRING (1 2 3, 10 20 30)'::geometry, 1, 4, 2, 7));
+
+select '216', ST_AsText(ST_Expand('LINESTRINGM (1 2 3, 10 20 30)'::geometry, 1, 4, 2, 7));
+select '217', ST_AsText(ST_Expand('LINESTRING (1 2, 10 20)'::geometry, 1, 4, 2, 7));
+select '218', ST_AsText(ST_Expand('POLYGON EMPTY'::geometry, 4, 3, 1, 1));
+select '219', ST_AsText(ST_Expand('POINT EMPTY'::geometry, 2, 3, 1, -1));
+select '220', ST_AsText(ST_Expand('POINT (2 3)'::geometry, 0, 4, -2, 8));
+select '221', ST_AsText(ST_Expand('POINT (0 0)'::geometry, -1, -2));
+select '222', ST_Expand(null::box3d, 1, 1, 1);
+select '223', ST_Expand('BOX3D(-1 3 5, -1 6 8)'::BOX3D, 1, -1, 7);
+select '224', ST_Expand(null::box2d, 1, 1);
+select '225', ST_Expand('BOX(-2 3, -1 6'::BOX2D, 4, 2);
+
 -- Drop test table
 DROP table test;

Modified: trunk/regress/regress_expected
===================================================================
--- trunk/regress/regress_expected	2016-06-02 22:28:47 UTC (rev 14929)
+++ trunk/regress/regress_expected	2016-06-02 22:47:05 UTC (rev 14930)
@@ -185,3 +185,17 @@
 209|POLYGON((4 4,4 6,6 6,6 4,4 4))
 210|
 211|BOX3D(-2 2 4,0 7 9)
+212|
+213|BOX(-6 -1,3 10)
+214|
+215|POLYGON Z ((0 -2 1,0 24 1,11 24 32,11 -2 32,0 -2 1))
+216|POLYGON M ((0 -2 -4,0 24 -4,11 24 37,11 -2 37,0 -2 -4))
+217|POLYGON((0 -2,0 24,11 24,11 -2,0 -2))
+218|POLYGON EMPTY
+219|POINT EMPTY
+220|POLYGON((2 -1,2 7,2 7,2 -1,2 -1))
+221|POLYGON((1 2,1 -2,-1 -2,-1 2,1 2))
+222|
+223|BOX3D(-2 4 -2,0 5 15)
+224|
+225|BOX(-6 1,3 8)



More information about the postgis-tickets mailing list