[postgis-tickets] [SCM] PostGIS branch master updated. e18a0b84dfa0995f3f78d52227aceb3b3e494a52

git at osgeo.org git at osgeo.org
Wed Dec 11 01:38:09 PST 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, master has been updated
       via  e18a0b84dfa0995f3f78d52227aceb3b3e494a52 (commit)
      from  722e45c2dd5c8cc367f0093bc750724687ca2273 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit e18a0b84dfa0995f3f78d52227aceb3b3e494a52
Author: Yuri Astrakhan <YuriAstrakhan at gmail.com>
Date:   Wed Nov 13 21:41:49 2019 -0500

    Add ST_TileEnvelope margin argument
    
    Increase or decrease if negative tile envelope by a given margin
    percentage. The result is always clipped according to bounds argument.
    
    Closes #4601
    Closes https://github.com/CartoDB/cartodb/pull/15169
    
    Signed-off-by: Raúl Marín <git at rmr.ninja>

diff --git a/NEWS b/NEWS
index 72a22b0..dea80ab 100644
--- a/NEWS
+++ b/NEWS
@@ -8,8 +8,10 @@ PostGIS 3.1.0
 * Breaking changes *
   - #4577, Drop support for PostgreSQL 9.5 (Raúl Marín)
   - #4579, Drop postgis_proc_set_search_path.pl (Raúl Marín)
+  - #4601, ST_TileEnvelope signature changed.
 
 * New features *
+  - #4601, Add ST_TileEnvelope margin argument (Yuri Astrakhan)
 
 * Enhancements *
   - #4539, Unify libm includes (Raúl Marín)
diff --git a/doc/reference_constructor.xml b/doc/reference_constructor.xml
index 87ef1ea..4b8e9a7 100644
--- a/doc/reference_constructor.xml
+++ b/doc/reference_constructor.xml
@@ -771,6 +771,7 @@ SRID=4326;POLYGON((75 29 1, 77 29 2, 77 29 3, 75 29 1))
 			<paramdef><type>integer</type> <parameter>tileX</parameter></paramdef>
 			<paramdef><type>integer</type> <parameter>tileY</parameter></paramdef>
 			<paramdef choice="opt"><type>geometry</type> <parameter>bounds=SRID=3857;LINESTRING(-20037508.342789 -20037508.342789,20037508.342789 20037508.342789)</parameter></paramdef>
+			<paramdef choice="opt"><type>float</type> <parameter>margin=0.0</parameter></paramdef>
 		  </funcprototype>
 		 </funcsynopsis>
 		</refsynopsisdiv>
@@ -780,7 +781,10 @@ SRID=4326;POLYGON((75 29 1, 77 29 2, 77 29 3, 75 29 1))
 
 			<para>Creates a rectangular Polygon in <ulink url="https://en.wikipedia.org/wiki/Web_Mercator_projection">Web Mercator</ulink> (SRID:3857) using the <ulink url="https://en.wikipedia.org/wiki/Tiled_web_map">XYZ tile system</ulink>. By default, the bounds are the in EPSG:3857 using the standard range of the Web Mercator system (-20037508.342789, 20037508.342789). The optional bounds parameter can be used to generate envelopes for any tiling scheme: provide a geometry that has the SRID and extent of the initial "zoom level zero" square within which the tile system is to be inscribed.</para>
 
+			<para>The optional margin parameter can be used to grow a tile by the given percentage, e.g. margin=0.125 grows the tile by 12.5%, which is equivalent to buffer=512 when extent is 4096, as used in <xref linkend="ST_AsMVTGeom" />. This is useful to create a tile buffer -- to include data lying outside of the tile's visible area, but whose existence affects current tile's rendering. For example, a city name (a geopoint) could be near an edge of a tile, but the text would need to render on two tiles, even though the geopoint is located in the visible area of just one tile. Using an expanded tile in a search would include the city geopoint for both tiles. Use negative value to shrink the tile instead. Values less than -0.5 are prohibited because that would eliminate the tile completely. Do not use margin with ST_AsMVTGeom(). See example in <xref linkend="ST_AsMVT" />.</para>
+
 			<para>Availability: 3.0</para>
+			<para>Enhanced in 3.1: Added margin parameter.</para>
 
 		</refsection>
 
