PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ ST_TileEnvelope()

Datum ST_TileEnvelope ( PG_FUNCTION_ARGS  )

Definition at line 2039 of file lwgeom_functions_basic.c.

2040 {
2041  GSERIALIZED *bounds;
2042  uint32_t zoomu;
2043  int32_t x, y, zoom;
2044  uint32_t worldTileSize;
2045  double tileGeoSizeX, tileGeoSizeY;
2046  double boundsWidth, boundsHeight;
2047  double x1, y1, x2, y2;
2048  /* This is broken, since 3857 doesn't mean "web mercator", it means
2049  the contents of the row in spatial_ref_sys with srid = 3857.
2050  For practical purposes this will work, but in good implementation
2051  we should de-reference in spatial ref sys to confirm that the
2052  srid of the object is EPSG:3857. */
2053  int32_t srid;
2054  GBOX bbox;
2055  LWGEOM *g = NULL;
2056 
2057  POSTGIS_DEBUG(2, "ST_TileEnvelope called");
2058 
2059  zoom = PG_GETARG_INT32(0);
2060  x = PG_GETARG_INT32(1);
2061  y = PG_GETARG_INT32(2);
2062 
2063  bounds = PG_GETARG_GSERIALIZED_P(3);
2064  /*
2065  * We deserialize the geometry and recalculate the bounding box here to get
2066  * 64b floating point precision. The serialized bbox has 32b float is not
2067  * precise enough with big numbers such as the ones used in the default
2068  * parameters, e.g: -20037508.3427892 is transformed into -20037510
2069  */
2070  g = lwgeom_from_gserialized(bounds);
2071  if (lwgeom_calculate_gbox(g, &bbox) != LW_SUCCESS)
2072  elog(ERROR, "%s: Unable to compute bbox", __func__);
2073  srid = g->srid;
2074  lwgeom_free(g);
2075 
2076  boundsWidth = bbox.xmax - bbox.xmin;
2077  boundsHeight = bbox.ymax - bbox.ymin;
2078  if (boundsWidth <= 0 || boundsHeight <= 0)
2079  elog(ERROR, "%s: Geometric bounds are too small", __func__);
2080 
2081  if (zoom < 0 || zoom >= 32)
2082  elog(ERROR, "%s: Invalid tile zoom value, %d", __func__, zoom);
2083 
2084  zoomu = (uint32_t)zoom;
2085  worldTileSize = 0x01u << (zoomu > 31 ? 31 : zoomu);
2086 
2087  if (x < 0 || (uint32_t)x >= worldTileSize)
2088  elog(ERROR, "%s: Invalid tile x value, %d", __func__, x);
2089  if (y < 0 || (uint32_t)y >= worldTileSize)
2090  elog(ERROR, "%s: Invalid tile y value, %d", __func__, y);
2091 
2092  tileGeoSizeX = boundsWidth / worldTileSize;
2093  tileGeoSizeY = boundsHeight / worldTileSize;
2094  x1 = bbox.xmin + tileGeoSizeX * (x);
2095  x2 = bbox.xmin + tileGeoSizeX * (x+1);
2096  y1 = bbox.ymax - tileGeoSizeY * (y+1);
2097  y2 = bbox.ymax - tileGeoSizeY * (y);
2098 
2099  PG_RETURN_POINTER(
2103  srid, x1, y1, x2, y2))));
2104 }
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1138
#define LW_SUCCESS
Definition: liblwgeom.h:111
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:311
LWPOLY * lwpoly_construct_envelope(int32_t srid, double x1, double y1, double x2, double y2)
Definition: lwpoly.c:98
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
Definition: lwgeom.c:737
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double ymax
Definition: liblwgeom.h:343
double xmax
Definition: liblwgeom.h:341
double ymin
Definition: liblwgeom.h:342
double xmin
Definition: liblwgeom.h:340
int32_t srid
Definition: liblwgeom.h:446

References geometry_serialize(), LW_SUCCESS, lwgeom_calculate_gbox(), lwgeom_free(), lwgeom_from_gserialized(), lwpoly_as_lwgeom(), lwpoly_construct_envelope(), LWGEOM::srid, pixval::x, GBOX::xmax, GBOX::xmin, pixval::y, GBOX::ymax, and GBOX::ymin.

Here is the call graph for this function: