1
/***********************************************************
3
* $Id: lwgeom_btree.c 2273 2006-01-09 15:55:55Z strk $
5
* Comparision function for use in Binary Tree searches
6
* (ORDER BY, GROUP BY, DISTINCT)
8
***********************************************************/
18
#include "utils/geo_decls.h"
20
#include "liblwgeom.h"
21
#include "lwgeom_pg.h"
23
Datum lwgeom_lt(PG_FUNCTION_ARGS);
24
Datum lwgeom_le(PG_FUNCTION_ARGS);
25
Datum lwgeom_eq(PG_FUNCTION_ARGS);
26
Datum lwgeom_ge(PG_FUNCTION_ARGS);
27
Datum lwgeom_gt(PG_FUNCTION_ARGS);
28
Datum lwgeom_cmp(PG_FUNCTION_ARGS);
30
/* #define PGIS_DEBUG */
33
#define BTREE_SRID_MISMATCH_SEVERITY NOTICE
36
#define BTREE_SRID_MISMATCH_SEVERITY WARNING
38
#define BTREE_SRID_MISMATCH_SEVERITY ERROR
42
PG_FUNCTION_INFO_V1(lwgeom_lt);
43
Datum lwgeom_lt(PG_FUNCTION_ARGS)
45
PG_LWGEOM *geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
46
PG_LWGEOM *geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
51
elog(NOTICE, "lwgeom_lt called");
54
if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
56
elog(BTREE_SRID_MISMATCH_SEVERITY,
57
"Operation on two GEOMETRIES with different SRIDs\n");
58
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 )
60
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 )
66
elog(NOTICE, "lwgeom_lt passed getSRID test");
69
getbox2d_p(SERIALIZED_FORM(geom1), &box1);
70
getbox2d_p(SERIALIZED_FORM(geom2), &box2);
73
elog(NOTICE, "lwgeom_lt getbox2d_p passed");
76
if ( ! FPeq(box1.xmin , box2.xmin) ) {
77
if (box1.xmin < box2.xmin)
81
if ( ! FPeq(box1.ymin , box2.ymin) ) {
82
if (box1.ymin < box2.ymin)
86
if ( ! FPeq(box1.xmax , box2.xmax) ) {
87
if (box1.xmax < box2.xmax)
91
if ( ! FPeq(box1.ymax , box2.ymax) ) {
92
if (box1.ymax < box2.ymax)
96
PG_RETURN_BOOL(FALSE);
99
PG_FUNCTION_INFO_V1(lwgeom_le);
100
Datum lwgeom_le(PG_FUNCTION_ARGS)
102
PG_LWGEOM *geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
103
PG_LWGEOM *geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
108
elog(NOTICE, "lwgeom_le called");
111
if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
113
elog(BTREE_SRID_MISMATCH_SEVERITY,
114
"Operation on two GEOMETRIES with different SRIDs\n");
115
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 )
117
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 )
122
getbox2d_p(SERIALIZED_FORM(geom1), &box1);
123
getbox2d_p(SERIALIZED_FORM(geom2), &box2);
125
if ( ! FPeq(box1.xmin , box2.xmin) ) {
126
if (box1.xmin < box2.xmin)
128
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
129
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
130
PG_RETURN_BOOL(TRUE);
132
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
133
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
134
PG_RETURN_BOOL(FALSE);
137
if ( ! FPeq(box1.ymin , box2.ymin) ) {
138
if (box1.ymin < box2.ymin)
140
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
141
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
142
PG_RETURN_BOOL(TRUE);
144
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
145
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
146
PG_RETURN_BOOL(FALSE);
149
if ( ! FPeq(box1.xmax , box2.xmax) ) {
150
if (box1.xmax < box2.xmax)
152
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
153
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
154
PG_RETURN_BOOL(TRUE);
156
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
157
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
158
PG_RETURN_BOOL(FALSE);
161
if ( ! FPeq(box1.ymax , box2.ymax) ) {
162
if (box1.ymax < box2.ymax)
164
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
165
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
166
PG_RETURN_BOOL(TRUE);
168
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
169
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
170
PG_RETURN_BOOL(FALSE);
173
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
174
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
176
PG_RETURN_BOOL(TRUE);
179
PG_FUNCTION_INFO_V1(lwgeom_eq);
180
Datum lwgeom_eq(PG_FUNCTION_ARGS)
182
PG_LWGEOM *geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
183
PG_LWGEOM *geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
188
elog(NOTICE, "lwgeom_eq called");
191
if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
193
elog(BTREE_SRID_MISMATCH_SEVERITY,
194
"Operation on two GEOMETRIES with different SRIDs\n");
195
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 )
197
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 )
202
getbox2d_p(SERIALIZED_FORM(geom1), &box1);
203
getbox2d_p(SERIALIZED_FORM(geom2), &box2);
205
if ( ! FPeq(box1.xmin , box2.xmin) )
207
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
208
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
209
PG_RETURN_BOOL(FALSE);
212
if ( ! FPeq(box1.ymin , box2.ymin) )
214
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
215
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
216
PG_RETURN_BOOL(FALSE);
219
if ( ! FPeq(box1.xmax , box2.xmax) )
221
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
222
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
223
PG_RETURN_BOOL(FALSE);
226
if ( ! FPeq(box1.ymax , box2.ymax) )
228
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
229
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
230
PG_RETURN_BOOL(FALSE);
233
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
234
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
236
PG_RETURN_BOOL(TRUE);
239
PG_FUNCTION_INFO_V1(lwgeom_ge);
240
Datum lwgeom_ge(PG_FUNCTION_ARGS)
242
PG_LWGEOM *geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
243
PG_LWGEOM *geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
248
elog(NOTICE, "lwgeom_ge called");
251
if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
253
elog(BTREE_SRID_MISMATCH_SEVERITY,
254
"Operation on two GEOMETRIES with different SRIDs\n");
255
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 )
257
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 )
262
getbox2d_p(SERIALIZED_FORM(geom1), &box1);
263
getbox2d_p(SERIALIZED_FORM(geom2), &box2);
265
if ( ! FPeq(box1.xmin , box2.xmin) ) {
266
if (box1.xmin > box2.xmin)
268
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
269
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
270
PG_RETURN_BOOL(TRUE);
272
PG_RETURN_BOOL(FALSE);
275
if ( ! FPeq(box1.ymin , box2.ymin) ) {
276
if (box1.ymin > box2.ymin)
278
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
279
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
280
PG_RETURN_BOOL(TRUE);
282
PG_RETURN_BOOL(FALSE);
285
if ( ! FPeq(box1.xmax , box2.xmax) ) {
286
if (box1.xmax > box2.xmax)
288
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
289
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
290
PG_RETURN_BOOL(TRUE);
292
PG_RETURN_BOOL(FALSE);
295
if ( ! FPeq(box1.ymax , box2.ymax) ) {
296
if (box1.ymax > box2.ymax)
298
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
299
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
300
PG_RETURN_BOOL(TRUE);
302
PG_RETURN_BOOL(FALSE);
305
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
306
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
308
PG_RETURN_BOOL(TRUE);
311
PG_FUNCTION_INFO_V1(lwgeom_gt);
312
Datum lwgeom_gt(PG_FUNCTION_ARGS)
314
PG_LWGEOM *geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
315
PG_LWGEOM *geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
320
elog(NOTICE, "lwgeom_gt called");
323
if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
325
elog(BTREE_SRID_MISMATCH_SEVERITY,
326
"Operation on two GEOMETRIES with different SRIDs\n");
327
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 )
329
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 )
334
getbox2d_p(SERIALIZED_FORM(geom1), &box1);
335
getbox2d_p(SERIALIZED_FORM(geom2), &box2);
337
if ( ! FPeq(box1.xmin , box2.xmin) ) {
338
if (box1.xmin > box2.xmin)
340
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
341
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
342
PG_RETURN_BOOL(TRUE);
346
if ( ! FPeq(box1.ymin , box2.ymin) ) {
347
if (box1.ymin > box2.ymin)
349
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
350
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
351
PG_RETURN_BOOL(TRUE);
355
if ( ! FPeq(box1.xmax , box2.xmax) ) {
356
if (box1.xmax > box2.xmax)
358
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
359
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
360
PG_RETURN_BOOL(TRUE);
364
if ( ! FPeq(box1.ymax , box2.ymax) ) {
365
if (box1.ymax > box2.ymax)
367
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
368
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
369
PG_RETURN_BOOL(TRUE);
373
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
374
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
376
PG_RETURN_BOOL(FALSE);
379
PG_FUNCTION_INFO_V1(lwgeom_cmp);
380
Datum lwgeom_cmp(PG_FUNCTION_ARGS)
382
PG_LWGEOM *geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
383
PG_LWGEOM *geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
388
elog(NOTICE, "lwgeom_cmp called");
391
if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
393
elog(BTREE_SRID_MISMATCH_SEVERITY,
394
"Operation on two GEOMETRIES with different SRIDs\n");
395
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 )
397
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 )
402
getbox2d_p(SERIALIZED_FORM(geom1), &box1);
403
getbox2d_p(SERIALIZED_FORM(geom2), &box2);
405
if ( ! FPeq(box1.xmin , box2.xmin) ) {
406
if (box1.xmin < box2.xmin)
408
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
409
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
412
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
413
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
417
if ( ! FPeq(box1.ymin , box2.ymin) ) {
418
if (box1.ymin < box2.ymin)
420
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
421
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
424
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
425
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
429
if ( ! FPeq(box1.xmax , box2.xmax) ) {
430
if (box1.xmax < box2.xmax)
432
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
433
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
436
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
437
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
441
if ( ! FPeq(box1.ymax , box2.ymax) ) {
442
if (box1.ymax < box2.ymax)
444
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
445
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
448
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
449
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
453
if ( (Pointer *)PG_GETARG_DATUM(0) != (Pointer *)geom1 ) pfree(geom1);
454
if ( (Pointer *)PG_GETARG_DATUM(1) != (Pointer *)geom2 ) pfree(geom2);
459
/***********************************************************
462
* Revision 1.9 2006/01/09 15:55:55 strk
463
* ISO C90 comments (finished in lwgeom/)
465
* Revision 1.8 2005/06/15 16:04:11 strk
466
* fault tolerant btree ops
468
* Revision 1.7 2005/02/07 13:21:10 strk
469
* Replaced DEBUG* macros with PGIS_DEBUG*, to avoid clashes with postgresql DEBUG
471
* Revision 1.6 2005/01/05 12:44:47 strk
472
* Added is_worth_caching_serialized_bbox(). Renamed lwgeom_setSRID() to
473
* pglwgeom_setSRID(). Fixed a bug in PG_LWGEOM_construct support for
476
* Revision 1.5 2004/09/29 10:50:30 strk
478
* lwgeom.h is public API
479
* liblwgeom.h is private header
480
* lwgeom_pg.h is for PG-links
481
* lw<type>.c contains type-specific functions
483
* Revision 1.4 2004/09/29 06:31:42 strk
484
* Changed LWGEOM to PG_LWGEOM.
485
* Changed LWGEOM_construct to PG_LWGEOM_construct.
487
* Revision 1.3 2004/08/20 14:08:41 strk
488
* Added Geom{etry,}FromWkb(<geometry>,[<int4>]) funx.
489
* Added LWGEOM typedef and SERIALIZED_FORM(LWGEOM) macro.
490
* Made lwgeom_setSRID an API function.
491
* Added LWGEOM_setAllocator().
493
* Revision 1.2 2004/08/19 13:10:13 strk
496
* (ORDER BY, GROUP BY, DISTINCT)
498
***********************************************************/