@@ -794,7 +798,7 @@ SRID=4326;POLYGON((75 29 1, 77 29 2, 77 29 3, 75 29 1))
 
 SELECT ST_AsText( ST_TileEnvelope(3, 1, 1, ST_MakeEnvelope(-180, -90, 180, 90, 4326) ) );
 
-                      st_astext                       
+                      st_astext
 ------------------------------------------------------
  POLYGON((-135 45,-135 67.5,-90 67.5,-90 45,-135 45))
 </programlisting>
diff --git a/doc/reference_output.xml b/doc/reference_output.xml
index 30a87c8..f64b992 100644
--- a/doc/reference_output.xml
+++ b/doc/reference_output.xml
@@ -1189,9 +1189,9 @@ SELECT (ST_AsLatLonText('POINT (-302.2342342 -792.32498)'));
 		<title>Examples</title>
 		<programlisting><![CDATA[WITH mvtgeom AS
 (
-  SELECT ST_AsMVTGeom(geom, ST_TileEnvelope(12,513,412)) AS geom, name, description
+  SELECT ST_AsMVTGeom(geom, ST_TileEnvelope(12, 513, 412), extent => 4096, buffer => 64) AS geom, name, description
   FROM points_of_interest
-  WHERE ST_Intersects(geom, ST_TileEnvelope(12,513,412)
+  WHERE geom && ST_TileEnvelope(12, 513, 412, margin => (64.0 / 4096))
 )
 SELECT ST_AsMVT(mvtgeom.*)
 FROM mvtgeom;
diff --git a/postgis/lwgeom_functions_basic.c b/postgis/lwgeom_functions_basic.c
index adc6d3f..89a395b 100644
--- a/postgis/lwgeom_functions_basic.c
+++ b/postgis/lwgeom_functions_basic.c
@@ -2051,6 +2051,7 @@ Datum ST_TileEnvelope(PG_FUNCTION_ARGS)
 	double tileGeoSizeX, tileGeoSizeY;
 	double boundsWidth, boundsHeight;
 	double x1, y1, x2, y2;
+	double margin;
 	/* This is broken, since 3857 doesn't mean "web mercator", it means
 	   the contents of the row in spatial_ref_sys with srid = 3857.
 	   For practical purposes this will work, but in good implementation
@@ -2070,6 +2071,11 @@ Datum ST_TileEnvelope(PG_FUNCTION_ARGS)
 		elog(ERROR, "%s: Empty bounds", __func__);
 	srid = gserialized_get_srid(bounds);
 
+	margin = PG_GETARG_FLOAT8(4);
+	/* shrinking by more than 50% would eliminate the tile outright */
+	if (margin < -0.5)
+		elog(ERROR, "%s: Margin must not be less than -50%%, margin=%f", __func__, margin);
+
 	boundsWidth  = bbox.xmax - bbox.xmin;
 	boundsHeight = bbox.ymax - bbox.ymin;
 	if (boundsWidth <= 0 || boundsHeight <= 0)
@@ -2088,10 +2094,29 @@ Datum ST_TileEnvelope(PG_FUNCTION_ARGS)
 
 	tileGeoSizeX = boundsWidth / worldTileSize;
 	tileGeoSizeY = boundsHeight / worldTileSize;
-	x1 = bbox.xmin + tileGeoSizeX * (x);
-	x2 = bbox.xmin + tileGeoSizeX * (x+1);
-	y1 = bbox.ymax - tileGeoSizeY * (y+1);
-	y2 = bbox.ymax - tileGeoSizeY * (y);
+
+	/*
+	 * 1 margin (100%) is the same as a single tile width
+	 * if the size of the tile with margins span more than the total number of tiles,
+	 * reset x1/x2 to the bounds
+	*/
+	if ((1 + margin * 2) > worldTileSize)
+	{
+		x1 = bbox.xmin;
+		x2 = bbox.xmax;
+	}
+	else
+	{
+		x1 = bbox.xmin + tileGeoSizeX * (x - margin);
+		x2 = bbox.xmin + tileGeoSizeX * (x + 1 + margin);
+	}
+
+	y1 = bbox.ymax - tileGeoSizeY * (y + 1 + margin);
+	y2 = bbox.ymax - tileGeoSizeY * (y - margin);
+
+	/* Clip y-axis to the given bounds */
+	if (y1 < bbox.ymin) y1 = bbox.ymin;
+	if (y2 > bbox.ymax) y2 = bbox.ymax;
 
 	PG_RETURN_POINTER(
 		geometry_serialize(
diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in
index 9ad89be..4727552 100644
--- a/postgis/postgis.sql.in
+++ b/postgis/postgis.sql.in
@@ -1686,7 +1686,8 @@ CREATE OR REPLACE FUNCTION ST_MakeEnvelope(float8, float8, float8, float8, integ
 	_COST_LOW;
 
 -- Availability: 3.0.0
-CREATE OR REPLACE FUNCTION ST_TileEnvelope(zoom integer, x integer, y integer, bounds geometry DEFAULT 'SRID=3857;LINESTRING(-20037508.342789 -20037508.342789, 20037508.342789 20037508.342789)'::geometry)
+-- Changed: 3.1.0 - add margin=0.0 parameter
+CREATE OR REPLACE FUNCTION ST_TileEnvelope(zoom integer, x integer, y integer, bounds geometry DEFAULT 'SRID=3857;LINESTRING(-20037508.342789 -20037508.342789, 20037508.342789 20037508.342789)'::geometry, margin float8 DEFAULT 0.0)
 	RETURNS geometry
 	AS 'MODULE_PATHNAME', 'ST_TileEnvelope'
 	LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE
@@ -2853,7 +2854,7 @@ BEGIN
 			THEN
 				--force install in same schema as postgis only if postgis extension is installed
 				IF rec.name NOT IN('postgis', 'postgis_topology', 'postgis_tiger_geocoder') AND EXISTS (SELECT 1 FROM pg_catalog.pg_extension WHERE extname = 'postgis') THEN
-					sql = 'CREATE EXTENSION ' || rec.name || ' FROM unpackaged SCHEMA ' 
+					sql = 'CREATE EXTENSION ' || rec.name || ' FROM unpackaged SCHEMA '
 					|| quote_ident( (SELECT ns.nspname FROM pg_catalog.pg_extension AS e INNER JOIN pg_catalog.pg_namespace AS ns ON e.extnamespace = ns.oid WHERE extname = 'postgis')) || ';';
 				ELSE
 					sql = 'CREATE EXTENSION ' || rec.name || ' FROM unpackaged;';
diff --git a/postgis/postgis_before_upgrade.sql b/postgis/postgis_before_upgrade.sql
index c709b05..8780c90 100644
--- a/postgis/postgis_before_upgrade.sql
+++ b/postgis/postgis_before_upgrade.sql
@@ -187,6 +187,12 @@ SELECT _postgis_drop_function_if_needed
 	'GeometryA geometry, GeometryB geometry'
 	);
 
+-- FUNCTION st_tileenvelope added a new default argument in 3.1
+SELECT _postgis_drop_function_if_needed
+    (
+    'st_tileenvelope',
+    'zoom integer, x integer, y integer, bounds geometry DEFAULT ''0102000020110F00000200000052107C45F81B73C152107C45F81B73C152107C45F81B734152107C45F81B7341''::geometry'
+    );
 
 -- FUNCTION st_askml changed to add defaults in 3.0 / r17357
 -- These signatures were superseeded
diff --git a/regress/core/regress.sql b/regress/core/regress.sql
index 78ab69b..6f5eea3 100644
--- a/regress/core/regress.sql
+++ b/regress/core/regress.sql
@@ -274,7 +274,17 @@ select '232', ST_AsEWKT(ST_TileEnvelope(4, 8, 8, ST_MakeEnvelope(-100, -100, 100
 select '233', ST_AsEWKT(ST_TileEnvelope(4, 15, 15, ST_MakeEnvelope(-100, -100, 100, 100, 0)));
 select '234', ST_AsEWKT(ST_TileEnvelope(4, 0, 0, ST_MakeEnvelope(-100, -100, 100, 100, 0)));
 select '235', ST_AsEWKT(ST_TileEnvelope(4, 8, 8, ST_MakeEnvelope(-200, -100, 200, 100, 0)));
-
+select '236', ST_AsEWKT(ST_TileEnvelope(0, 0, 0, margin => 0.1));
+select '237', ST_AsEWKT(ST_TileEnvelope(1, 0, 0, margin => 0.1));
+select '238', ST_AsEWKT(ST_TileEnvelope(2, 1, 3, margin => 0.5));
+select '239', ST_AsEWKT(ST_TileEnvelope(0, 0, 0, margin => -0.5));
+select '240', ST_AsEWKT(ST_TileEnvelope(0, 0, 0, margin => -0.51));
+select '241', ST_AsEWKT(ST_TileEnvelope(0, 0, 0, margin => -0.4));
+select '250', ST_AsEWKT(ST_TileEnvelope(10,300,387));
+select '251', ST_AsEWKT(ST_TileEnvelope(10,300,387, margin => 0.1));
+select '252', ST_AsEWKT(ST_TileEnvelope(10,300,387, margin => 0.5));
+select '253', ST_AsEWKT(ST_TileEnvelope(10,300,387, margin => 2));
+select '254', ST_AsEWKT(ST_TileEnvelope(10,300,387, margin => -0.3));
 
 -- Drop test table
 DROP table test;
diff --git a/regress/core/regress_expected b/regress/core/regress_expected
index d82fe5c..4b3d7bc 100644
--- a/regress/core/regress_expected
+++ b/regress/core/regress_expected
@@ -203,3 +203,14 @@ ERROR:  ST_TileEnvelope: Invalid tile y value, 1
 233|POLYGON((87.5 -100,87.5 -87.5,100 -87.5,100 -100,87.5 -100))
 234|POLYGON((-100 87.5,-100 100,-87.5 100,-87.5 87.5,-100 87.5))
 235|POLYGON((0 -12.5,0 0,25 0,25 -12.5,0 -12.5))
+236|SRID=3857;POLYGON((-20037510 -20037510,-20037510 20037510,20037510 20037510,20037510 -20037510,-20037510 -20037510))
+237|SRID=3857;POLYGON((-22041261 -2003751,-22041261 20037510,2003751 20037510,2003751 -2003751,-22041261 -2003751))
+238|SRID=3857;POLYGON((-15028132.5 -20037510,-15028132.5 -5009377.5,5009377.5 -5009377.5,5009377.5 -20037510,-15028132.5 -20037510))
+239|SRID=3857;POLYGON((0 0,0 0,0 0,0 0,0 0))
+ERROR:  ST_TileEnvelope: Margin must not be less than -50%, margin=-0.510000
+241|SRID=3857;POLYGON((-4007502 -4007502,-4007502 4007502,4007502 4007502,4007502 -4007502,-4007502 -4007502))
+250|SRID=3857;POLYGON((-8296781.484375 4852834.453125,-8296781.484375 4891970.21484375,-8257645.72265625 4891970.21484375,-8257645.72265625 4852834.453125,-8296781.484375 4852834.453125))
+251|SRID=3857;POLYGON((-8300695.06054688 4848920.87695312,-8300695.06054688 4895883.79101562,-8253732.14648438 4895883.79101562,-8253732.14648438 4848920.87695312,-8300695.06054688 4848920.87695312))
+252|SRID=3857;POLYGON((-8316349.36523438 4833266.57226562,-8316349.36523438 4911538.09570312,-8238077.84179688 4911538.09570312,-8238077.84179688 4833266.57226562,-8316349.36523438 4833266.57226562))
+253|SRID=3857;POLYGON((-8375053.0078125 4774562.9296875,-8375053.0078125 4970241.73828125,-8179374.19921875 4970241.73828125,-8179374.19921875 4774562.9296875,-8375053.0078125 4774562.9296875))
+254|SRID=3857;POLYGON((-8285040.75585938 4864575.18164062,-8285040.75585938 4880229.48632812,-8269386.45117188 4880229.48632812,-8269386.45117188 4864575.18164062,-8285040.75585938 4864575.18164062))

-----------------------------------------------------------------------

Summary of changes:
 NEWS                               |  2 ++
 doc/reference_constructor.xml      |  6 +++++-
 doc/reference_output.xml           |  4 ++--
 postgis/lwgeom_functions_basic.c   | 33 +++++++++++++++++++++++++++++----
 postgis/postgis.sql.in             |  5 +++--
 postgis/postgis_before_upgrade.sql |  6 ++++++
 regress/core/regress.sql           | 12 +++++++++++-
 regress/core/regress_expected      | 11 +++++++++++
 8 files changed, 69 insertions(+), 10 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list