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