PostGIS  2.5.1dev-r@@SVN_REVISION@@
rtpg_spatial_relationship.c
Go to the documentation of this file.
1 /*
2  *
3  * WKTRaster - Raster Types for PostGIS
4  * http://trac.osgeo.org/postgis/wiki/WKTRaster
5  *
6  * Copyright (C) 2011-2013 Regents of the University of California
7  * <bkpark@ucdavis.edu>
8  * Copyright (C) 2010-2011 Jorge Arevalo <jorge.arevalo@deimos-space.com>
9  * Copyright (C) 2010-2011 David Zwarg <dzwarg@azavea.com>
10  * Copyright (C) 2009-2011 Pierre Racine <pierre.racine@sbf.ulaval.ca>
11  * Copyright (C) 2009-2011 Mateusz Loskot <mateusz@loskot.net>
12  * Copyright (C) 2008-2009 Sandro Santilli <strk@kbt.io>
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27  *
28  */
29 
30 #include <postgres.h> /* for palloc */
31 #include <fmgr.h>
32 #include <utils/builtins.h>
33 
34 #include "../../postgis_config.h"
35 
36 #include "lwgeom_pg.h"
37 #include "rtpostgis.h"
38 
39 /* determine if two rasters intersect */
40 Datum RASTER_intersects(PG_FUNCTION_ARGS);
41 
42 /* determine if two rasters overlap */
43 Datum RASTER_overlaps(PG_FUNCTION_ARGS);
44 
45 /* determine if two rasters touch */
46 Datum RASTER_touches(PG_FUNCTION_ARGS);
47 
48 /* determine if the first raster contains the second raster */
49 Datum RASTER_contains(PG_FUNCTION_ARGS);
50 
51 /* determine if the first raster contains properly the second raster */
52 Datum RASTER_containsProperly(PG_FUNCTION_ARGS);
53 
54 /* determine if the first raster covers the second raster */
55 Datum RASTER_covers(PG_FUNCTION_ARGS);
56 
57 /* determine if the first raster is covered by the second raster */
58 Datum RASTER_coveredby(PG_FUNCTION_ARGS);
59 
60 /* determine if the two rasters are within the specified distance of each other */
61 Datum RASTER_dwithin(PG_FUNCTION_ARGS);
62 
63 /* determine if the two rasters are fully within the specified distance of each other */
64 Datum RASTER_dfullywithin(PG_FUNCTION_ARGS);
65 
66 /* determine if two rasters are aligned */
67 Datum RASTER_sameAlignment(PG_FUNCTION_ARGS);
68 Datum RASTER_notSameAlignmentReason(PG_FUNCTION_ARGS);
69 
74 Datum RASTER_intersects(PG_FUNCTION_ARGS)
75 {
76  const uint32_t set_count = 2;
77  rt_pgraster *pgrast[2];
78  int pgrastpos[2] = {-1, -1};
79  rt_raster rast[2] = {NULL};
80  uint32_t bandindex[2] = {0};
81  uint32_t hasbandindex[2] = {0};
82 
83  uint32_t i;
84  uint32_t j;
85  uint32_t k;
87  int rtn;
88  int result;
89 
90  for (i = 0, j = 0; i < set_count; i++) {
91  /* pgrast is null, return null */
92  if (PG_ARGISNULL(j)) {
93  for (k = 0; k < i; k++) {
94  rt_raster_destroy(rast[k]);
95  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
96  }
97  PG_RETURN_NULL();
98  }
99  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
100  pgrastpos[i] = j;
101  j++;
102 
103  /* raster */
104  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
105  if (!rast[i]) {
106  for (k = 0; k <= i; k++) {
107  if (k < i)
108  rt_raster_destroy(rast[k]);
109  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
110  }
111  elog(ERROR, "RASTER_intersects: Could not deserialize the %s raster", i < 1 ? "first" : "second");
112  PG_RETURN_NULL();
113  }
114 
115  /* numbands */
116  numBands = rt_raster_get_num_bands(rast[i]);
117  if (numBands < 1) {
118  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
119  if (i > 0) i++;
120  for (k = 0; k < i; k++) {
121  rt_raster_destroy(rast[k]);
122  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
123  }
124  PG_RETURN_NULL();
125  }
126 
127  /* band index */
128  if (!PG_ARGISNULL(j)) {
129  bandindex[i] = PG_GETARG_INT32(j);
130  if (bandindex[i] < 1 || bandindex[i] > numBands) {
131  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
132  if (i > 0) i++;
133  for (k = 0; k < i; k++) {
134  rt_raster_destroy(rast[k]);
135  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
136  }
137  PG_RETURN_NULL();
138  }
139  hasbandindex[i] = 1;
140  }
141  else
142  hasbandindex[i] = 0;
143  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
144  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
145  j++;
146  }
147 
148  /* hasbandindex must be balanced */
149  if (
150  (hasbandindex[0] && !hasbandindex[1]) ||
151  (!hasbandindex[0] && hasbandindex[1])
152  ) {
153  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
154  for (k = 0; k < set_count; k++) {
155  rt_raster_destroy(rast[k]);
156  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
157  }
158  PG_RETURN_NULL();
159  }
160 
161  /* SRID must match */
162  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
163  for (k = 0; k < set_count; k++) {
164  rt_raster_destroy(rast[k]);
165  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
166  }
167  elog(ERROR, "The two rasters provided have different SRIDs");
168  PG_RETURN_NULL();
169  }
170 
171  rtn = rt_raster_intersects(
172  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
173  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
174  &result
175  );
176  for (k = 0; k < set_count; k++) {
177  rt_raster_destroy(rast[k]);
178  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
179  }
180 
181  if (rtn != ES_NONE) {
182  elog(ERROR, "RASTER_intersects: Could not test for intersection on the two rasters");
183  PG_RETURN_NULL();
184  }
185 
186  PG_RETURN_BOOL(result);
187 }
188 
193 Datum RASTER_overlaps(PG_FUNCTION_ARGS)
194 {
195  const uint32_t set_count = 2;
196  rt_pgraster *pgrast[2];
197  int pgrastpos[2] = {-1, -1};
198  rt_raster rast[2] = {NULL};
199  uint32_t bandindex[2] = {0};
200  uint32_t hasbandindex[2] = {0};
201 
202  uint32_t i;
203  uint32_t j;
204  uint32_t k;
206  int rtn;
207  int result;
208 
209  for (i = 0, j = 0; i < set_count; i++) {
210  /* pgrast is null, return null */
211  if (PG_ARGISNULL(j)) {
212  for (k = 0; k < i; k++) {
213  rt_raster_destroy(rast[k]);
214  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
215  }
216  PG_RETURN_NULL();
217  }
218  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
219  pgrastpos[i] = j;
220  j++;
221 
222  /* raster */
223  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
224  if (!rast[i]) {
225  for (k = 0; k <= i; k++) {
226  if (k < i)
227  rt_raster_destroy(rast[k]);
228  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
229  }
230  elog(ERROR, "RASTER_overlaps: Could not deserialize the %s raster", i < 1 ? "first" : "second");
231  PG_RETURN_NULL();
232  }
233 
234  /* numbands */
235  numBands = rt_raster_get_num_bands(rast[i]);
236  if (numBands < 1) {
237  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
238  if (i > 0) i++;
239  for (k = 0; k < i; k++) {
240  rt_raster_destroy(rast[k]);
241  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
242  }
243  PG_RETURN_NULL();
244  }
245 
246  /* band index */
247  if (!PG_ARGISNULL(j)) {
248  bandindex[i] = PG_GETARG_INT32(j);
249  if (bandindex[i] < 1 || bandindex[i] > numBands) {
250  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
251  if (i > 0) i++;
252  for (k = 0; k < i; k++) {
253  rt_raster_destroy(rast[k]);
254  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
255  }
256  PG_RETURN_NULL();
257  }
258  hasbandindex[i] = 1;
259  }
260  else
261  hasbandindex[i] = 0;
262  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
263  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
264  j++;
265  }
266 
267  /* hasbandindex must be balanced */
268  if (
269  (hasbandindex[0] && !hasbandindex[1]) ||
270  (!hasbandindex[0] && hasbandindex[1])
271  ) {
272  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
273  for (k = 0; k < set_count; k++) {
274  rt_raster_destroy(rast[k]);
275  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
276  }
277  PG_RETURN_NULL();
278  }
279 
280  /* SRID must match */
281  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
282  for (k = 0; k < set_count; k++) {
283  rt_raster_destroy(rast[k]);
284  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
285  }
286  elog(ERROR, "The two rasters provided have different SRIDs");
287  PG_RETURN_NULL();
288  }
289 
290  rtn = rt_raster_overlaps(
291  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
292  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
293  &result
294  );
295  for (k = 0; k < set_count; k++) {
296  rt_raster_destroy(rast[k]);
297  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
298  }
299 
300  if (rtn != ES_NONE) {
301  elog(ERROR, "RASTER_overlaps: Could not test for overlap on the two rasters");
302  PG_RETURN_NULL();
303  }
304 
305  PG_RETURN_BOOL(result);
306 }
307 
312 Datum RASTER_touches(PG_FUNCTION_ARGS)
313 {
314  const uint32_t set_count = 2;
315  rt_pgraster *pgrast[2];
316  int pgrastpos[2] = {-1, -1};
317  rt_raster rast[2] = {NULL};
318  uint32_t bandindex[2] = {0};
319  uint32_t hasbandindex[2] = {0};
320 
321  uint32_t i;
322  uint32_t j;
323  uint32_t k;
325  int rtn;
326  int result;
327 
328  for (i = 0, j = 0; i < set_count; i++) {
329  /* pgrast is null, return null */
330  if (PG_ARGISNULL(j)) {
331  for (k = 0; k < i; k++) {
332  rt_raster_destroy(rast[k]);
333  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
334  }
335  PG_RETURN_NULL();
336  }
337  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
338  pgrastpos[i] = j;
339  j++;
340 
341  /* raster */
342  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
343  if (!rast[i]) {
344  for (k = 0; k <= i; k++) {
345  if (k < i)
346  rt_raster_destroy(rast[k]);
347  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
348  }
349  elog(ERROR, "RASTER_touches: Could not deserialize the %s raster", i < 1 ? "first" : "second");
350  PG_RETURN_NULL();
351  }
352 
353  /* numbands */
354  numBands = rt_raster_get_num_bands(rast[i]);
355  if (numBands < 1) {
356  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
357  if (i > 0) i++;
358  for (k = 0; k < i; k++) {
359  rt_raster_destroy(rast[k]);
360  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
361  }
362  PG_RETURN_NULL();
363  }
364 
365  /* band index */
366  if (!PG_ARGISNULL(j)) {
367  bandindex[i] = PG_GETARG_INT32(j);
368  if (bandindex[i] < 1 || bandindex[i] > numBands) {
369  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
370  if (i > 0) i++;
371  for (k = 0; k < i; k++) {
372  rt_raster_destroy(rast[k]);
373  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
374  }
375  PG_RETURN_NULL();
376  }
377  hasbandindex[i] = 1;
378  }
379  else
380  hasbandindex[i] = 0;
381  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
382  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
383  j++;
384  }
385 
386  /* hasbandindex must be balanced */
387  if (
388  (hasbandindex[0] && !hasbandindex[1]) ||
389  (!hasbandindex[0] && hasbandindex[1])
390  ) {
391  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
392  for (k = 0; k < set_count; k++) {
393  rt_raster_destroy(rast[k]);
394  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
395  }
396  PG_RETURN_NULL();
397  }
398 
399  /* SRID must match */
400  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
401  for (k = 0; k < set_count; k++) {
402  rt_raster_destroy(rast[k]);
403  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
404  }
405  elog(ERROR, "The two rasters provided have different SRIDs");
406  PG_RETURN_NULL();
407  }
408 
409  rtn = rt_raster_touches(
410  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
411  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
412  &result
413  );
414  for (k = 0; k < set_count; k++) {
415  rt_raster_destroy(rast[k]);
416  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
417  }
418 
419  if (rtn != ES_NONE) {
420  elog(ERROR, "RASTER_touches: Could not test for touch on the two rasters");
421  PG_RETURN_NULL();
422  }
423 
424  PG_RETURN_BOOL(result);
425 }
426 
431 Datum RASTER_contains(PG_FUNCTION_ARGS)
432 {
433  const uint32_t set_count = 2;
434  rt_pgraster *pgrast[2];
435  int pgrastpos[2] = {-1, -1};
436  rt_raster rast[2] = {NULL};
437  uint32_t bandindex[2] = {0};
438  uint32_t hasbandindex[2] = {0};
439 
440  uint32_t i;
441  uint32_t j;
442  uint32_t k;
444  int rtn;
445  int result;
446 
447  for (i = 0, j = 0; i < set_count; i++) {
448  /* pgrast is null, return null */
449  if (PG_ARGISNULL(j)) {
450  for (k = 0; k < i; k++) {
451  rt_raster_destroy(rast[k]);
452  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
453  }
454  PG_RETURN_NULL();
455  }
456  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
457  pgrastpos[i] = j;
458  j++;
459 
460  /* raster */
461  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
462  if (!rast[i]) {
463  for (k = 0; k <= i; k++) {
464  if (k < i)
465  rt_raster_destroy(rast[k]);
466  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
467  }
468  elog(ERROR, "RASTER_contains: Could not deserialize the %s raster", i < 1 ? "first" : "second");
469  PG_RETURN_NULL();
470  }
471 
472  /* numbands */
473  numBands = rt_raster_get_num_bands(rast[i]);
474  if (numBands < 1) {
475  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
476  if (i > 0) i++;
477  for (k = 0; k < i; k++) {
478  rt_raster_destroy(rast[k]);
479  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
480  }
481  PG_RETURN_NULL();
482  }
483 
484  /* band index */
485  if (!PG_ARGISNULL(j)) {
486  bandindex[i] = PG_GETARG_INT32(j);
487  if (bandindex[i] < 1 || bandindex[i] > numBands) {
488  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
489  if (i > 0) i++;
490  for (k = 0; k < i; k++) {
491  rt_raster_destroy(rast[k]);
492  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
493  }
494  PG_RETURN_NULL();
495  }
496  hasbandindex[i] = 1;
497  }
498  else
499  hasbandindex[i] = 0;
500  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
501  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
502  j++;
503  }
504 
505  /* hasbandindex must be balanced */
506  if (
507  (hasbandindex[0] && !hasbandindex[1]) ||
508  (!hasbandindex[0] && hasbandindex[1])
509  ) {
510  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
511  for (k = 0; k < set_count; k++) {
512  rt_raster_destroy(rast[k]);
513  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
514  }
515  PG_RETURN_NULL();
516  }
517 
518  /* SRID must match */
519  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
520  for (k = 0; k < set_count; k++) {
521  rt_raster_destroy(rast[k]);
522  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
523  }
524  elog(ERROR, "The two rasters provided have different SRIDs");
525  PG_RETURN_NULL();
526  }
527 
528  rtn = rt_raster_contains(
529  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
530  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
531  &result
532  );
533  for (k = 0; k < set_count; k++) {
534  rt_raster_destroy(rast[k]);
535  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
536  }
537 
538  if (rtn != ES_NONE) {
539  elog(ERROR, "RASTER_contains: Could not test that the first raster contains the second raster");
540  PG_RETURN_NULL();
541  }
542 
543  PG_RETURN_BOOL(result);
544 }
545 
550 Datum RASTER_containsProperly(PG_FUNCTION_ARGS)
551 {
552  const uint32_t set_count = 2;
553  rt_pgraster *pgrast[2];
554  int pgrastpos[2] = {-1, -1};
555  rt_raster rast[2] = {NULL};
556  uint32_t bandindex[2] = {0};
557  uint32_t hasbandindex[2] = {0};
558 
559  uint32_t i;
560  uint32_t j;
561  uint32_t k;
563  int rtn;
564  int result;
565 
566  for (i = 0, j = 0; i < set_count; i++) {
567  /* pgrast is null, return null */
568  if (PG_ARGISNULL(j)) {
569  for (k = 0; k < i; k++) {
570  rt_raster_destroy(rast[k]);
571  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
572  }
573  PG_RETURN_NULL();
574  }
575  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
576  pgrastpos[i] = j;
577  j++;
578 
579  /* raster */
580  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
581  if (!rast[i]) {
582  for (k = 0; k <= i; k++) {
583  if (k < i)
584  rt_raster_destroy(rast[k]);
585  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
586  }
587  elog(ERROR, "RASTER_containsProperly: Could not deserialize the %s raster", i < 1 ? "first" : "second");
588  PG_RETURN_NULL();
589  }
590 
591  /* numbands */
592  numBands = rt_raster_get_num_bands(rast[i]);
593  if (numBands < 1) {
594  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
595  if (i > 0) i++;
596  for (k = 0; k < i; k++) {
597  rt_raster_destroy(rast[k]);
598  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
599  }
600  PG_RETURN_NULL();
601  }
602 
603  /* band index */
604  if (!PG_ARGISNULL(j)) {
605  bandindex[i] = PG_GETARG_INT32(j);
606  if (bandindex[i] < 1 || bandindex[i] > numBands) {
607  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
608  if (i > 0) i++;
609  for (k = 0; k < i; k++) {
610  rt_raster_destroy(rast[k]);
611  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
612  }
613  PG_RETURN_NULL();
614  }
615  hasbandindex[i] = 1;
616  }
617  else
618  hasbandindex[i] = 0;
619  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
620  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
621  j++;
622  }
623 
624  /* hasbandindex must be balanced */
625  if (
626  (hasbandindex[0] && !hasbandindex[1]) ||
627  (!hasbandindex[0] && hasbandindex[1])
628  ) {
629  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
630  for (k = 0; k < set_count; k++) {
631  rt_raster_destroy(rast[k]);
632  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
633  }
634  PG_RETURN_NULL();
635  }
636 
637  /* SRID must match */
638  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
639  for (k = 0; k < set_count; k++) {
640  rt_raster_destroy(rast[k]);
641  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
642  }
643  elog(ERROR, "The two rasters provided have different SRIDs");
644  PG_RETURN_NULL();
645  }
646 
648  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
649  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
650  &result
651  );
652  for (k = 0; k < set_count; k++) {
653  rt_raster_destroy(rast[k]);
654  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
655  }
656 
657  if (rtn != ES_NONE) {
658  elog(ERROR, "RASTER_containsProperly: Could not test that the first raster contains properly the second raster");
659  PG_RETURN_NULL();
660  }
661 
662  PG_RETURN_BOOL(result);
663 }
664 
669 Datum RASTER_covers(PG_FUNCTION_ARGS)
670 {
671  const uint32_t set_count = 2;
672  rt_pgraster *pgrast[2];
673  int pgrastpos[2] = {-1, -1};
674  rt_raster rast[2] = {NULL};
675  uint32_t bandindex[2] = {0};
676  uint32_t hasbandindex[2] = {0};
677 
678  uint32_t i;
679  uint32_t j;
680  uint32_t k;
682  int rtn;
683  int result;
684 
685  for (i = 0, j = 0; i < set_count; i++) {
686  /* pgrast is null, return null */
687  if (PG_ARGISNULL(j)) {
688  for (k = 0; k < i; k++) {
689  rt_raster_destroy(rast[k]);
690  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
691  }
692  PG_RETURN_NULL();
693  }
694  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
695  pgrastpos[i] = j;
696  j++;
697 
698  /* raster */
699  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
700  if (!rast[i]) {
701  for (k = 0; k <= i; k++) {
702  if (k < i)
703  rt_raster_destroy(rast[k]);
704  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
705  }
706  elog(ERROR, "RASTER_covers: Could not deserialize the %s raster", i < 1 ? "first" : "second");
707  PG_RETURN_NULL();
708  }
709 
710  /* numbands */
711  numBands = rt_raster_get_num_bands(rast[i]);
712  if (numBands < 1) {
713  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
714  if (i > 0) i++;
715  for (k = 0; k < i; k++) {
716  rt_raster_destroy(rast[k]);
717  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
718  }
719  PG_RETURN_NULL();
720  }
721 
722  /* band index */
723  if (!PG_ARGISNULL(j)) {
724  bandindex[i] = PG_GETARG_INT32(j);
725  if (bandindex[i] < 1 || bandindex[i] > numBands) {
726  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
727  if (i > 0) i++;
728  for (k = 0; k < i; k++) {
729  rt_raster_destroy(rast[k]);
730  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
731  }
732  PG_RETURN_NULL();
733  }
734  hasbandindex[i] = 1;
735  }
736  else
737  hasbandindex[i] = 0;
738  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
739  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
740  j++;
741  }
742 
743  /* hasbandindex must be balanced */
744  if (
745  (hasbandindex[0] && !hasbandindex[1]) ||
746  (!hasbandindex[0] && hasbandindex[1])
747  ) {
748  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
749  for (k = 0; k < set_count; k++) {
750  rt_raster_destroy(rast[k]);
751  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
752  }
753  PG_RETURN_NULL();
754  }
755 
756  /* SRID must match */
757  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
758  for (k = 0; k < set_count; k++) {
759  rt_raster_destroy(rast[k]);
760  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
761  }
762  elog(ERROR, "The two rasters provided have different SRIDs");
763  PG_RETURN_NULL();
764  }
765 
766  rtn = rt_raster_covers(
767  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
768  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
769  &result
770  );
771  for (k = 0; k < set_count; k++) {
772  rt_raster_destroy(rast[k]);
773  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
774  }
775 
776  if (rtn != ES_NONE) {
777  elog(ERROR, "RASTER_covers: Could not test that the first raster covers the second raster");
778  PG_RETURN_NULL();
779  }
780 
781  PG_RETURN_BOOL(result);
782 }
783 
788 Datum RASTER_coveredby(PG_FUNCTION_ARGS)
789 {
790  const uint32_t set_count = 2;
791  rt_pgraster *pgrast[2];
792  int pgrastpos[2] = {-1, -1};
793  rt_raster rast[2] = {NULL};
794  uint32_t bandindex[2] = {0};
795  uint32_t hasbandindex[2] = {0};
796 
797  uint32_t i;
798  uint32_t j;
799  uint32_t k;
801  int rtn;
802  int result;
803 
804  for (i = 0, j = 0; i < set_count; i++) {
805  /* pgrast is null, return null */
806  if (PG_ARGISNULL(j)) {
807  for (k = 0; k < i; k++) {
808  rt_raster_destroy(rast[k]);
809  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
810  }
811  PG_RETURN_NULL();
812  }
813  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
814  pgrastpos[i] = j;
815  j++;
816 
817  /* raster */
818  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
819  if (!rast[i]) {
820  for (k = 0; k <= i; k++) {
821  if (k < i)
822  rt_raster_destroy(rast[k]);
823  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
824  }
825  elog(ERROR, "RASTER_coveredby: Could not deserialize the %s raster", i < 1 ? "first" : "second");
826  PG_RETURN_NULL();
827  }
828 
829  /* numbands */
830  numBands = rt_raster_get_num_bands(rast[i]);
831  if (numBands < 1) {
832  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
833  if (i > 0) i++;
834  for (k = 0; k < i; k++) {
835  rt_raster_destroy(rast[k]);
836  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
837  }
838  PG_RETURN_NULL();
839  }
840 
841  /* band index */
842  if (!PG_ARGISNULL(j)) {
843  bandindex[i] = PG_GETARG_INT32(j);
844  if (bandindex[i] < 1 || bandindex[i] > numBands) {
845  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
846  if (i > 0) i++;
847  for (k = 0; k < i; k++) {
848  rt_raster_destroy(rast[k]);
849  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
850  }
851  PG_RETURN_NULL();
852  }
853  hasbandindex[i] = 1;
854  }
855  else
856  hasbandindex[i] = 0;
857  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
858  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
859  j++;
860  }
861 
862  /* hasbandindex must be balanced */
863  if (
864  (hasbandindex[0] && !hasbandindex[1]) ||
865  (!hasbandindex[0] && hasbandindex[1])
866  ) {
867  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
868  for (k = 0; k < set_count; k++) {
869  rt_raster_destroy(rast[k]);
870  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
871  }
872  PG_RETURN_NULL();
873  }
874 
875  /* SRID must match */
876  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
877  for (k = 0; k < set_count; k++) {
878  rt_raster_destroy(rast[k]);
879  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
880  }
881  elog(ERROR, "The two rasters provided have different SRIDs");
882  PG_RETURN_NULL();
883  }
884 
885  rtn = rt_raster_coveredby(
886  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
887  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
888  &result
889  );
890  for (k = 0; k < set_count; k++) {
891  rt_raster_destroy(rast[k]);
892  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
893  }
894 
895  if (rtn != ES_NONE) {
896  elog(ERROR, "RASTER_coveredby: Could not test that the first raster is covered by the second raster");
897  PG_RETURN_NULL();
898  }
899 
900  PG_RETURN_BOOL(result);
901 }
902 
907 Datum RASTER_dwithin(PG_FUNCTION_ARGS)
908 {
909  const uint32_t set_count = 2;
910  rt_pgraster *pgrast[2];
911  int pgrastpos[2] = {-1, -1};
912  rt_raster rast[2] = {NULL};
913  uint32_t bandindex[2] = {0};
914  uint32_t hasbandindex[2] = {0};
915  double distance = 0;
916 
917  uint32_t i;
918  uint32_t j;
919  uint32_t k;
921  int rtn;
922  int result;
923 
924  for (i = 0, j = 0; i < set_count; i++) {
925  /* pgrast is null, return null */
926  if (PG_ARGISNULL(j)) {
927  for (k = 0; k < i; k++) {
928  rt_raster_destroy(rast[k]);
929  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
930  }
931  PG_RETURN_NULL();
932  }
933  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
934  pgrastpos[i] = j;
935  j++;
936 
937  /* raster */
938  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
939  if (!rast[i]) {
940  for (k = 0; k <= i; k++) {
941  if (k < i)
942  rt_raster_destroy(rast[k]);
943  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
944  }
945  elog(ERROR, "RASTER_dwithin: Could not deserialize the %s raster", i < 1 ? "first" : "second");
946  PG_RETURN_NULL();
947  }
948 
949  /* numbands */
950  numBands = rt_raster_get_num_bands(rast[i]);
951  if (numBands < 1) {
952  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
953  if (i > 0) i++;
954  for (k = 0; k < i; k++) {
955  rt_raster_destroy(rast[k]);
956  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
957  }
958  PG_RETURN_NULL();
959  }
960 
961  /* band index */
962  if (!PG_ARGISNULL(j)) {
963  bandindex[i] = PG_GETARG_INT32(j);
964  if (bandindex[i] < 1 || bandindex[i] > numBands) {
965  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
966  if (i > 0) i++;
967  for (k = 0; k < i; k++) {
968  rt_raster_destroy(rast[k]);
969  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
970  }
971  PG_RETURN_NULL();
972  }
973  hasbandindex[i] = 1;
974  }
975  else
976  hasbandindex[i] = 0;
977  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
978  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
979  j++;
980  }
981 
982  /* distance */
983  if (PG_ARGISNULL(4)) {
984  elog(NOTICE, "Distance cannot be NULL. Returning NULL");
985  for (k = 0; k < set_count; k++) {
986  rt_raster_destroy(rast[k]);
987  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
988  }
989  PG_RETURN_NULL();
990  }
991 
992  distance = PG_GETARG_FLOAT8(4);
993  if (distance < 0) {
994  elog(NOTICE, "Distance cannot be less than zero. Returning NULL");
995  for (k = 0; k < set_count; k++) {
996  rt_raster_destroy(rast[k]);
997  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
998  }
999  PG_RETURN_NULL();
1000  }
1001 
1002  /* hasbandindex must be balanced */
1003  if (
1004  (hasbandindex[0] && !hasbandindex[1]) ||
1005  (!hasbandindex[0] && hasbandindex[1])
1006  ) {
1007  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
1008  for (k = 0; k < set_count; k++) {
1009  rt_raster_destroy(rast[k]);
1010  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1011  }
1012  PG_RETURN_NULL();
1013  }
1014 
1015  /* SRID must match */
1016  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
1017  for (k = 0; k < set_count; k++) {
1018  rt_raster_destroy(rast[k]);
1019  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1020  }
1021  elog(ERROR, "The two rasters provided have different SRIDs");
1022  PG_RETURN_NULL();
1023  }
1024 
1026  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
1027  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
1028  distance,
1029  &result
1030  );
1031  for (k = 0; k < set_count; k++) {
1032  rt_raster_destroy(rast[k]);
1033  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1034  }
1035 
1036  if (rtn != ES_NONE) {
1037  elog(ERROR, "RASTER_dwithin: Could not test that the two rasters are within the specified distance of each other");
1038  PG_RETURN_NULL();
1039  }
1040 
1041  PG_RETURN_BOOL(result);
1042 }
1043 
1048 Datum RASTER_dfullywithin(PG_FUNCTION_ARGS)
1049 {
1050  const uint32_t set_count = 2;
1051  rt_pgraster *pgrast[2];
1052  int pgrastpos[2] = {-1, -1};
1053  rt_raster rast[2] = {NULL};
1054  uint32_t bandindex[2] = {0};
1055  uint32_t hasbandindex[2] = {0};
1056  double distance = 0;
1057 
1058  uint32_t i;
1059  uint32_t j;
1060  uint32_t k;
1062  int rtn;
1063  int result;
1064 
1065  for (i = 0, j = 0; i < set_count; i++) {
1066  /* pgrast is null, return null */
1067  if (PG_ARGISNULL(j)) {
1068  for (k = 0; k < i; k++) {
1069  rt_raster_destroy(rast[k]);
1070  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1071  }
1072  PG_RETURN_NULL();
1073  }
1074  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
1075  pgrastpos[i] = j;
1076  j++;
1077 
1078  /* raster */
1079  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
1080  if (!rast[i]) {
1081  for (k = 0; k <= i; k++) {
1082  if (k < i)
1083  rt_raster_destroy(rast[k]);
1084  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1085  }
1086  elog(ERROR, "RASTER_dfullywithin: Could not deserialize the %s raster", i < 1 ? "first" : "second");
1087  PG_RETURN_NULL();
1088  }
1089 
1090  /* numbands */
1091  numBands = rt_raster_get_num_bands(rast[i]);
1092  if (numBands < 1) {
1093  elog(NOTICE, "The %s raster provided has no bands", i < 1 ? "first" : "second");
1094  if (i > 0) i++;
1095  for (k = 0; k < i; k++) {
1096  rt_raster_destroy(rast[k]);
1097  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1098  }
1099  PG_RETURN_NULL();
1100  }
1101 
1102  /* band index */
1103  if (!PG_ARGISNULL(j)) {
1104  bandindex[i] = PG_GETARG_INT32(j);
1105  if (bandindex[i] < 1 || bandindex[i] > numBands) {
1106  elog(NOTICE, "Invalid band index (must use 1-based) for the %s raster. Returning NULL", i < 1 ? "first" : "second");
1107  if (i > 0) i++;
1108  for (k = 0; k < i; k++) {
1109  rt_raster_destroy(rast[k]);
1110  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1111  }
1112  PG_RETURN_NULL();
1113  }
1114  hasbandindex[i] = 1;
1115  }
1116  else
1117  hasbandindex[i] = 0;
1118  POSTGIS_RT_DEBUGF(4, "hasbandindex[%d] = %d", i, hasbandindex[i]);
1119  POSTGIS_RT_DEBUGF(4, "bandindex[%d] = %d", i, bandindex[i]);
1120  j++;
1121  }
1122 
1123  /* distance */
1124  if (PG_ARGISNULL(4)) {
1125  elog(NOTICE, "Distance cannot be NULL. Returning NULL");
1126  for (k = 0; k < set_count; k++) {
1127  rt_raster_destroy(rast[k]);
1128  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1129  }
1130  PG_RETURN_NULL();
1131  }
1132 
1133  distance = PG_GETARG_FLOAT8(4);
1134  if (distance < 0) {
1135  elog(NOTICE, "Distance cannot be less than zero. Returning NULL");
1136  for (k = 0; k < set_count; k++) {
1137  rt_raster_destroy(rast[k]);
1138  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1139  }
1140  PG_RETURN_NULL();
1141  }
1142 
1143  /* hasbandindex must be balanced */
1144  if (
1145  (hasbandindex[0] && !hasbandindex[1]) ||
1146  (!hasbandindex[0] && hasbandindex[1])
1147  ) {
1148  elog(NOTICE, "Missing band index. Band indices must be provided for both rasters if any one is provided");
1149  for (k = 0; k < set_count; k++) {
1150  rt_raster_destroy(rast[k]);
1151  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1152  }
1153  PG_RETURN_NULL();
1154  }
1155 
1156  /* SRID must match */
1157  if (rt_raster_get_srid(rast[0]) != rt_raster_get_srid(rast[1])) {
1158  for (k = 0; k < set_count; k++) {
1159  rt_raster_destroy(rast[k]);
1160  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1161  }
1162  elog(ERROR, "The two rasters provided have different SRIDs");
1163  PG_RETURN_NULL();
1164  }
1165 
1167  rast[0], (hasbandindex[0] ? (int)bandindex[0] - 1 : -1),
1168  rast[1], (hasbandindex[1] ? (int)bandindex[1] - 1 : -1),
1169  distance,
1170  &result
1171  );
1172  for (k = 0; k < set_count; k++) {
1173  rt_raster_destroy(rast[k]);
1174  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1175  }
1176 
1177  if (rtn != ES_NONE) {
1178  elog(ERROR, "RASTER_dfullywithin: Could not test that the two rasters are fully within the specified distance of each other");
1179  PG_RETURN_NULL();
1180  }
1181 
1182  PG_RETURN_BOOL(result);
1183 }
1184 
1189 Datum RASTER_sameAlignment(PG_FUNCTION_ARGS)
1190 {
1191  const uint32_t set_count = 2;
1192  rt_pgraster *pgrast[2];
1193  int pgrastpos[2] = {-1, -1};
1194  rt_raster rast[2] = {NULL};
1195 
1196  uint32_t i;
1197  uint32_t j;
1198  uint32_t k;
1199  int rtn;
1200  int aligned = 0;
1201  char *reason = NULL;
1202 
1203  for (i = 0, j = 0; i < set_count; i++) {
1204  /* pgrast is null, return null */
1205  if (PG_ARGISNULL(j)) {
1206  for (k = 0; k < i; k++) {
1207  rt_raster_destroy(rast[k]);
1208  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1209  }
1210  PG_RETURN_NULL();
1211  }
1212  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(j), 0, sizeof(struct rt_raster_serialized_t));
1213  pgrastpos[i] = j;
1214  j++;
1215 
1216  /* raster */
1217  rast[i] = rt_raster_deserialize(pgrast[i], TRUE);
1218  if (!rast[i]) {
1219  for (k = 0; k <= i; k++) {
1220  if (k < i)
1221  rt_raster_destroy(rast[k]);
1222  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1223  }
1224  elog(ERROR, "RASTER_sameAlignment: Could not deserialize the %s raster", i < 1 ? "first" : "second");
1225  PG_RETURN_NULL();
1226  }
1227  }
1228 
1230  rast[0],
1231  rast[1],
1232  &aligned,
1233  &reason
1234  );
1235  for (k = 0; k < set_count; k++) {
1236  rt_raster_destroy(rast[k]);
1237  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1238  }
1239 
1240  if (rtn != ES_NONE) {
1241  elog(ERROR, "RASTER_sameAlignment: Could not test for alignment on the two rasters");
1242  PG_RETURN_NULL();
1243  }
1244 
1245  /* only output reason if not aligned */
1246  if (reason != NULL && !aligned)
1247  elog(NOTICE, "%s", reason);
1248 
1249  PG_RETURN_BOOL(aligned);
1250 }
1251 
1256 Datum RASTER_notSameAlignmentReason(PG_FUNCTION_ARGS)
1257 {
1258  const uint32_t set_count = 2;
1259  rt_pgraster *pgrast[2];
1260  int pgrastpos[2] = {-1, -1};
1261  rt_raster rast[2] = {NULL};
1262 
1263  uint32_t i;
1264  uint32_t j;
1265  uint32_t k;
1266  int rtn;
1267  int aligned = 0;
1268  char *reason = NULL;
1269  text *result = NULL;
1270 
1271  for (i = 0, j = 0; i < set_count; i++) {
1272  /* pgrast is null, return null */
1273  if (PG_ARGISNULL(j)) {
1274  for (k = 0; k < i; k++) {
1275  rt_raster_destroy(rast[k]);
1276  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1277  }
1278  PG_RETURN_NULL();
1279  }
1280  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(j), 0, sizeof(struct rt_raster_serialized_t));
1281  pgrastpos[i] = j;
1282  j++;
1283 
1284  /* raster */
1285  rast[i] = rt_raster_deserialize(pgrast[i], TRUE);
1286  if (!rast[i]) {
1287  for (k = 0; k <= i; k++) {
1288  if (k < i)
1289  rt_raster_destroy(rast[k]);
1290  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1291  }
1292  elog(ERROR, "RASTER_notSameAlignmentReason: Could not deserialize the %s raster", i < 1 ? "first" : "second");
1293  PG_RETURN_NULL();
1294  }
1295  }
1296 
1298  rast[0],
1299  rast[1],
1300  &aligned,
1301  &reason
1302  );
1303  for (k = 0; k < set_count; k++) {
1304  rt_raster_destroy(rast[k]);
1305  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
1306  }
1307 
1308  if (rtn != ES_NONE) {
1309  elog(ERROR, "RASTER_notSameAlignmentReason: Could not test for alignment on the two rasters");
1310  PG_RETURN_NULL();
1311  }
1312 
1313  result = cstring_to_text(reason);
1314  PG_RETURN_TEXT_P(result);
1315 }
Datum RASTER_contains(PG_FUNCTION_ARGS)
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:372
Datum RASTER_containsProperly(PG_FUNCTION_ARGS)
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
Datum RASTER_notSameAlignmentReason(PG_FUNCTION_ARGS)
rt_errorstate rt_raster_covers(rt_raster rast1, int nband1, rt_raster rast2, int nband2, int *covers)
Return ES_ERROR if error occurred in function.
rt_errorstate rt_raster_contains(rt_raster rast1, int nband1, rt_raster rast2, int nband2, int *contains)
Return ES_ERROR if error occurred in function.
Datum RASTER_dwithin(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(RASTER_intersects)
See if two rasters intersect.
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
unsigned int uint32_t
Definition: uthash.h:78
Datum RASTER_intersects(PG_FUNCTION_ARGS)
rt_errorstate rt_raster_intersects(rt_raster rast1, int nband1, rt_raster rast2, int nband2, int *intersects)
Return ES_ERROR if error occurred in function.
Datum RASTER_covers(PG_FUNCTION_ARGS)
Datum RASTER_overlaps(PG_FUNCTION_ARGS)
int32_t rt_raster_get_srid(rt_raster raster)
Get raster&#39;s SRID.
Definition: rt_raster.c:356
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
Datum distance(PG_FUNCTION_ARGS)
Datum RASTER_dfullywithin(PG_FUNCTION_ARGS)
Datum RASTER_sameAlignment(PG_FUNCTION_ARGS)
#define FALSE
Definition: dbfopen.c:168
Struct definitions.
Definition: librtcore.h:2250
rt_errorstate rt_raster_touches(rt_raster rast1, int nband1, rt_raster rast2, int nband2, int *touches)
Return ES_ERROR if error occurred in function.
Datum RASTER_coveredby(PG_FUNCTION_ARGS)
Datum RASTER_touches(PG_FUNCTION_ARGS)
rt_errorstate rt_raster_fully_within_distance(rt_raster rast1, int nband1, rt_raster rast2, int nband2, double distance, int *dfwithin)
Return ES_ERROR if error occurred in function.
rt_errorstate rt_raster_coveredby(rt_raster rast1, int nband1, rt_raster rast2, int nband2, int *coveredby)
Return ES_ERROR if error occurred in function.
rt_errorstate rt_raster_within_distance(rt_raster rast1, int nband1, rt_raster rast2, int nband2, double distance, int *dwithin)
Return ES_ERROR if error occurred in function.
#define TRUE
Definition: dbfopen.c:169
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
rt_errorstate rt_raster_contains_properly(rt_raster rast1, int nband1, rt_raster rast2, int nband2, int *contains)
Return ES_ERROR if error occurred in function.
rt_errorstate rt_raster_overlaps(rt_raster rast1, int nband1, rt_raster rast2, int nband2, int *overlaps)
Return ES_ERROR if error occurred in function.