2065{
2067 uint32_t zoomu;
2069 uint32_t worldTileSize;
2070 double tileGeoSizeX, tileGeoSizeY;
2071 double boundsWidth, boundsHeight;
2072 double x1, y1, x2, y2;
2073 double margin;
2074
2075
2076
2077
2078
2079 int32_t srid;
2082
2083 POSTGIS_DEBUG(2, "ST_TileEnvelope called");
2084
2085 zoom = PG_GETARG_INT32(0);
2086 x = PG_GETARG_INT32(1);
2087 y = PG_GETARG_INT32(2);
2088
2089 bounds = PG_GETARG_GSERIALIZED_P(3);
2090
2091
2092
2093
2094
2095
2098 elog(ERROR, "%s: Unable to compute bbox", __func__);
2101
2102
2103 margin = PG_NARGS() < 4 ? 0 : PG_GETARG_FLOAT8(4);
2104
2105 if (margin < -0.5)
2106 elog(ERROR, "%s: Margin must not be less than -50%%, margin=%f", __func__, margin);
2107
2108 boundsWidth = bbox.
xmax - bbox.
xmin;
2109 boundsHeight = bbox.
ymax - bbox.
ymin;
2110 if (boundsWidth <= 0 || boundsHeight <= 0)
2111 elog(ERROR, "%s: Geometric bounds are too small", __func__);
2112
2113 if (zoom < 0 || zoom >= 32)
2114 elog(ERROR, "%s: Invalid tile zoom value, %d", __func__, zoom);
2115
2116 zoomu = (uint32_t)zoom;
2117 worldTileSize = 0x01u << (zoomu > 31 ? 31 : zoomu);
2118
2119 if (x < 0 || (uint32_t)
x >= worldTileSize)
2120 elog(ERROR, "%s: Invalid tile x value, %d", __func__, x);
2121 if (y < 0 || (uint32_t)
y >= worldTileSize)
2122 elog(ERROR, "%s: Invalid tile y value, %d", __func__, y);
2123
2124 tileGeoSizeX = boundsWidth / worldTileSize;
2125 tileGeoSizeY = boundsHeight / worldTileSize;
2126
2127
2128
2129
2130
2131
2132 if ((1 + margin * 2) > worldTileSize)
2133 {
2136 }
2137 else
2138 {
2139 x1 = bbox.
xmin + tileGeoSizeX * (
x - margin);
2140 x2 = bbox.
xmin + tileGeoSizeX * (
x + 1 + margin);
2141 }
2142
2143 y1 = bbox.
ymax - tileGeoSizeY * (
y + 1 + margin);
2144 y2 = bbox.
ymax - tileGeoSizeY * (
y - margin);
2145
2146
2147 if (y1 < bbox.
ymin) y1 = bbox.
ymin;
2148 if (y2 > bbox.
ymax) y2 = bbox.
ymax;
2149 if (x1 < bbox.
xmin) x1 = bbox.
xmin;
2150 if (x2 > bbox.
xmax) x2 = bbox.
xmax;
2151
2152 PG_RETURN_POINTER(
2153 geometry_serialize(
2156 srid, x1, y1, x2, y2))));
2157}
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
LWPOLY * lwpoly_construct_envelope(int32_t srid, double x1, double y1, double x2, double y2)
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...
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)