/* determine if two rasters intersect */
Datum RASTER_intersects(PG_FUNCTION_ARGS);
+/* determine if two rasters overlap */
+Datum RASTER_overlaps(PG_FUNCTION_ARGS);
+
/* determine if two rasters are aligned */
Datum RASTER_sameAlignment(PG_FUNCTION_ARGS);
int rtn;
int intersects;
- LWPOLY *hull[2] = {NULL};
- GEOSGeometry *ghull[2] = {NULL};
-
for (i = 0, j = 0; i < set_count; i++) {
/* pgrast is null, return null */
if (PG_ARGISNULL(j)) {
PG_RETURN_NULL();
}
- /* raster extents need to intersect */
- do {
- initGEOS(lwnotice, lwgeom_geos_error);
-
- rtn = 1;
- for (i = 0; i < 2; i++) {
- hull[i] = rt_raster_get_convex_hull(rast[i]);
- if (NULL == hull[i]) {
- for (j = 0; j < i; j++) {
- GEOSGeom_destroy(ghull[j]);
- lwpoly_free(hull[j]);
- }
- rtn = 0;
- break;
- }
- ghull[i] = (GEOSGeometry *) LWGEOM2GEOS(lwpoly_as_lwgeom(hull[i]));
- if (NULL == ghull[i]) {
- for (j = 0; j < i; j++) {
- GEOSGeom_destroy(ghull[j]);
- lwpoly_free(hull[j]);
- }
- lwpoly_free(hull[i]);
- rtn = 0;
- break;
- }
- }
- if (!rtn) break;
+ rtn = rt_raster_intersects(
+ rast[0], (hasbandindex[0] ? bandindex[0] - 1 : -1),
+ rast[1], (hasbandindex[1] ? bandindex[1] - 1 : -1),
+ &intersects
+ );
+ for (k = 0; k < set_count; k++) {
+ rt_raster_destroy(rast[k]);
+ PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
+ }
+
+ if (!rtn) {
+ elog(ERROR, "RASTER_intersects: Unable to test for intersection on the two rasters");
+ PG_RETURN_NULL();
+ }
+
+ PG_RETURN_BOOL(intersects);
+}
+
+/**
+ * See if two rasters overlap
+ */
+PG_FUNCTION_INFO_V1(RASTER_overlaps);
+Datum RASTER_overlaps(PG_FUNCTION_ARGS)
+{
+ const int set_count = 2;
+ rt_pgraster *pgrast[2];
+ int pgrastpos[2] = {-1, -1};
+ rt_raster rast[2] = {NULL};
+ uint32_t bandindex[2] = {0};
+ uint32_t hasbandindex[2] = {0};
- rtn = GEOSIntersects(ghull[0], ghull[1]);
+ uint32_t i;
+ uint32_t j;
+ uint32_t k;
+ uint32_t numBands;
+ int rtn;
+ int overlaps;
- for (i = 0; i < 2; i++) {
- GEOSGeom_destroy(ghull[i]);
- lwpoly_free(hull[i]);
+ for (i = 0, j = 0; i < set_count; i++) {
+ /* pgrast is null, return null */
+ if (PG_ARGISNULL(j)) {
+ for (k = 0; k < i; k++) {
+ rt_raster_destroy(rast[k]);
+ PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
+ }
+ PG_RETURN_NULL();
}
+ pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
+ pgrastpos[i] = j;
+ j++;
- if (rtn != 2) {
- if (rtn != 1) {
- for (k = 0; k < set_count; k++) {
+ /* raster */
+ rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
+ if (!rast[i]) {
+ elog(ERROR, "RASTER_overlaps: Could not deserialize the %s raster", i < 1 ? "first" : "second");
+ for (k = 0; k <= i; k++) {
+ if (k < i)
rt_raster_destroy(rast[k]);
- PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
- }
- PG_RETURN_BOOL(0);
+ PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
}
- /* band isn't specified */
- else if (!hasbandindex[0]) {
- for (k = 0; k < set_count; k++) {
+ PG_RETURN_NULL();
+ }
+
+ /* numbands */
+ numBands = rt_raster_get_num_bands(rast[i]);
+ if (numBands < 1) {
+ elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
+ if (i > 0) i++;
+ for (k = 0; k < i; k++) {
+ rt_raster_destroy(rast[k]);
+ PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
+ }
+ PG_RETURN_NULL();
+ }
+
+ /* band index */
+ if (!PG_ARGISNULL(j)) {
+ bandindex[i] = PG_GETARG_INT32(j);
+ if (bandindex[i] < 1 || bandindex[i] > numBands) {
+ elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
+ if (i > 0) i++;
+ for (k = 0; k < i; k++) {
rt_raster_destroy(rast[k]);
PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
}
- PG_RETURN_BOOL(1);
+ PG_RETURN_NULL();
}
+ hasbandindex[i] = 1;
+ }
+ else
+ hasbandindex[i] = 0;
+ POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
+ POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
+ j++;
+ }
+
+ /* hasbandindex must be balanced */
+ if (
+ (hasbandindex[0] && !hasbandindex[1]) ||
+ (!hasbandindex[0] && hasbandindex[1])
+ ) {
+ elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
+ for (k = 0; k < set_count; k++) {
+ rt_raster_destroy(rast[k]);
+ PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
+ }
+ PG_RETURN_NULL();
+ }
+
+ /* SRID must match */
+ if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
+ elog(ERROR, "The two rasters provided have different SRIDs");
+ for (k = 0; k < set_count; k++) {
+ rt_raster_destroy(rast[k]);
+ PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
}
+ PG_RETURN_NULL();
}
- while (0);
- rtn = rt_raster_intersects(
+ rtn = rt_raster_overlaps(
rast[0], (hasbandindex[0] ? bandindex[0] - 1 : -1),
rast[1], (hasbandindex[1] ? bandindex[1] - 1 : -1),
- &intersects
+ &overlaps
);
for (k = 0; k < set_count; k++) {
rt_raster_destroy(rast[k]);
}
if (!rtn) {
- elog(ERROR, "RASTER_intersects: Unable to test for intersection on the two rasters");
+ elog(ERROR, "RASTER_overlaps: Unable to test for overlap on the two rasters");
PG_RETURN_NULL();
}
- PG_RETURN_BOOL(intersects);
+ PG_RETURN_BOOL(overlaps);
}
/**
LANGUAGE 'sql' IMMUTABLE
COST 1000;
+-----------------------------------------------------------------------
+-- ST_Overlaps(raster, raster)
+-----------------------------------------------------------------------
+
+CREATE OR REPLACE FUNCTION _st_overlaps(rast1 raster, nband1 integer, rast2 raster, nband2 integer)
+ RETURNS boolean
+ AS 'MODULE_PATHNAME', 'RASTER_overlaps'
+ LANGUAGE 'c' IMMUTABLE STRICT
+ COST 1000;
+
+CREATE OR REPLACE FUNCTION st_overlaps(rast1 raster, nband1 integer, rast2 raster, nband2 integer)
+ RETURNS boolean
+ AS $$ SELECT $1 && $3 AND CASE WHEN $2 IS NULL OR $4 IS NULL THEN st_overlaps(st_convexhull($1), st_convexhull($3)) ELSE _st_overlaps($1, $2, $3, $4) END $$
+ LANGUAGE 'sql' IMMUTABLE
+ COST 1000;
+
+CREATE OR REPLACE FUNCTION st_overlaps(rast1 raster, rast2 raster)
+ RETURNS boolean
+ AS $$ SELECT st_overlaps($1, NULL::integer, $2, NULL::integer) $$
+ LANGUAGE 'sql' IMMUTABLE
+ COST 1000;
+
+-----------------------------------------------------------------------
+-- ST_Overlaps(raster, geometry) in raster-space
+-----------------------------------------------------------------------
+
+CREATE OR REPLACE FUNCTION _st_overlaps(rast raster, geom geometry, nband integer DEFAULT NULL)
+ RETURNS boolean
+ AS $$
+ DECLARE
+ gr raster;
+ scale double precision;
+ BEGIN
+ IF ST_Overlaps(geom, ST_ConvexHull(rast)) IS NOT TRUE THEN
+ RETURN FALSE;
+ ELSEIF nband IS NULL THEN
+ RETURN TRUE;
+ END IF;
+
+ -- scale is set to 1/100th of raster for granularity
+ SELECT least(scalex, scaley) / 100. INTO scale FROM ST_Metadata(rast);
+ gr := _st_asraster(geom, scale, scale);
+ IF gr IS NULL THEN
+ RAISE EXCEPTION 'Unable to convert geometry to a raster';
+ RETURN FALSE;
+ END IF;
+
+ RETURN ST_Overlaps(rast, nband, gr, 1);
+ END;
+ $$ LANGUAGE 'plpgsql' IMMUTABLE
+ COST 1000;
+
+CREATE OR REPLACE FUNCTION st_overlaps(rast raster, geom geometry, nband integer DEFAULT NULL)
+ RETURNS boolean
+ AS $$ SELECT $1::geometry && $2 AND _st_overlaps($1, $2, $3) $$
+ LANGUAGE 'sql' IMMUTABLE
+ COST 1000;
+
+CREATE OR REPLACE FUNCTION st_overlaps(rast raster, nband integer, geom geometry)
+ RETURNS boolean
+ AS $$ SELECT $1::geometry && $3 AND _st_overlaps($1, $3, $2) $$
+ LANGUAGE 'sql' IMMUTABLE
+ COST 1000;
+
+-----------------------------------------------------------------------
+-- ST_Overlaps(geometry, raster) in geometry-space
+-----------------------------------------------------------------------
+
+-- This function can not be STRICT
+CREATE OR REPLACE FUNCTION _st_overlaps(geom geometry, rast raster, nband integer DEFAULT NULL)
+ RETURNS boolean AS $$
+ DECLARE
+ convexhull geometry;
+ hasnodata boolean := TRUE;
+ surface geometry;
+ BEGIN
+ convexhull := ST_ConvexHull(rast);
+ IF nband IS NOT NULL THEN
+ SELECT CASE WHEN bmd.nodatavalue IS NULL THEN FALSE ELSE NULL END INTO hasnodata FROM ST_BandMetaData(rast, nband) AS bmd;
+ END IF;
+
+ IF ST_Overlaps(geom, convexhull) IS NOT TRUE THEN
+ RETURN FALSE;
+ ELSEIF nband IS NULL OR hasnodata IS FALSE THEN
+ RETURN TRUE;
+ END IF;
+
+ -- get band polygon
+ surface := ST_Polygon(rast, nband);
+
+ IF surface IS NOT NULL THEN
+ RETURN ST_Overlaps(geom, surface);
+ END IF;
+
+ RETURN FALSE;
+ END;
+ $$ LANGUAGE 'plpgsql' IMMUTABLE
+ COST 1000;
+
+-- This function can not be STRICT
+CREATE OR REPLACE FUNCTION st_overlaps(geom geometry, rast raster, nband integer DEFAULT NULL)
+ RETURNS boolean AS
+ $$ SELECT $1 && $2::geometry AND _st_overlaps($1, $2, $3); $$
+ LANGUAGE 'sql' IMMUTABLE
+ COST 1000;
+
-----------------------------------------------------------------------
-- ST_Intersection(geometry, raster) in geometry-space
-----------------------------------------------------------------------
+
CREATE OR REPLACE FUNCTION st_intersection(geomin geometry, rast raster, band integer DEFAULT 1)
RETURNS SETOF geomval AS $$
DECLARE
TEST_SREL = \
rt_spatial_relationship \
rt_intersects \
+ rt_overlaps \
rt_samealignment
TEST_BUGS = \
y int;
rast raster;
BEGIN
- rast := ST_MakeEmptyRaster(width, height, ul_x, ul_y, 1, 1, skew_x, skew_y, 994326);
+ rast := ST_MakeEmptyRaster(width, height, ul_x, ul_y, 1, 1, skew_x, skew_y, 0);
rast := ST_AddBand(rast, 1, '8BUI', 1, 0);
SELECT make_test_raster(2, 3, 3);
DROP FUNCTION make_test_raster(integer, integer, integer, double precision, double precision, double precision, double precision);
-INSERT into spatial_ref_sys (srid, auth_name, auth_srid, proj4text, srtext) values (994326, 'epsg', 4326, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ', 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]');
-
INSERT INTO raster_intersects_rast VALUES (10, (
SELECT
ST_SetValue(rast, 1, 1, 1, 0)
-- point
INSERT INTO raster_intersects_geom VALUES (
1, (
- SELECT ST_SetSRID(ST_MakePoint(0, 0), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(0, 0), 0)
)
), (
2, (
- SELECT ST_SetSRID(ST_MakePoint(0.1, 0.1), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(0.1, 0.1), 0)
)
), (
3, (
- SELECT ST_SetSRID(ST_MakePoint(-0.1, -0.1), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(-0.1, -0.1), 0)
)
), (
4, (
- SELECT ST_SetSRID(ST_MakePoint(-1, -1), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(-1, -1), 0)
)
), (
5, (
- SELECT ST_SetSRID(ST_MakePoint(-1.1, -1), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(-1.1, -1), 0)
)
), (
6, (
- SELECT ST_SetSRID(ST_MakePoint(-1, -1.1), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(-1, -1.1), 0)
)
), (
7, (
- SELECT ST_SetSRID(ST_MakePoint(-1.5, -1.5), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(-1.5, -1.5), 0)
)
), (
8, (
- SELECT ST_SetSRID(ST_MakePoint(3, 3), 994326)
+ SELECT ST_SetSRID(ST_MakePoint(3, 3), 0)
)
);
SELECT ST_SetSRID(ST_MakeLine(ARRAY[
ST_MakePoint(1, 1),
ST_MakePoint(1, 0)
- ]), 994326)
+ ]), 0)
)
), (
22, (
ST_MakePoint(-1, -1),
ST_MakePoint(1, 1),
ST_MakePoint(1, 0)
- ]), 994326)
+ ]), 0)
)
), (
23, (
ST_MakePoint(-1, 1),
ST_MakePoint(1, 1),
ST_MakePoint(1, -1)
- ]), 994326)
+ ]), 0)
)
), (
24, (
ST_MakePoint(1.1, -1.1),
ST_MakePoint(-1.1, -1.1),
ST_MakePoint(-1.1, 1.1)
- ]), 994326)
+ ]), 0)
)
), (
25, (
ST_MakePoint(2, -1),
ST_MakePoint(-1, -2),
ST_MakePoint(-2, 1)
- ]), 994326)
+ ]), 0)
)
), (
26, (
ST_MakePoint(0, 0),
ST_MakePoint(0, -0.5),
ST_MakePoint(-0.5, 0.5)
- ]), 994326)
+ ]), 0)
)
), (
27, (
ST_MakePoint(1, 1),
ST_MakePoint(1, 0),
ST_MakePoint(0.5, 0.5)
- ]), 994326)
+ ]), 0)
)
), (
28, (
ST_MakePoint(0, 2),
ST_MakePoint(1, 2),
ST_MakePoint(1, 1)
- ]), 994326)
+ ]), 0)
)
), (
29, (
ST_MakePoint(1, 2),
ST_MakePoint(1, 4),
ST_MakePoint(0, 2)
- ]), 994326)
+ ]), 0)
)
);
-- multipolygon
INSERT INTO raster_intersects_geom VALUES (
41, (
- SELECT ST_Collect(geom) FROM raster_intersects_geom WHERE gid BETWEEN 31 and 40
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_intersects_geom WHERE gid BETWEEN 31 and 40
)
), (
42, (
- SELECT ST_Collect(geom) FROM raster_intersects_geom WHERE gid BETWEEN 32 and 40
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_intersects_geom WHERE gid BETWEEN 32 and 40
)
), (
43, (
- SELECT ST_Collect(geom) FROM raster_intersects_geom WHERE gid BETWEEN 33 and 40
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_intersects_geom WHERE gid BETWEEN 33 and 40
)
), (
44, (
- SELECT ST_Collect(geom) FROM raster_intersects_geom WHERE gid BETWEEN 34 and 40
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_intersects_geom WHERE gid BETWEEN 34 and 40
)
), (
45, (
- SELECT ST_Collect(geom) FROM raster_intersects_geom WHERE gid BETWEEN 35 and 40
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_intersects_geom WHERE gid BETWEEN 35 and 40
)
), (
46, (
- SELECT ST_Collect(geom) FROM raster_intersects_geom WHERE gid BETWEEN 36 and 40
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_intersects_geom WHERE gid BETWEEN 36 and 40
)
);
ST_GeometryType(g1.geom),
ST_Intersects(r1.rast, g1.geom)
FROM raster_intersects_rast r1
-JOIN raster_intersects_geom g1
- ON 1 = 1
+CROSS JOIN raster_intersects_geom g1
WHERE r1.rid = 0;
SELECT
ST_GeometryType(g1.geom),
ST_Intersects(g1.geom, r1.rast)
FROM raster_intersects_rast r1
-JOIN raster_intersects_geom g1
- ON 1 = 1
+CROSS JOIN raster_intersects_geom g1
WHERE r1.rid = 0;
SELECT
ST_GeometryType(g1.geom),
ST_Intersects(r1.rast, g1.geom)
FROM raster_intersects_rast r1
-JOIN raster_intersects_geom g1
- ON 1 = 1
+CROSS JOIN raster_intersects_geom g1
WHERE r1.rid = 2;
SELECT
ST_GeometryType(g1.geom),
ST_Intersects(g1.geom, r1.rast)
FROM raster_intersects_rast r1
-JOIN raster_intersects_geom g1
- ON 1 = 1
+CROSS JOIN raster_intersects_geom g1
WHERE r1.rid = 2;
SELECT
ST_GeometryType(g1.geom),
ST_Intersects(r1.rast, g1.geom, 1)
FROM raster_intersects_rast r1
-JOIN raster_intersects_geom g1
- ON 1 = 1
+CROSS JOIN raster_intersects_geom g1
WHERE r1.rid = 0;
SELECT
ST_GeometryType(g1.geom),
ST_Intersects(r1.rast, g1.geom, 1)
FROM raster_intersects_rast r1
-JOIN raster_intersects_geom g1
- ON 1 = 1
+CROSS JOIN raster_intersects_geom g1
WHERE r1.rid = 2;
-DELETE FROM spatial_ref_sys WHERE srid = 994326;
-
DROP TABLE IF EXISTS raster_intersects_rast;
DROP TABLE IF EXISTS raster_intersects_geom;
--- /dev/null
+SET client_min_messages TO warning;
+
+DROP TABLE IF EXISTS raster_overlaps_rast;
+DROP TABLE IF EXISTS raster_overlaps_geom;
+CREATE TABLE raster_overlaps_rast (
+ rid integer,
+ rast raster
+);
+CREATE TABLE raster_overlaps_geom (
+ gid integer,
+ geom geometry
+);
+CREATE OR REPLACE FUNCTION make_test_raster(
+ rid integer,
+ width integer DEFAULT 2, height integer DEFAULT 2,
+ ul_x double precision DEFAULT 0, ul_y double precision DEFAULT 0,
+ skew_x double precision DEFAULT 0, skew_y double precision DEFAULT 0
+)
+ RETURNS void
+ AS $$
+ DECLARE
+ x int;
+ y int;
+ rast raster;
+ BEGIN
+ rast := ST_MakeEmptyRaster(width, height, ul_x, ul_y, 1, 1, skew_x, skew_y, 0);
+ rast := ST_AddBand(rast, 1, '8BUI', 1, 0);
+
+
+ INSERT INTO raster_overlaps_rast VALUES (rid, rast);
+
+ RETURN;
+ END;
+ $$ LANGUAGE 'plpgsql';
+SELECT make_test_raster(0, 2, 2, -1, -1);
+SELECT make_test_raster(1, 2, 2);
+SELECT make_test_raster(2, 3, 3);
+DROP FUNCTION make_test_raster(integer, integer, integer, double precision, double precision, double precision, double precision);
+
+INSERT INTO raster_overlaps_rast VALUES (10, (
+ SELECT
+ ST_SetValue(rast, 1, 1, 1, 0)
+ FROM raster_overlaps_rast
+ WHERE rid = 1
+));
+INSERT INTO raster_overlaps_rast VALUES (11, (
+ SELECT
+ ST_SetValue(rast, 1, 2, 1, 0)
+ FROM raster_overlaps_rast
+ WHERE rid = 1
+));
+INSERT INTO raster_overlaps_rast VALUES (12, (
+ SELECT
+ ST_SetValue(
+ ST_SetValue(
+ ST_SetValue(rast, 1, 1, 1, 0),
+ 1, 2, 1, 0
+ ),
+ 1, 1, 2, 0
+ )
+ FROM raster_overlaps_rast
+ WHERE rid = 1
+));
+INSERT INTO raster_overlaps_rast VALUES (13, (
+ SELECT
+ ST_SetValue(
+ ST_SetValue(
+ ST_SetValue(
+ ST_SetValue(rast, 1, 1, 1, 0),
+ 1, 2, 1, 0
+ ),
+ 1, 1, 2, 0
+ ),
+ 1, 2, 2, 0
+ )
+ FROM raster_overlaps_rast
+ WHERE rid = 1
+));
+INSERT INTO raster_overlaps_rast VALUES (14, (
+ SELECT
+ ST_SetUpperLeft(rast, 2, 0)
+ FROM raster_overlaps_rast
+ WHERE rid = 1
+));
+INSERT INTO raster_overlaps_rast VALUES (15, (
+ SELECT
+ ST_SetScale(
+ ST_SetUpperLeft(rast, 0.1, 0.1),
+ 0.4, 0.4
+ )
+ FROM raster_overlaps_rast
+ WHERE rid = 1
+));
+INSERT INTO raster_overlaps_rast VALUES (16, (
+ SELECT
+ ST_SetScale(
+ ST_SetUpperLeft(rast, -0.1, 0.1),
+ 0.4, 0.4
+ )
+ FROM raster_overlaps_rast
+ WHERE rid = 1
+));
+
+INSERT INTO raster_overlaps_rast VALUES (20, (
+ SELECT
+ ST_SetUpperLeft(rast, -2, -2)
+ FROM raster_overlaps_rast
+ WHERE rid = 2
+));
+INSERT INTO raster_overlaps_rast VALUES (21, (
+ SELECT
+ ST_SetValue(
+ ST_SetValue(
+ ST_SetValue(rast, 1, 1, 1, 0),
+ 1, 2, 2, 0
+ ),
+ 1, 3, 3, 0
+ )
+ FROM raster_overlaps_rast
+ WHERE rid = 20
+));
+INSERT INTO raster_overlaps_rast VALUES (22, (
+ SELECT
+ ST_SetValue(
+ ST_SetValue(
+ rast, 1, 3, 2, 0
+ ),
+ 1, 2, 3, 0
+ )
+ FROM raster_overlaps_rast
+ WHERE rid = 21
+));
+INSERT INTO raster_overlaps_rast VALUES (23, (
+ SELECT
+ ST_SetValue(
+ ST_SetValue(
+ rast, 1, 3, 1, 0
+ ),
+ 1, 1, 3, 0
+ )
+ FROM raster_overlaps_rast
+ WHERE rid = 22
+));
+
+INSERT INTO raster_overlaps_rast VALUES (30, (
+ SELECT
+ ST_SetSkew(rast, -0.5, 0.5)
+ FROM raster_overlaps_rast
+ WHERE rid = 2
+));
+INSERT INTO raster_overlaps_rast VALUES (31, (
+ SELECT
+ ST_SetSkew(rast, -1, 1)
+ FROM raster_overlaps_rast
+ WHERE rid = 2
+));
+INSERT INTO raster_overlaps_rast VALUES (32, (
+ SELECT
+ ST_SetSkew(rast, 1, -1)
+ FROM raster_overlaps_rast
+ WHERE rid = 2
+));
+
+SELECT
+ '1.1',
+ r1.rid,
+ r2.rid,
+ ST_Overlaps(r1.rast, NULL, r2.rast, NULL)
+FROM raster_overlaps_rast r1
+JOIN raster_overlaps_rast r2
+ ON r1.rid != r2.rid
+WHERE r1.rid = 0;
+
+SELECT
+ '1.2',
+ r1.rid,
+ r2.rid,
+ ST_Overlaps(r1.rast, 1, r2.rast, 1)
+FROM raster_overlaps_rast r1
+JOIN raster_overlaps_rast r2
+ ON r1.rid != r2.rid
+WHERE r1.rid = 0;
+
+-- point
+INSERT INTO raster_overlaps_geom VALUES (
+ 1, (
+ SELECT ST_SetSRID(ST_MakePoint(0, 0), 0)
+ )
+), (
+ 2, (
+ SELECT ST_SetSRID(ST_MakePoint(0.1, 0.1), 0)
+ )
+), (
+ 3, (
+ SELECT ST_SetSRID(ST_MakePoint(-0.1, -0.1), 0)
+ )
+), (
+ 4, (
+ SELECT ST_SetSRID(ST_MakePoint(-1, -1), 0)
+ )
+), (
+ 5, (
+ SELECT ST_SetSRID(ST_MakePoint(-1.1, -1), 0)
+ )
+), (
+ 6, (
+ SELECT ST_SetSRID(ST_MakePoint(-1, -1.1), 0)
+ )
+), (
+ 7, (
+ SELECT ST_SetSRID(ST_MakePoint(-1.5, -1.5), 0)
+ )
+), (
+ 8, (
+ SELECT ST_SetSRID(ST_MakePoint(3, 3), 0)
+ )
+);
+
+-- multipoint
+INSERT INTO raster_overlaps_geom VALUES (
+ 11, (
+ SELECT ST_Collect(geom) FROM raster_overlaps_geom WHERE gid BETWEEN 1 AND 10
+ )
+), (
+ 12, (
+ SELECT ST_Collect(geom) FROM raster_overlaps_geom WHERE gid BETWEEN 3 AND 10
+ )
+), (
+ 13, (
+ SELECT ST_Collect(geom) FROM raster_overlaps_geom WHERE gid BETWEEN 4 AND 10
+ )
+), (
+ 14, (
+ SELECT ST_Collect(geom) FROM raster_overlaps_geom WHERE gid BETWEEN 5 AND 10
+ )
+), (
+ 15, (
+ SELECT ST_Collect(geom) FROM raster_overlaps_geom WHERE gid BETWEEN 6 AND 10
+ )
+);
+
+-- linestring
+INSERT INTO raster_overlaps_geom VALUES (
+ 21, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(1, 1),
+ ST_MakePoint(1, 0)
+ ]), 0)
+ )
+), (
+ 22, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(-1, -1),
+ ST_MakePoint(1, 1),
+ ST_MakePoint(1, 0)
+ ]), 0)
+ )
+), (
+ 23, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(-1, -1),
+ ST_MakePoint(-1, 1),
+ ST_MakePoint(1, 1),
+ ST_MakePoint(1, -1)
+ ]), 0)
+ )
+), (
+ 24, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(-1.1, 1.1),
+ ST_MakePoint(1.1, 1.1),
+ ST_MakePoint(1.1, -1.1),
+ ST_MakePoint(-1.1, -1.1),
+ ST_MakePoint(-1.1, 1.1)
+ ]), 0)
+ )
+), (
+ 25, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(-2, 1),
+ ST_MakePoint(1, 2),
+ ST_MakePoint(2, -1),
+ ST_MakePoint(-1, -2),
+ ST_MakePoint(-2, 1)
+ ]), 0)
+ )
+), (
+ 26, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(-0.5, 0.5),
+ ST_MakePoint(0, 0.5),
+ ST_MakePoint(0, 0),
+ ST_MakePoint(0, -0.5),
+ ST_MakePoint(-0.5, 0.5)
+ ]), 0)
+ )
+), (
+ 27, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(0.5, 0.5),
+ ST_MakePoint(1, 1),
+ ST_MakePoint(1, 0),
+ ST_MakePoint(0.5, 0.5)
+ ]), 0)
+ )
+), (
+ 28, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(1, 1),
+ ST_MakePoint(0, 2),
+ ST_MakePoint(1, 2),
+ ST_MakePoint(1, 1)
+ ]), 0)
+ )
+), (
+ 29, (
+ SELECT ST_SetSRID(ST_MakeLine(ARRAY[
+ ST_MakePoint(0, 2),
+ ST_MakePoint(1, 2),
+ ST_MakePoint(1, 4),
+ ST_MakePoint(0, 2)
+ ]), 0)
+ )
+);
+
+-- polygon
+INSERT INTO raster_overlaps_geom VALUES (
+ 31, (
+ SELECT ST_MakePolygon(geom) FROM raster_overlaps_geom WHERE gid = 24
+ )
+), (
+ 32, (
+ SELECT ST_MakePolygon(geom) FROM raster_overlaps_geom WHERE gid = 25
+ )
+), (
+ 33, (
+ SELECT ST_MakePolygon(geom) FROM raster_overlaps_geom WHERE gid = 26
+ )
+), (
+ 34, (
+ SELECT ST_MakePolygon(geom) FROM raster_overlaps_geom WHERE gid = 27
+ )
+), (
+ 35, (
+ SELECT ST_MakePolygon(geom) FROM raster_overlaps_geom WHERE gid = 28
+ )
+), (
+ 36, (
+ SELECT ST_MakePolygon(geom) FROM raster_overlaps_geom WHERE gid = 29
+ )
+);
+
+-- multipolygon
+INSERT INTO raster_overlaps_geom VALUES (
+ 41, (
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_overlaps_geom WHERE gid BETWEEN 31 and 40
+ )
+), (
+ 42, (
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_overlaps_geom WHERE gid BETWEEN 32 and 40
+ )
+), (
+ 43, (
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_overlaps_geom WHERE gid BETWEEN 33 and 40
+ )
+), (
+ 44, (
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_overlaps_geom WHERE gid BETWEEN 34 and 40
+ )
+), (
+ 45, (
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_overlaps_geom WHERE gid BETWEEN 35 and 40
+ )
+), (
+ 46, (
+ SELECT ST_Multi(ST_Union(geom)) FROM raster_overlaps_geom WHERE gid BETWEEN 36 and 40
+ )
+);
+
+SELECT
+ '2.1',
+ r1.rid,
+ g1.gid,
+ ST_GeometryType(g1.geom),
+ ST_Overlaps(r1.rast, g1.geom)
+FROM raster_overlaps_rast r1
+CROSS JOIN raster_overlaps_geom g1
+WHERE r1.rid = 0;
+
+SELECT
+ '2.2',
+ r1.rid,
+ g1.gid,
+ ST_GeometryType(g1.geom),
+ ST_Overlaps(g1.geom, r1.rast)
+FROM raster_overlaps_rast r1
+CROSS JOIN raster_overlaps_geom g1
+WHERE r1.rid = 0;
+
+SELECT
+ '2.3',
+ r1.rid,
+ g1.gid,
+ ST_GeometryType(g1.geom),
+ ST_Overlaps(r1.rast, g1.geom)
+FROM raster_overlaps_rast r1
+CROSS JOIN raster_overlaps_geom g1
+WHERE r1.rid = 2;
+
+SELECT
+ '2.4',
+ r1.rid,
+ g1.gid,
+ ST_GeometryType(g1.geom),
+ ST_Overlaps(g1.geom, r1.rast)
+FROM raster_overlaps_rast r1
+CROSS JOIN raster_overlaps_geom g1
+WHERE r1.rid = 2;
+
+SELECT
+ '2.5',
+ r1.rid,
+ g1.gid,
+ ST_GeometryType(g1.geom),
+ ST_Overlaps(r1.rast, g1.geom, 1)
+FROM raster_overlaps_rast r1
+CROSS JOIN raster_overlaps_geom g1
+WHERE r1.rid = 0;
+
+SELECT
+ '2.6',
+ r1.rid,
+ g1.gid,
+ ST_GeometryType(g1.geom),
+ ST_Overlaps(r1.rast, g1.geom, 1)
+FROM raster_overlaps_rast r1
+CROSS JOIN raster_overlaps_geom g1
+WHERE r1.rid = 2;
+
+DROP TABLE IF EXISTS raster_overlaps_rast;
+DROP TABLE IF EXISTS raster_overlaps_geom;
--- /dev/null
+1.1|0|1|t
+1.1|0|2|t
+1.1|0|10|t
+1.1|0|11|t
+1.1|0|12|t
+1.1|0|13|t
+1.1|0|14|f
+1.1|0|15|f
+1.1|0|16|f
+1.1|0|20|f
+1.1|0|21|f
+1.1|0|22|f
+1.1|0|23|f
+1.1|0|30|t
+1.1|0|31|t
+1.1|0|32|t
+1.2|0|1|t
+1.2|0|2|t
+1.2|0|10|f
+1.2|0|11|t
+1.2|0|12|f
+1.2|0|13|f
+1.2|0|14|f
+1.2|0|15|f
+1.2|0|16|f
+1.2|0|20|f
+1.2|0|21|t
+1.2|0|22|f
+1.2|0|23|f
+1.2|0|30|t
+1.2|0|31|t
+1.2|0|32|t
+2.1|0|1|ST_Point|f
+2.1|0|2|ST_Point|f
+2.1|0|3|ST_Point|f
+2.1|0|4|ST_Point|f
+2.1|0|5|ST_Point|f
+2.1|0|6|ST_Point|f
+2.1|0|7|ST_Point|f
+2.1|0|8|ST_Point|f
+2.1|0|11|ST_MultiPoint|f
+2.1|0|12|ST_MultiPoint|f
+2.1|0|13|ST_MultiPoint|f
+2.1|0|14|ST_MultiPoint|f
+2.1|0|15|ST_MultiPoint|f
+2.1|0|21|ST_LineString|f
+2.1|0|22|ST_LineString|f
+2.1|0|23|ST_LineString|f
+2.1|0|24|ST_LineString|f
+2.1|0|25|ST_LineString|f
+2.1|0|26|ST_LineString|f
+2.1|0|27|ST_LineString|f
+2.1|0|28|ST_LineString|f
+2.1|0|29|ST_LineString|f
+2.1|0|31|ST_Polygon|f
+2.1|0|32|ST_Polygon|f
+2.1|0|33|ST_Polygon|f
+2.1|0|34|ST_Polygon|f
+2.1|0|35|ST_Polygon|f
+2.1|0|36|ST_Polygon|f
+2.1|0|41|ST_MultiPolygon|f
+2.1|0|42|ST_MultiPolygon|f
+2.1|0|43|ST_MultiPolygon|t
+2.1|0|44|ST_MultiPolygon|t
+2.1|0|45|ST_MultiPolygon|f
+2.1|0|46|ST_MultiPolygon|f
+2.2|0|1|ST_Point|f
+2.2|0|2|ST_Point|f
+2.2|0|3|ST_Point|f
+2.2|0|4|ST_Point|f
+2.2|0|5|ST_Point|f
+2.2|0|6|ST_Point|f
+2.2|0|7|ST_Point|f
+2.2|0|8|ST_Point|f
+2.2|0|11|ST_MultiPoint|f
+2.2|0|12|ST_MultiPoint|f
+2.2|0|13|ST_MultiPoint|f
+2.2|0|14|ST_MultiPoint|f
+2.2|0|15|ST_MultiPoint|f
+2.2|0|21|ST_LineString|f
+2.2|0|22|ST_LineString|f
+2.2|0|23|ST_LineString|f
+2.2|0|24|ST_LineString|f
+2.2|0|25|ST_LineString|f
+2.2|0|26|ST_LineString|f
+2.2|0|27|ST_LineString|f
+2.2|0|28|ST_LineString|f
+2.2|0|29|ST_LineString|f
+2.2|0|31|ST_Polygon|f
+2.2|0|32|ST_Polygon|f
+2.2|0|33|ST_Polygon|f
+2.2|0|34|ST_Polygon|f
+2.2|0|35|ST_Polygon|f
+2.2|0|36|ST_Polygon|f
+2.2|0|41|ST_MultiPolygon|f
+2.2|0|42|ST_MultiPolygon|f
+2.2|0|43|ST_MultiPolygon|t
+2.2|0|44|ST_MultiPolygon|t
+2.2|0|45|ST_MultiPolygon|f
+2.2|0|46|ST_MultiPolygon|f
+2.3|2|1|ST_Point|f
+2.3|2|2|ST_Point|f
+2.3|2|3|ST_Point|f
+2.3|2|4|ST_Point|f
+2.3|2|5|ST_Point|f
+2.3|2|6|ST_Point|f
+2.3|2|7|ST_Point|f
+2.3|2|8|ST_Point|f
+2.3|2|11|ST_MultiPoint|f
+2.3|2|12|ST_MultiPoint|f
+2.3|2|13|ST_MultiPoint|f
+2.3|2|14|ST_MultiPoint|f
+2.3|2|15|ST_MultiPoint|f
+2.3|2|21|ST_LineString|f
+2.3|2|22|ST_LineString|f
+2.3|2|23|ST_LineString|f
+2.3|2|24|ST_LineString|f
+2.3|2|25|ST_LineString|f
+2.3|2|26|ST_LineString|f
+2.3|2|27|ST_LineString|f
+2.3|2|28|ST_LineString|f
+2.3|2|29|ST_LineString|f
+2.3|2|31|ST_Polygon|t
+2.3|2|32|ST_Polygon|t
+2.3|2|33|ST_Polygon|f
+2.3|2|34|ST_Polygon|f
+2.3|2|35|ST_Polygon|f
+2.3|2|36|ST_Polygon|t
+2.3|2|41|ST_MultiPolygon|t
+2.3|2|42|ST_MultiPolygon|t
+2.3|2|43|ST_MultiPolygon|t
+2.3|2|44|ST_MultiPolygon|t
+2.3|2|45|ST_MultiPolygon|t
+2.3|2|46|ST_MultiPolygon|t
+2.4|2|1|ST_Point|f
+2.4|2|2|ST_Point|f
+2.4|2|3|ST_Point|f
+2.4|2|4|ST_Point|f
+2.4|2|5|ST_Point|f
+2.4|2|6|ST_Point|f
+2.4|2|7|ST_Point|f
+2.4|2|8|ST_Point|f
+2.4|2|11|ST_MultiPoint|f
+2.4|2|12|ST_MultiPoint|f
+2.4|2|13|ST_MultiPoint|f
+2.4|2|14|ST_MultiPoint|f
+2.4|2|15|ST_MultiPoint|f
+2.4|2|21|ST_LineString|f
+2.4|2|22|ST_LineString|f
+2.4|2|23|ST_LineString|f
+2.4|2|24|ST_LineString|f
+2.4|2|25|ST_LineString|f
+2.4|2|26|ST_LineString|f
+2.4|2|27|ST_LineString|f
+2.4|2|28|ST_LineString|f
+2.4|2|29|ST_LineString|f
+2.4|2|31|ST_Polygon|t
+2.4|2|32|ST_Polygon|t
+2.4|2|33|ST_Polygon|f
+2.4|2|34|ST_Polygon|f
+2.4|2|35|ST_Polygon|f
+2.4|2|36|ST_Polygon|t
+2.4|2|41|ST_MultiPolygon|t
+2.4|2|42|ST_MultiPolygon|t
+2.4|2|43|ST_MultiPolygon|t
+2.4|2|44|ST_MultiPolygon|t
+2.4|2|45|ST_MultiPolygon|t
+2.4|2|46|ST_MultiPolygon|t
+2.5|0|1|ST_Point|f
+2.5|0|2|ST_Point|f
+2.5|0|3|ST_Point|f
+2.5|0|4|ST_Point|f
+2.5|0|5|ST_Point|f
+2.5|0|6|ST_Point|f
+2.5|0|7|ST_Point|f
+2.5|0|8|ST_Point|f
+2.5|0|11|ST_MultiPoint|f
+2.5|0|12|ST_MultiPoint|f
+2.5|0|13|ST_MultiPoint|f
+2.5|0|14|ST_MultiPoint|f
+2.5|0|15|ST_MultiPoint|f
+2.5|0|21|ST_LineString|f
+2.5|0|22|ST_LineString|f
+2.5|0|23|ST_LineString|f
+2.5|0|24|ST_LineString|f
+2.5|0|25|ST_LineString|f
+2.5|0|26|ST_LineString|f
+2.5|0|27|ST_LineString|f
+2.5|0|28|ST_LineString|f
+2.5|0|29|ST_LineString|f
+2.5|0|31|ST_Polygon|f
+2.5|0|32|ST_Polygon|f
+2.5|0|33|ST_Polygon|f
+2.5|0|34|ST_Polygon|f
+2.5|0|35|ST_Polygon|f
+2.5|0|36|ST_Polygon|f
+2.5|0|41|ST_MultiPolygon|f
+2.5|0|42|ST_MultiPolygon|f
+2.5|0|43|ST_MultiPolygon|t
+2.5|0|44|ST_MultiPolygon|t
+2.5|0|45|ST_MultiPolygon|f
+2.5|0|46|ST_MultiPolygon|f
+2.6|2|1|ST_Point|f
+2.6|2|2|ST_Point|f
+2.6|2|3|ST_Point|f
+2.6|2|4|ST_Point|f
+2.6|2|5|ST_Point|f
+2.6|2|6|ST_Point|f
+2.6|2|7|ST_Point|f
+2.6|2|8|ST_Point|f
+2.6|2|11|ST_MultiPoint|f
+2.6|2|12|ST_MultiPoint|f
+2.6|2|13|ST_MultiPoint|f
+2.6|2|14|ST_MultiPoint|f
+2.6|2|15|ST_MultiPoint|f
+2.6|2|21|ST_LineString|f
+2.6|2|22|ST_LineString|f
+2.6|2|23|ST_LineString|f
+2.6|2|24|ST_LineString|f
+2.6|2|25|ST_LineString|f
+2.6|2|26|ST_LineString|f
+2.6|2|27|ST_LineString|f
+2.6|2|28|ST_LineString|f
+2.6|2|29|ST_LineString|f
+2.6|2|31|ST_Polygon|t
+2.6|2|32|ST_Polygon|t
+2.6|2|33|ST_Polygon|f
+2.6|2|34|ST_Polygon|f
+2.6|2|35|ST_Polygon|f
+2.6|2|36|ST_Polygon|t
+2.6|2|41|ST_MultiPolygon|t
+2.6|2|42|ST_MultiPolygon|t
+2.6|2|43|ST_MultiPolygon|t
+2.6|2|44|ST_MultiPolygon|t
+2.6|2|45|ST_MultiPolygon|t
+2.6|2|46|ST_MultiPolygon|t