Return zero if error occurred in function.
Return ES_ERROR if error occurred in function.
992 {
993 int i;
995
997 GEOSGeometry *ghull[2] = {NULL};
998
999 uint16_t width1;
1000 uint16_t height1;
1001 uint16_t width2;
1002 uint16_t height2;
1003 double area1;
1004 double area2;
1005 double pixarea1;
1006 double pixarea2;
1009 uint16_t *widthS = NULL;
1010 uint16_t *heightS = NULL;
1011 uint16_t *widthL = NULL;
1012 uint16_t *heightL = NULL;
1013 int nbandS;
1014 int nbandL;
1017 int hasnodataS =
FALSE;
1018 int hasnodataL =
FALSE;
1019 double nodataS = 0;
1020 double nodataL = 0;
1021 int isnodataS = 0;
1022 int isnodataL = 0;
1023 double gtS[6] = {0};
1024 double igtL[6] = {0};
1025
1026 uint32_t row;
1027 uint32_t rowoffset;
1028 uint32_t col;
1029 uint32_t coloffset;
1030
1031 enum line_points {X1, Y1, X2, Y2};
1032 enum point {pX, pY};
1033 double lineS[4];
1034 double Qr[2];
1035 double valS;
1036 double valL;
1037
1039
1040 assert(NULL != rast1);
1041 assert(NULL != rast2);
1042 assert(NULL != intersects);
1043
1044 if (nband1 < 0 && nband2 < 0) {
1045 nband1 = -1;
1046 nband2 = -1;
1047 }
1048 else {
1051 }
1052
1053
1055 rterror(
"rt_raster_intersects: The two rasters provided have different SRIDs");
1056 *intersects = 0;
1058 }
1059
1060
1061 do {
1062 int rtn;
1063
1065
1066 rtn = 1;
1067
1069 break;
1070 }
1071 ghull[0] = (GEOSGeometry *)
LWGEOM2GEOS(hull[0], 0);
1072 if (!ghull[0]) {
1074 break;
1075 }
1076
1078 GEOSGeom_destroy(ghull[0]);
1080 break;
1081 }
1082 ghull[1] = (GEOSGeometry *)
LWGEOM2GEOS(hull[1], 0);
1083 if (!ghull[0]) {
1084 GEOSGeom_destroy(ghull[0]);
1087 break;
1088 }
1089
1090
1092 if (GEOSWithin(ghull[0], ghull[1]) == 1)
1094 else if (GEOSWithin(ghull[1], ghull[0]) == 1)
1096
1098 rtn = 1;
1099 else
1100 rtn = GEOSIntersects(ghull[0], ghull[1]);
1101
1102 for (i = 0; i < 2; i++) {
1103 GEOSGeom_destroy(ghull[i]);
1105 }
1106
1107 if (rtn != 2) {
1108 RASTER_DEBUGF(4,
"convex hulls of rasters do %sintersect", rtn != 1 ?
"NOT " :
"");
1109 if (rtn != 1) {
1110 *intersects = 0;
1112 }
1113
1114 else if (nband1 < 0) {
1115 *intersects = 1;
1117 }
1118 }
1119 else {
1121 }
1122 }
1123 while (0);
1124
1125
1132 area1 = fabs(width1 * height1 * pixarea1);
1133 area2 = fabs(width2 * height2 * pixarea2);
1134 RASTER_DEBUGF(4,
"pixarea1, pixarea2, area1, area2 = %f, %f, %f, %f",
1135 pixarea1, pixarea2, area1, area2);
1136 if (
1138 (area1 < area2) ||
1140 (area1 < pixarea2) ||
1142 ) {
1143 rastS = rast1;
1144 nbandS = nband1;
1145 widthS = &width1;
1146 heightS = &height1;
1147
1148 rastL = rast2;
1149 nbandL = nband2;
1150 widthL = &width2;
1151 heightL = &height2;
1152 }
1153 else {
1154 rastS = rast2;
1155 nbandS = nband2;
1156 widthS = &width2;
1157 heightS = &height2;
1158
1159 rastL = rast1;
1160 nbandL = nband1;
1161 widthL = &width1;
1162 heightL = &height1;
1163 }
1164
1165
1166 if (nband1 < 0) {
1167 nbandS = 0;
1168 nbandL = 0;
1169 }
1170
1175
1176
1178 if (NULL == bandS) {
1179 rterror(
"rt_raster_intersects: Could not get band %d of the first raster", nbandS);
1180 *intersects = 0;
1182 }
1183
1185 if (hasnodataS !=
FALSE)
1187
1188
1190 if (NULL == bandL) {
1191 rterror(
"rt_raster_intersects: Could not get band %d of the first raster", nbandL);
1192 *intersects = 0;
1194 }
1195
1197 if (hasnodataL !=
FALSE)
1199
1200
1201 if (nband1 < 0) {
1204 }
1205
1206
1207 if (
1210 ) {
1211 RASTER_DEBUG(3,
"One of the two raster bands is NODATA. The two rasters do not intersect");
1212 *intersects = 0;
1214 }
1215
1216
1217 if (
within != 0 && ((pixarea1 > area2) || (pixarea2 > area1))) {
1218 RASTER_DEBUG(4,
"Using special case of raster fitting into another raster's pixel");
1219
1220 for (coloffset = 0; coloffset < 3; coloffset++) {
1221 for (rowoffset = 0; rowoffset < 3; rowoffset++) {
1222 for (col = coloffset; col < *widthS; col += 3) {
1223 for (row = rowoffset; row < *heightS; row += 3) {
1224 if (hasnodataS ==
FALSE)
1225 valS = 1;
1227 continue;
1228
1229 if ((hasnodataS ==
FALSE) || !isnodataS) {
1231 rastS,
1232 col, row,
1233 &(lineS[X1]), &(lineS[Y1]),
1234 gtS
1235 );
1236
1238 rastL,
1239 lineS[X1], lineS[Y1],
1240 &(Qr[pX]), &(Qr[pY]),
1241 igtL
1243 continue;
1244 }
1245
1246 if ((Qr[pX] < 0 || Qr[pX] >= *widthL) ||
1247 (Qr[pY] < 0 || Qr[pY] >= *heightL))
1248 {
1249 continue;
1250 }
1251
1252 if (hasnodataS ==
FALSE)
1253 valL = 1;
1255 continue;
1256
1257 if ((hasnodataL ==
FALSE) || !isnodataL) {
1259 *intersects = 1;
1261 }
1262 }
1263 }
1264 }
1265 }
1266 }
1267 RASTER_DEBUG(4,
"Smaller raster not in the other raster's pixel. Continuing");
1268 }
1269
1270 RASTER_DEBUG(4,
"Testing smaller raster vs larger raster");
1272 rastS, rastL,
1273 bandS, bandL,
1274 hasnodataS, hasnodataL,
1275 nodataS, nodataL
1276 );
1277
1278 if (*intersects)
return ES_NONE;
1279
1280 RASTER_DEBUG(4,
"Testing larger raster vs smaller raster");
1282 rastL, rastS,
1283 bandL, bandS,
1284 hasnodataL, hasnodataS,
1285 nodataL, nodataS
1286 );
1287
1288 if (*intersects)
return ES_NONE;
1289
1291
1292 *intersects = 0;
1294}
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
void lwgeom_geos_error(const char *fmt,...)
void lwgeom_free(LWGEOM *geom)
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
#define RASTER_DEBUG(level, msg)
rt_errorstate rt_raster_cell_to_geopoint(rt_raster raster, double xr, double yr, double *xw, double *yw, double *gt)
Convert an xr, yr raster point to an xw, yw point on map.
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
#define RASTER_DEBUGF(level, msg,...)
void void rtinfo(const char *fmt,...) __attribute__((format(printf
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
rt_errorstate rt_raster_geopoint_to_cell(rt_raster raster, double xw, double yw, double *xr, double *yr, double *igt)
Convert an xw, yw map point to a xr, yr raster point.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
double rt_raster_get_x_scale(rt_raster raster)
Get scale X in projection units.
uint16_t rt_raster_get_num_bands(rt_raster raster)
rt_errorstate rt_raster_get_convex_hull(rt_raster raster, LWGEOM **hull)
Get raster's convex hull.
uint16_t rt_raster_get_height(rt_raster raster)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
uint16_t rt_raster_get_width(rt_raster raster)
double rt_raster_get_y_scale(rt_raster raster)
Get scale Y in projection units.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Datum within(PG_FUNCTION_ARGS)
static int rt_raster_intersects_algorithm(rt_raster rast1, rt_raster rast2, rt_band band1, rt_band band2, int hasnodata1, int hasnodata2, double nodata1, double nodata2)