From: Bborie Park Date: Thu, 19 Jul 2012 18:18:24 +0000 (+0000) Subject: Added ST_Overlaps() and associated regression tests X-Git-Tag: 2.1.0beta2~786 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6447ae42aa5d1ce07a54de74715ee617489a17e8;p=postgis Added ST_Overlaps() and associated regression tests git-svn-id: http://svn.osgeo.org/postgis/trunk@10074 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/raster/rt_pg/rt_pg.c b/raster/rt_pg/rt_pg.c index 0bb727d8e..5274e2375 100644 --- a/raster/rt_pg/rt_pg.c +++ b/raster/rt_pg/rt_pg.c @@ -270,6 +270,9 @@ Datum RASTER_worldToRasterCoord(PG_FUNCTION_ARGS); /* 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); @@ -9876,9 +9879,6 @@ Datum RASTER_intersects(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)) { @@ -9960,65 +9960,129 @@ Datum RASTER_intersects(PG_FUNCTION_ARGS) 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]); @@ -10026,11 +10090,11 @@ Datum RASTER_intersects(PG_FUNCTION_ARGS) } 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); } /** diff --git a/raster/rt_pg/rtpostgis.sql.in.c b/raster/rt_pg/rtpostgis.sql.in.c index a2fb3e55c..a4e36434a 100644 --- a/raster/rt_pg/rtpostgis.sql.in.c +++ b/raster/rt_pg/rtpostgis.sql.in.c @@ -3218,9 +3218,116 @@ CREATE OR REPLACE FUNCTION st_intersects(geom geometry, rast raster, nband integ 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 diff --git a/raster/test/regress/Makefile.in b/raster/test/regress/Makefile.in index a8c3a98a3..a9880e1d0 100644 --- a/raster/test/regress/Makefile.in +++ b/raster/test/regress/Makefile.in @@ -126,6 +126,7 @@ TEST_GIST = \ TEST_SREL = \ rt_spatial_relationship \ rt_intersects \ + rt_overlaps \ rt_samealignment TEST_BUGS = \ diff --git a/raster/test/regress/rt_intersects.sql b/raster/test/regress/rt_intersects.sql index 1f4a15a88..c3d6525b2 100644 --- a/raster/test/regress/rt_intersects.sql +++ b/raster/test/regress/rt_intersects.sql @@ -16,7 +16,7 @@ CREATE OR REPLACE FUNCTION make_test_raster(rid integer, width integer DEFAULT 2 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); @@ -30,8 +30,6 @@ 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 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) @@ -179,35 +177,35 @@ WHERE r1.rid = 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) ) ); @@ -240,7 +238,7 @@ INSERT INTO raster_intersects_geom VALUES ( SELECT ST_SetSRID(ST_MakeLine(ARRAY[ ST_MakePoint(1, 1), ST_MakePoint(1, 0) - ]), 994326) + ]), 0) ) ), ( 22, ( @@ -248,7 +246,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(-1, -1), ST_MakePoint(1, 1), ST_MakePoint(1, 0) - ]), 994326) + ]), 0) ) ), ( 23, ( @@ -257,7 +255,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(-1, 1), ST_MakePoint(1, 1), ST_MakePoint(1, -1) - ]), 994326) + ]), 0) ) ), ( 24, ( @@ -267,7 +265,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(1.1, -1.1), ST_MakePoint(-1.1, -1.1), ST_MakePoint(-1.1, 1.1) - ]), 994326) + ]), 0) ) ), ( 25, ( @@ -277,7 +275,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(2, -1), ST_MakePoint(-1, -2), ST_MakePoint(-2, 1) - ]), 994326) + ]), 0) ) ), ( 26, ( @@ -287,7 +285,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(0, 0), ST_MakePoint(0, -0.5), ST_MakePoint(-0.5, 0.5) - ]), 994326) + ]), 0) ) ), ( 27, ( @@ -296,7 +294,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(1, 1), ST_MakePoint(1, 0), ST_MakePoint(0.5, 0.5) - ]), 994326) + ]), 0) ) ), ( 28, ( @@ -305,7 +303,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(0, 2), ST_MakePoint(1, 2), ST_MakePoint(1, 1) - ]), 994326) + ]), 0) ) ), ( 29, ( @@ -314,7 +312,7 @@ INSERT INTO raster_intersects_geom VALUES ( ST_MakePoint(1, 2), ST_MakePoint(1, 4), ST_MakePoint(0, 2) - ]), 994326) + ]), 0) ) ); @@ -348,27 +346,27 @@ INSERT INTO raster_intersects_geom VALUES ( -- 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 ) ); @@ -379,8 +377,7 @@ 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 = 0; SELECT @@ -390,8 +387,7 @@ 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 @@ -401,8 +397,7 @@ 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 @@ -412,8 +407,7 @@ 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 @@ -423,8 +417,7 @@ 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 @@ -434,11 +427,8 @@ 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; diff --git a/raster/test/regress/rt_overlaps.sql b/raster/test/regress/rt_overlaps.sql new file mode 100644 index 000000000..de220e39e --- /dev/null +++ b/raster/test/regress/rt_overlaps.sql @@ -0,0 +1,441 @@ +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; diff --git a/raster/test/regress/rt_overlaps_expected b/raster/test/regress/rt_overlaps_expected new file mode 100644 index 000000000..b75d6dfff --- /dev/null +++ b/raster/test/regress/rt_overlaps_expected @@ -0,0 +1,236 @@ +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