From: Darafei Praliaskouski Date: Fri, 13 Jul 2018 20:06:43 +0000 (+0000) Subject: SP-GiST implementation polishing X-Git-Tag: 2.5.0beta2~45 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=587badb8cca5b59f734c1a0d689024f0287bc47b;p=postgis SP-GiST implementation polishing Added copyrights to headers, moved BOX3D function declarations from SP-GiST to box3d headers to suppress warnings. References #1847 Closes https://github.com/postgis/postgis/pull/269 git-svn-id: http://svn.osgeo.org/postgis/trunk@16641 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/postgis/gserialized_spgist_2d.c b/postgis/gserialized_spgist_2d.c index 52547b9c7..8f8ff7609 100644 --- a/postgis/gserialized_spgist_2d.c +++ b/postgis/gserialized_spgist_2d.c @@ -64,24 +64,24 @@ * that we don't yet have as infinity. * * Portions Copyright (c) 2018, Esteban Zimanyi, Arthur Lesuisse, - * Université Libre de Bruxelles + * Université Libre de Bruxelles * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *****************************************************************************/ #include -#include /* For float manipulation */ -#include "access/spgist.h" /* For SP-GiST */ -#include "catalog/namespace.h" /* For TypenameGetTypid */ -#include "catalog/pg_type_d.h" /* For VOIDOID */ +#include /* For float manipulation */ +#include "access/spgist.h" /* For SP-GiST */ +#include "catalog/namespace.h" /* For TypenameGetTypid */ +#include "catalog/pg_type_d.h" /* For VOIDOID */ #include "../postgis_config.h" -#include "liblwgeom.h" /* For standard geometry types. */ -#include "lwgeom_pg.h" /* For debugging macros. */ -#include /* For utility functions. */ -#include /* For debugging macros. */ +#include "liblwgeom.h" /* For standard geometry types. */ +#include "lwgeom_pg.h" /* For debugging macros. */ +#include /* For utility functions. */ +#include /* For debugging macros. */ /* ** SP-GiST 2D index function prototypes @@ -104,8 +104,8 @@ Datum gserialized_spgist_compress_2d(PG_FUNCTION_ARGS); static int compareDoubles(const void *a, const void *b) { - double x = *(double *) a; - double y = *(double *) b; + double x = *(double *)a; + double y = *(double *)b; if (x == y) return 0; @@ -114,8 +114,8 @@ compareDoubles(const void *a, const void *b) typedef struct { - BOX2DF left; - BOX2DF right; + BOX2DF left; + BOX2DF right; } RectBox; /* @@ -128,7 +128,7 @@ typedef struct static uint8 getQuadrant4D(BOX2DF *centroid, BOX2DF *inBox) { - uint8 quadrant = 0; + uint8 quadrant = 0; if (inBox->xmin > centroid->xmin) quadrant |= 0x8; @@ -154,8 +154,8 @@ getQuadrant4D(BOX2DF *centroid, BOX2DF *inBox) static RectBox * initRectBox(void) { - RectBox *rect_box = (RectBox *) palloc(sizeof(RectBox)); - float infinity = get_float4_infinity(); + RectBox *rect_box = (RectBox *)palloc(sizeof(RectBox)); + float infinity = get_float4_infinity(); rect_box->left.xmin = -infinity; rect_box->left.xmax = infinity; @@ -182,7 +182,7 @@ initRectBox(void) static RectBox * nextRectBox(RectBox *rect_box, BOX2DF *centroid, uint8 quadrant) { - RectBox *next_rect_box = (RectBox *) palloc(sizeof(RectBox)); + RectBox *next_rect_box = (RectBox *)palloc(sizeof(RectBox)); memcpy(next_rect_box, rect_box, sizeof(RectBox)); @@ -213,20 +213,16 @@ nextRectBox(RectBox *rect_box, BOX2DF *centroid, uint8 quadrant) static bool overlap4D(RectBox *rect_box, BOX2DF *query) { - return (rect_box->left.xmin <= query->xmax && - rect_box->right.xmax >= query->xmin && - rect_box->left.ymin <= query->ymax && - rect_box->right.ymax >= query->ymin); + return (rect_box->left.xmin <= query->xmax && rect_box->right.xmax >= query->xmin) && + (rect_box->left.ymin <= query->ymax && rect_box->right.ymax >= query->ymin); } /* Can any cube from rect_box contain query? */ static bool contain4D(RectBox *rect_box, BOX2DF *query) { - return (rect_box->right.xmax >= query->xmax && - rect_box->left.xmin <= query->xmin && - rect_box->right.ymax >= query->ymax && - rect_box->left.ymin <= query->ymin); + return (rect_box->right.xmax >= query->xmax && rect_box->left.xmin <= query->xmin) && + (rect_box->right.ymax >= query->ymax && rect_box->left.ymin <= query->ymin); } /* Can any cube from rect_box be left of query? */ @@ -291,14 +287,13 @@ overAbove4D(RectBox *rect_box, BOX2DF *query) PG_FUNCTION_INFO_V1(gserialized_spgist_config_2d); -PGDLLEXPORT Datum -gserialized_spgist_config_2d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_config_2d(PG_FUNCTION_ARGS) { - spgConfigOut *cfg = (spgConfigOut *) PG_GETARG_POINTER(1); + spgConfigOut *cfg = (spgConfigOut *)PG_GETARG_POINTER(1); Oid boxoid = TypenameGetTypid("box2df"); cfg->prefixType = boxoid; - cfg->labelType = VOIDOID; /* We don't need node labels. */ + cfg->labelType = VOIDOID; /* We don't need node labels. */ cfg->leafType = boxoid; cfg->canReturnData = false; cfg->longValuesOK = false; @@ -312,13 +307,11 @@ gserialized_spgist_config_2d(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(gserialized_spgist_choose_2d); -PGDLLEXPORT Datum -gserialized_spgist_choose_2d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_choose_2d(PG_FUNCTION_ARGS) { - spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0); - spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1); - BOX2DF *centroid = (BOX2DF *) DatumGetPointer(in->prefixDatum), - *box = (BOX2DF *) DatumGetPointer(in->leafDatum); + spgChooseIn *in = (spgChooseIn *)PG_GETARG_POINTER(0); + spgChooseOut *out = (spgChooseOut *)PG_GETARG_POINTER(1); + BOX2DF *centroid = (BOX2DF *)DatumGetPointer(in->prefixDatum), *box = (BOX2DF *)DatumGetPointer(in->leafDatum); out->resultType = spgMatchNode; out->result.matchNode.restDatum = PointerGetDatum(box); @@ -338,28 +331,26 @@ gserialized_spgist_choose_2d(PG_FUNCTION_ARGS) */ PG_FUNCTION_INFO_V1(gserialized_spgist_picksplit_2d); -PGDLLEXPORT Datum -gserialized_spgist_picksplit_2d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_picksplit_2d(PG_FUNCTION_ARGS) { - spgPickSplitIn *in = (spgPickSplitIn *) PG_GETARG_POINTER(0); - spgPickSplitOut *out = (spgPickSplitOut *) PG_GETARG_POINTER(1); - BOX2DF *centroid; - int median, - i; - double *lowXs = palloc(sizeof(double) * in->nTuples); - double *highXs = palloc(sizeof(double) * in->nTuples); - double *lowYs = palloc(sizeof(double) * in->nTuples); - double *highYs = palloc(sizeof(double) * in->nTuples); + spgPickSplitIn *in = (spgPickSplitIn *)PG_GETARG_POINTER(0); + spgPickSplitOut *out = (spgPickSplitOut *)PG_GETARG_POINTER(1); + BOX2DF *centroid; + int median, i; + double *lowXs = palloc(sizeof(double) * in->nTuples); + double *highXs = palloc(sizeof(double) * in->nTuples); + double *lowYs = palloc(sizeof(double) * in->nTuples); + double *highYs = palloc(sizeof(double) * in->nTuples); /* Calculate median of all 4D coordinates */ for (i = 0; i < in->nTuples; i++) { - BOX2DF *box = (BOX2DF *) DatumGetPointer(in->datums[i]); + BOX2DF *box = (BOX2DF *)DatumGetPointer(in->datums[i]); - lowXs[i] = (double) box->xmin; - highXs[i] = (double) box->xmax; - lowYs[i] = (double) box->ymin; - highYs[i] = (double) box->ymax; + lowXs[i] = (double)box->xmin; + highXs[i] = (double)box->xmax; + lowYs[i] = (double)box->ymin; + highYs[i] = (double)box->ymax; } qsort(lowXs, in->nTuples, sizeof(double), compareDoubles); @@ -371,29 +362,28 @@ gserialized_spgist_picksplit_2d(PG_FUNCTION_ARGS) centroid = palloc(sizeof(BOX2DF)); - centroid->xmin = (float) lowXs[median]; - centroid->xmax = (float) highXs[median]; - centroid->ymin = (float) lowYs[median]; - centroid->ymax = (float) highYs[median]; + centroid->xmin = (float)lowXs[median]; + centroid->xmax = (float)highXs[median]; + centroid->ymin = (float)lowYs[median]; + centroid->ymax = (float)highYs[median]; /* Fill the output */ out->hasPrefix = true; out->prefixDatum = BoxPGetDatum(centroid); out->nNodes = 16; - out->nodeLabels = NULL; /* We don't need node labels. */ + out->nodeLabels = NULL; /* We don't need node labels. */ out->mapTuplesToNodes = palloc(sizeof(int) * in->nTuples); out->leafTupleDatums = palloc(sizeof(Datum) * in->nTuples); /* - * Assign ranges to corresponding nodes according to quadrants relative to - * the "centroid" range + * Assign ranges to corresponding nodes according to quadrants relative to the "centroid" range */ for (i = 0; i < in->nTuples; i++) { - BOX2DF *box = (BOX2DF *) DatumGetPointer(in->datums[i]); - uint8 quadrant = getQuadrant4D(centroid, box); + BOX2DF *box = (BOX2DF *)DatumGetPointer(in->datums[i]); + uint8 quadrant = getQuadrant4D(centroid, box); out->leafTupleDatums[i] = PointerGetDatum(box); out->mapTuplesToNodes[i] = quadrant; @@ -412,22 +402,21 @@ gserialized_spgist_picksplit_2d(PG_FUNCTION_ARGS) */ PG_FUNCTION_INFO_V1(gserialized_spgist_inner_consistent_2d); -PGDLLEXPORT Datum -gserialized_spgist_inner_consistent_2d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_inner_consistent_2d(PG_FUNCTION_ARGS) { - spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); - spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); - int i; + spgInnerConsistentIn *in = (spgInnerConsistentIn *)PG_GETARG_POINTER(0); + spgInnerConsistentOut *out = (spgInnerConsistentOut *)PG_GETARG_POINTER(1); + int i; MemoryContext old_ctx; - RectBox *rect_box; - uint8 quadrant; - BOX2DF *centroid; + RectBox *rect_box; + uint8 quadrant; + BOX2DF *centroid; if (in->allTheSame) { /* Report that all nodes should be visited */ out->nNodes = in->nNodes; - out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); + out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes); for (i = 0; i < in->nNodes; i++) out->nodeNumbers[i] = i; @@ -443,12 +432,12 @@ gserialized_spgist_inner_consistent_2d(PG_FUNCTION_ARGS) else rect_box = initRectBox(); - centroid = (BOX2DF *) DatumGetPointer(in->prefixDatum); + centroid = (BOX2DF *)DatumGetPointer(in->prefixDatum); /* Allocate enough memory for nodes */ out->nNodes = 0; - out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); - out->traversalValues = (void **) palloc(sizeof(void *) * in->nNodes); + out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes); + out->traversalValues = (void **)palloc(sizeof(void *) * in->nNodes); /* * We switch memory context, because we want to allocate memory for new @@ -459,24 +448,24 @@ gserialized_spgist_inner_consistent_2d(PG_FUNCTION_ARGS) for (quadrant = 0; quadrant < in->nNodes; quadrant++) { - RectBox *next_rect_box = nextRectBox(rect_box, centroid, quadrant); - bool flag = true; + RectBox *next_rect_box = nextRectBox(rect_box, centroid, quadrant); + bool flag = true; for (i = 0; i < in->nkeys; i++) { StrategyNumber strategy = in->scankeys[i].sk_strategy; - Datum query = in->scankeys[i].sk_argument; - BOX2DF query_gbox_index; + Datum query = in->scankeys[i].sk_argument; + BOX2DF query_gbox_index; /* Quick sanity check on query argument. */ - if ( DatumGetPointer(query) == NULL ) + if (DatumGetPointer(query) == NULL) { POSTGIS_DEBUG(4, "[SPGIST] null query pointer (!?!), returning false"); PG_RETURN_BOOL(false); /* NULL query! This is screwy! */ } - if ( gserialized_datum_get_box2df_p(query, &query_gbox_index) == LW_FAILURE ) + if (gserialized_datum_get_box2df_p(query, &query_gbox_index) == LW_FAILURE) { POSTGIS_DEBUG(4, "[SPGIST] null query_gbox_index!"); PG_RETURN_BOOL(false); @@ -484,51 +473,51 @@ gserialized_spgist_inner_consistent_2d(PG_FUNCTION_ARGS) switch (strategy) { - case RTOverlapStrategyNumber: - case RTContainedByStrategyNumber: - case RTOldContainedByStrategyNumber: - flag = overlap4D(next_rect_box, &query_gbox_index); - break; - - case RTContainsStrategyNumber: - case RTSameStrategyNumber: - flag = contain4D(next_rect_box, &query_gbox_index); - break; - - case RTLeftStrategyNumber: - flag = !overRight4D(next_rect_box, &query_gbox_index); - break; - - case RTOverLeftStrategyNumber: - flag = !right4D(next_rect_box, &query_gbox_index); - break; - - case RTRightStrategyNumber: - flag = !overLeft4D(next_rect_box, &query_gbox_index); - break; - - case RTOverRightStrategyNumber: - flag = !left4D(next_rect_box, &query_gbox_index); - break; - - case RTAboveStrategyNumber: - flag = !overBelow4D(next_rect_box, &query_gbox_index); - break; - - case RTOverAboveStrategyNumber: - flag = !below4D(next_rect_box, &query_gbox_index); - break; - - case RTBelowStrategyNumber: - flag = !overAbove4D(next_rect_box, &query_gbox_index); - break; - - case RTOverBelowStrategyNumber: - flag = !above4D(next_rect_box, &query_gbox_index); - break; - - default: - elog(ERROR, "unrecognized strategy: %d", strategy); + case RTOverlapStrategyNumber: + case RTContainedByStrategyNumber: + case RTOldContainedByStrategyNumber: + flag = overlap4D(next_rect_box, &query_gbox_index); + break; + + case RTContainsStrategyNumber: + case RTSameStrategyNumber: + flag = contain4D(next_rect_box, &query_gbox_index); + break; + + case RTLeftStrategyNumber: + flag = !overRight4D(next_rect_box, &query_gbox_index); + break; + + case RTOverLeftStrategyNumber: + flag = !right4D(next_rect_box, &query_gbox_index); + break; + + case RTRightStrategyNumber: + flag = !overLeft4D(next_rect_box, &query_gbox_index); + break; + + case RTOverRightStrategyNumber: + flag = !left4D(next_rect_box, &query_gbox_index); + break; + + case RTAboveStrategyNumber: + flag = !overBelow4D(next_rect_box, &query_gbox_index); + break; + + case RTOverAboveStrategyNumber: + flag = !below4D(next_rect_box, &query_gbox_index); + break; + + case RTBelowStrategyNumber: + flag = !overAbove4D(next_rect_box, &query_gbox_index); + break; + + case RTOverBelowStrategyNumber: + flag = !above4D(next_rect_box, &query_gbox_index); + break; + + default: + elog(ERROR, "unrecognized strategy: %d", strategy); } /* If any check is failed, we have found our answer. */ @@ -563,17 +552,16 @@ gserialized_spgist_inner_consistent_2d(PG_FUNCTION_ARGS) */ PG_FUNCTION_INFO_V1(gserialized_spgist_leaf_consistent_2d); -PGDLLEXPORT Datum -gserialized_spgist_leaf_consistent_2d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_leaf_consistent_2d(PG_FUNCTION_ARGS) { - spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0); - spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1); - BOX2DF *key = (BOX2DF *) DatumGetPointer(in->leafDatum); - bool flag = true; - int i; + spgLeafConsistentIn *in = (spgLeafConsistentIn *)PG_GETARG_POINTER(0); + spgLeafConsistentOut *out = (spgLeafConsistentOut *)PG_GETARG_POINTER(1); + BOX2DF *key = (BOX2DF *)DatumGetPointer(in->leafDatum); + bool flag = true; + int i; /* Quick sanity check on entry key. */ - if ( DatumGetPointer(key) == NULL ) + if (DatumGetPointer(key) == NULL) { POSTGIS_DEBUG(4, "[SPGIST] null index entry, returning false"); PG_RETURN_BOOL(false); /* NULL entry! */ @@ -589,17 +577,17 @@ gserialized_spgist_leaf_consistent_2d(PG_FUNCTION_ARGS) for (i = 0; i < in->nkeys; i++) { StrategyNumber strategy = in->scankeys[i].sk_strategy; - Datum query = in->scankeys[i].sk_argument; - BOX2DF query_gbox_index; + Datum query = in->scankeys[i].sk_argument; + BOX2DF query_gbox_index; /* Quick sanity check on query argument. */ - if ( DatumGetPointer(query) == NULL ) + if (DatumGetPointer(query) == NULL) { POSTGIS_DEBUG(4, "[SPGIST] null query pointer (!?!), returning false"); PG_RETURN_BOOL(false); /* NULL query! This is screwy! */ } - if ( gserialized_datum_get_box2df_p(query, &query_gbox_index) == LW_FAILURE ) + if (gserialized_datum_get_box2df_p(query, &query_gbox_index) == LW_FAILURE) { POSTGIS_DEBUG(4, "[SPGIST] null query_gbox_index!"); PG_RETURN_BOOL(false); @@ -607,58 +595,58 @@ gserialized_spgist_leaf_consistent_2d(PG_FUNCTION_ARGS) switch (strategy) { - case RTOverlapStrategyNumber: - flag = box2df_overlaps(key, &query_gbox_index); - break; + case RTOverlapStrategyNumber: + flag = box2df_overlaps(key, &query_gbox_index); + break; - case RTContainsStrategyNumber: - case RTOldContainsStrategyNumber: - flag = box2df_contains(key, &query_gbox_index); - break; + case RTContainsStrategyNumber: + case RTOldContainsStrategyNumber: + flag = box2df_contains(key, &query_gbox_index); + break; - case RTContainedByStrategyNumber: - case RTOldContainedByStrategyNumber: - flag = box2df_contains(&query_gbox_index, key); - break; + case RTContainedByStrategyNumber: + case RTOldContainedByStrategyNumber: + flag = box2df_contains(&query_gbox_index, key); + break; - case RTSameStrategyNumber: - flag = box2df_equals(key, &query_gbox_index); - break; + case RTSameStrategyNumber: + flag = box2df_equals(key, &query_gbox_index); + break; - case RTLeftStrategyNumber: - flag = box2df_left(key, &query_gbox_index); - break; + case RTLeftStrategyNumber: + flag = box2df_left(key, &query_gbox_index); + break; - case RTOverLeftStrategyNumber: - flag = box2df_overleft(key, &query_gbox_index); - break; + case RTOverLeftStrategyNumber: + flag = box2df_overleft(key, &query_gbox_index); + break; - case RTRightStrategyNumber: - flag = box2df_right(key, &query_gbox_index); - break; + case RTRightStrategyNumber: + flag = box2df_right(key, &query_gbox_index); + break; - case RTOverRightStrategyNumber: - flag = box2df_overright(key, &query_gbox_index); - break; + case RTOverRightStrategyNumber: + flag = box2df_overright(key, &query_gbox_index); + break; - case RTAboveStrategyNumber: - flag = box2df_above(key, &query_gbox_index); - break; + case RTAboveStrategyNumber: + flag = box2df_above(key, &query_gbox_index); + break; - case RTOverAboveStrategyNumber: - flag = box2df_overabove(key, &query_gbox_index); - break; + case RTOverAboveStrategyNumber: + flag = box2df_overabove(key, &query_gbox_index); + break; - case RTBelowStrategyNumber: - flag = box2df_below(key, &query_gbox_index); - break; + case RTBelowStrategyNumber: + flag = box2df_below(key, &query_gbox_index); + break; - case RTOverBelowStrategyNumber: - flag = box2df_overbelow(key, &query_gbox_index); - break; + case RTOverBelowStrategyNumber: + flag = box2df_overbelow(key, &query_gbox_index); + break; - default: - elog(ERROR, "unrecognized strategy: %d", strategy); + default: + elog(ERROR, "unrecognized strategy: %d", strategy); } /* If any check is failed, we have found our answer. */ @@ -669,20 +657,12 @@ gserialized_spgist_leaf_consistent_2d(PG_FUNCTION_ARGS) PG_RETURN_BOOL(flag); } -/* -** RTiST support function. Given a geography, return a "compressed" -** version. In this case, we convert the geography into a geocentric -** bounding box. If the geography already has the box embedded in it -** we pull that out and hand it back. -*/ - PG_FUNCTION_INFO_V1(gserialized_spgist_compress_2d); -PGDLLEXPORT Datum -gserialized_spgist_compress_2d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_compress_2d(PG_FUNCTION_ARGS) { - Datum gsdatum = PG_GETARG_DATUM(0); - BOX2DF *bbox_out = palloc(sizeof(BOX2DF)); + Datum gsdatum = PG_GETARG_DATUM(0); + BOX2DF *bbox_out = palloc(sizeof(BOX2DF)); int result = LW_SUCCESS; POSTGIS_DEBUG(4, "[SPGIST] 'compress' function called"); @@ -691,7 +671,7 @@ gserialized_spgist_compress_2d(PG_FUNCTION_ARGS) result = gserialized_datum_get_box2df_p(gsdatum, bbox_out); /* Is the bounding box valid (non-empty, non-infinite)? If not, return input uncompressed. */ - if ( result == LW_FAILURE ) + if (result == LW_FAILURE) { box2df_set_empty(bbox_out); @@ -702,8 +682,8 @@ gserialized_spgist_compress_2d(PG_FUNCTION_ARGS) POSTGIS_DEBUGF(4, "[SPGIST] got box: %s", box2df_to_string(bbox_out)); /* Check all the dimensions for finite values */ - if ( ! isfinite(bbox_out->xmax) || ! isfinite(bbox_out->xmin) || - ! isfinite(bbox_out->ymax) || ! isfinite(bbox_out->ymin) ) + if ((!isfinite(bbox_out->xmax) || !isfinite(bbox_out->xmin)) || + (!isfinite(bbox_out->ymax) || !isfinite(bbox_out->ymin))) { box2df_set_finite(bbox_out); diff --git a/postgis/gserialized_spgist_3d.c b/postgis/gserialized_spgist_3d.c index 79a2f3eb3..2b8e8c650 100644 --- a/postgis/gserialized_spgist_3d.c +++ b/postgis/gserialized_spgist_3d.c @@ -71,6 +71,7 @@ *****************************************************************************/ #include "gserialized_spgist_3d.h" +#include "lwgeom_box3d.h" #include "lwgeom_pg.h" PG_FUNCTION_INFO_V1(gserialized_overlaps_3d); @@ -79,7 +80,8 @@ Datum gserialized_overlaps_3d(PG_FUNCTION_ARGS) BOX3D *box1 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(0))); BOX3D *box2 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(1))); bool resut = BOX3D_overlaps_internal(box1, box2); - pfree(box1); pfree(box2); + pfree(box1); + pfree(box2); PG_RETURN_BOOL(resut); } @@ -90,7 +92,8 @@ Datum gserialized_contains_3d(PG_FUNCTION_ARGS) BOX3D *box1 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(0))); BOX3D *box2 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(1))); bool resut = BOX3D_contains_internal(box1, box2); - pfree(box1); pfree(box2); + pfree(box1); + pfree(box2); PG_RETURN_BOOL(resut); } @@ -101,7 +104,8 @@ Datum gserialized_contained_3d(PG_FUNCTION_ARGS) BOX3D *box1 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(0))); BOX3D *box2 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(1))); bool resut = BOX3D_contained_internal(box1, box2); - pfree(box1); pfree(box2); + pfree(box1); + pfree(box2); PG_RETURN_BOOL(resut); } @@ -112,7 +116,8 @@ Datum gserialized_same_3d(PG_FUNCTION_ARGS) BOX3D *box1 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(0))); BOX3D *box2 = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(1))); bool resut = BOX3D_same_internal(box1, box2); - pfree(box1); pfree(box2); + pfree(box1); + pfree(box2); PG_RETURN_BOOL(resut); } @@ -127,8 +132,8 @@ Datum gserialized_same_3d(PG_FUNCTION_ARGS) static int compareDoubles(const void *a, const void *b) { - double x = *(double *) a; - double y = *(double *) b; + double x = *(double *)a; + double y = *(double *)b; if (x == y) return 0; @@ -137,8 +142,8 @@ compareDoubles(const void *a, const void *b) typedef struct { - BOX3D left; - BOX3D right; + BOX3D left; + BOX3D right; } CubeBox3D; /* @@ -151,7 +156,7 @@ typedef struct static uint8 getOctant(BOX3D *centroid, BOX3D *inBox) { - uint8 octant = 0; + uint8 octant = 0; if (inBox->xmin > centroid->xmin) octant |= 0x20; @@ -183,8 +188,8 @@ getOctant(BOX3D *centroid, BOX3D *inBox) static CubeBox3D * initCubeBox(void) { - CubeBox3D *cube_box = (CubeBox3D *) palloc(sizeof(CubeBox3D)); - double infinity = get_float8_infinity(); + CubeBox3D *cube_box = (CubeBox3D *)palloc(sizeof(CubeBox3D)); + double infinity = get_float8_infinity(); cube_box->left.xmin = -infinity; cube_box->left.xmax = infinity; @@ -210,14 +215,14 @@ initCubeBox(void) /* * Calculate the next traversal value * - * All centroids are bounded by CubeBox3D, but SP-GiST only keeps - * boxes. When we are traversing the tree, we must calculate CubeBox3D, + * All centroids are bounded by CubeBox3D, but SP-GiST only keeps boxes. + * When we are traversing the tree, we must calculate CubeBox3D, * using centroid and octant. */ static CubeBox3D * nextCubeBox3D(CubeBox3D *cube_box, BOX3D *centroid, uint8 octant) { - CubeBox3D *next_cube_box = (CubeBox3D *) palloc(sizeof(CubeBox3D)); + CubeBox3D *next_cube_box = (CubeBox3D *)palloc(sizeof(CubeBox3D)); memcpy(next_cube_box, cube_box, sizeof(CubeBox3D)); @@ -258,24 +263,18 @@ nextCubeBox3D(CubeBox3D *cube_box, BOX3D *centroid, uint8 octant) static bool overlap6D(CubeBox3D *cube_box, BOX3D *query) { - return (cube_box->left.xmin <= query->xmax) && - (cube_box->right.xmax >= query->xmin) && - (cube_box->left.ymin <= query->ymax) && - (cube_box->right.ymax >= query->ymin) && - (cube_box->left.zmin <= query->zmax) && - (cube_box->right.zmax >= query->zmin); + return (cube_box->left.xmin <= query->xmax) && (cube_box->right.xmax >= query->xmin) && + (cube_box->left.ymin <= query->ymax) && (cube_box->right.ymax >= query->ymin) && + (cube_box->left.zmin <= query->zmax) && (cube_box->right.zmax >= query->zmin); } /* Can any cube from cube_box contain query? */ static bool contain6D(CubeBox3D *cube_box, BOX3D *query) { - return (cube_box->right.xmax >= query->xmax) && - (cube_box->left.xmin <= query->xmin) && - (cube_box->right.ymax >= query->ymax) && - (cube_box->left.ymin <= query->ymin) && - (cube_box->right.zmax >= query->zmax) && - (cube_box->left.zmin <= query->zmin); + return (cube_box->right.xmax >= query->xmax) && (cube_box->left.xmin <= query->xmin) && + (cube_box->right.ymax >= query->ymax) && (cube_box->left.ymin <= query->ymin) && + (cube_box->right.zmax >= query->zmax) && (cube_box->left.zmin <= query->zmin); } /* Can any cube from cube_box be left of query? */ @@ -368,14 +367,13 @@ overBack6D(CubeBox3D *cube_box, BOX3D *query) PG_FUNCTION_INFO_V1(gserialized_spgist_config_3d); -PGDLLEXPORT Datum -gserialized_spgist_config_3d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_config_3d(PG_FUNCTION_ARGS) { - spgConfigOut *cfg = (spgConfigOut *) PG_GETARG_POINTER(1); + spgConfigOut *cfg = (spgConfigOut *)PG_GETARG_POINTER(1); Oid boxoid = TypenameGetTypid("box3d"); cfg->prefixType = boxoid; - cfg->labelType = VOIDOID; /* We don't need node labels. */ + cfg->labelType = VOIDOID; /* We don't need node labels. */ cfg->leafType = boxoid; cfg->canReturnData = false; cfg->longValuesOK = false; @@ -389,13 +387,12 @@ gserialized_spgist_config_3d(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(gserialized_spgist_choose_3d); -PGDLLEXPORT Datum -gserialized_spgist_choose_3d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_choose_3d(PG_FUNCTION_ARGS) { - spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0); - spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1); - BOX3D *centroid = DatumGetBox3DP(in->prefixDatum), - *box = DatumGetBox3DP(in->leafDatum); + spgChooseIn *in = (spgChooseIn *)PG_GETARG_POINTER(0); + spgChooseOut *out = (spgChooseOut *)PG_GETARG_POINTER(1); + BOX3D *centroid = DatumGetBox3DP(in->prefixDatum); + BOX3D *box = DatumGetBox3DP(in->leafDatum); out->resultType = spgMatchNode; out->result.matchNode.restDatum = Box3DPGetDatum(box); @@ -415,27 +412,25 @@ gserialized_spgist_choose_3d(PG_FUNCTION_ARGS) */ PG_FUNCTION_INFO_V1(gserialized_spgist_picksplit_3d); -PGDLLEXPORT Datum -gserialized_spgist_picksplit_3d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_picksplit_3d(PG_FUNCTION_ARGS) { - spgPickSplitIn *in = (spgPickSplitIn *) PG_GETARG_POINTER(0); - spgPickSplitOut *out = (spgPickSplitOut *) PG_GETARG_POINTER(1); - BOX3D *centroid; - int median, - i; - double *lowXs = palloc(sizeof(double) * in->nTuples); - double *highXs = palloc(sizeof(double) * in->nTuples); - double *lowYs = palloc(sizeof(double) * in->nTuples); - double *highYs = palloc(sizeof(double) * in->nTuples); - double *lowZs = palloc(sizeof(double) * in->nTuples); - double *highZs = palloc(sizeof(double) * in->nTuples); - BOX3D *box = DatumGetBox3DP(in->datums[0]); - int32_t srid = box->srid; + spgPickSplitIn *in = (spgPickSplitIn *)PG_GETARG_POINTER(0); + spgPickSplitOut *out = (spgPickSplitOut *)PG_GETARG_POINTER(1); + BOX3D *centroid; + int median, i; + double *lowXs = palloc(sizeof(double) * in->nTuples); + double *highXs = palloc(sizeof(double) * in->nTuples); + double *lowYs = palloc(sizeof(double) * in->nTuples); + double *highYs = palloc(sizeof(double) * in->nTuples); + double *lowZs = palloc(sizeof(double) * in->nTuples); + double *highZs = palloc(sizeof(double) * in->nTuples); + BOX3D *box = DatumGetBox3DP(in->datums[0]); + int32_t srid = box->srid; /* Calculate median of all 6D coordinates */ for (i = 0; i < in->nTuples; i++) { - BOX3D *box = DatumGetBox3DP(in->datums[i]); + BOX3D *box = DatumGetBox3DP(in->datums[i]); lowXs[i] = box->xmin; highXs[i] = box->xmax; @@ -469,7 +464,7 @@ gserialized_spgist_picksplit_3d(PG_FUNCTION_ARGS) out->prefixDatum = Box3DPGetDatum(centroid); out->nNodes = 64; - out->nodeLabels = NULL; /* We don't need node labels. */ + out->nodeLabels = NULL; /* We don't need node labels. */ out->mapTuplesToNodes = palloc(sizeof(int) * in->nTuples); out->leafTupleDatums = palloc(sizeof(Datum) * in->nTuples); @@ -480,8 +475,8 @@ gserialized_spgist_picksplit_3d(PG_FUNCTION_ARGS) */ for (i = 0; i < in->nTuples; i++) { - BOX3D *box = DatumGetBox3DP(in->datums[i]); - uint8 octant = getOctant(centroid, box); + BOX3D *box = DatumGetBox3DP(in->datums[i]); + uint8 octant = getOctant(centroid, box); out->leafTupleDatums[i] = Box3DPGetDatum(box); out->mapTuplesToNodes[i] = octant; @@ -502,24 +497,23 @@ gserialized_spgist_picksplit_3d(PG_FUNCTION_ARGS) */ PG_FUNCTION_INFO_V1(gserialized_spgist_inner_consistent_3d); -PGDLLEXPORT Datum -gserialized_spgist_inner_consistent_3d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_inner_consistent_3d(PG_FUNCTION_ARGS) { - spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); - spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); - int i; + spgInnerConsistentIn *in = (spgInnerConsistentIn *)PG_GETARG_POINTER(0); + spgInnerConsistentOut *out = (spgInnerConsistentOut *)PG_GETARG_POINTER(1); + int i; MemoryContext old_ctx; - CubeBox3D *cube_box; - uint8 octant; - BOX3D *centroid; - int *nodeNumbers; - void **traversalValues; + CubeBox3D *cube_box; + uint8 octant; + BOX3D *centroid; + int *nodeNumbers; + void **traversalValues; if (in->allTheSame) { /* Report that all nodes should be visited */ out->nNodes = in->nNodes; - out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); + out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes); for (i = 0; i < in->nNodes; i++) out->nodeNumbers[i] = i; @@ -539,8 +533,8 @@ gserialized_spgist_inner_consistent_3d(PG_FUNCTION_ARGS) /* Allocate enough memory for nodes */ out->nNodes = 0; - nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); - traversalValues = (void **) palloc(sizeof(void *) * in->nNodes); + nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes); + traversalValues = (void **)palloc(sizeof(void *) * in->nNodes); /* * We switch memory context, because we want to allocate memory for new @@ -551,77 +545,77 @@ gserialized_spgist_inner_consistent_3d(PG_FUNCTION_ARGS) for (octant = 0; octant < in->nNodes; octant++) { - CubeBox3D *next_cube_box = nextCubeBox3D(cube_box, centroid, octant); - bool flag = true; + CubeBox3D *next_cube_box = nextCubeBox3D(cube_box, centroid, octant); + bool flag = true; for (i = 0; i < in->nkeys; i++) { StrategyNumber strategy = in->scankeys[i].sk_strategy; - Datum query = in->scankeys[i].sk_argument; - BOX3D *box = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, query)); + Datum query = in->scankeys[i].sk_argument; + BOX3D *box = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, query)); switch (strategy) { - case SPGOverlapStrategyNumber: - case SPGContainedByStrategyNumber: - flag = overlap6D(next_cube_box, box); - break; - - case SPGContainsStrategyNumber: - case SPGSameStrategyNumber: - flag = contain6D(next_cube_box, box); - break; - - case SPGLeftStrategyNumber: - flag = !overRight6D(next_cube_box, box); - break; - - case SPGOverLeftStrategyNumber: - flag = !right6D(next_cube_box, box); - break; - - case SPGRightStrategyNumber: - flag = !overLeft6D(next_cube_box, box); - break; - - case SPGOverRightStrategyNumber: - flag = !left6D(next_cube_box, box); - break; - - case SPGAboveStrategyNumber: - flag = !overBelow6D(next_cube_box, box); - break; - - case SPGOverAboveStrategyNumber: - flag = !below6D(next_cube_box, box); - break; - - case SPGBelowStrategyNumber: - flag = !overAbove6D(next_cube_box, box); - break; - - case SPGOverBelowStrategyNumber: - flag = !above6D(next_cube_box, box); - break; - - case SPGBackStrategyNumber: - flag = !overFront6D(next_cube_box, box); - break; - - case SPGOverBackStrategyNumber: - flag = !front6D(next_cube_box, box); - break; - - case SPGFrontStrategyNumber: - flag = !overBack6D(next_cube_box, box); - break; - - case SPGOverFrontStrategyNumber: - flag = !back6D(next_cube_box, box); - break; - - default: - elog(ERROR, "unrecognized strategy: %d", strategy); + case SPGOverlapStrategyNumber: + case SPGContainedByStrategyNumber: + flag = overlap6D(next_cube_box, box); + break; + + case SPGContainsStrategyNumber: + case SPGSameStrategyNumber: + flag = contain6D(next_cube_box, box); + break; + + case SPGLeftStrategyNumber: + flag = !overRight6D(next_cube_box, box); + break; + + case SPGOverLeftStrategyNumber: + flag = !right6D(next_cube_box, box); + break; + + case SPGRightStrategyNumber: + flag = !overLeft6D(next_cube_box, box); + break; + + case SPGOverRightStrategyNumber: + flag = !left6D(next_cube_box, box); + break; + + case SPGAboveStrategyNumber: + flag = !overBelow6D(next_cube_box, box); + break; + + case SPGOverAboveStrategyNumber: + flag = !below6D(next_cube_box, box); + break; + + case SPGBelowStrategyNumber: + flag = !overAbove6D(next_cube_box, box); + break; + + case SPGOverBelowStrategyNumber: + flag = !above6D(next_cube_box, box); + break; + + case SPGBackStrategyNumber: + flag = !overFront6D(next_cube_box, box); + break; + + case SPGOverBackStrategyNumber: + flag = !front6D(next_cube_box, box); + break; + + case SPGFrontStrategyNumber: + flag = !overBack6D(next_cube_box, box); + break; + + case SPGOverFrontStrategyNumber: + flag = !back6D(next_cube_box, box); + break; + + default: + elog(ERROR, "unrecognized strategy: %d", strategy); } /* If any check is failed, we have found our answer. */ @@ -646,8 +640,8 @@ gserialized_spgist_inner_consistent_3d(PG_FUNCTION_ARGS) } /* Pass to the next level only the values that need to be traversed */ - out->nodeNumbers = (int *) palloc(sizeof(int) * out->nNodes); - out->traversalValues = (void **) palloc(sizeof(void *) * out->nNodes); + out->nodeNumbers = (int *)palloc(sizeof(int) * out->nNodes); + out->traversalValues = (void **)palloc(sizeof(void *) * out->nNodes); for (i = 0; i < out->nNodes; i++) { out->nodeNumbers[i] = nodeNumbers[i]; @@ -667,14 +661,13 @@ gserialized_spgist_inner_consistent_3d(PG_FUNCTION_ARGS) */ PG_FUNCTION_INFO_V1(gserialized_spgist_leaf_consistent_3d); -PGDLLEXPORT Datum -gserialized_spgist_leaf_consistent_3d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_leaf_consistent_3d(PG_FUNCTION_ARGS) { - spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0); - spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1); - BOX3D *leaf = DatumGetBox3DP(in->leafDatum); - bool flag = true; - int i; + spgLeafConsistentIn *in = (spgLeafConsistentIn *)PG_GETARG_POINTER(0); + spgLeafConsistentOut *out = (spgLeafConsistentOut *)PG_GETARG_POINTER(1); + BOX3D *leaf = DatumGetBox3DP(in->leafDatum); + bool flag = true; + int i; /* All tests are exact. */ out->recheck = false; @@ -686,77 +679,77 @@ gserialized_spgist_leaf_consistent_3d(PG_FUNCTION_ARGS) for (i = 0; i < in->nkeys; i++) { StrategyNumber strategy = in->scankeys[i].sk_strategy; - Datum query = in->scankeys[i].sk_argument; - BOX3D *box = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, query)); + Datum query = in->scankeys[i].sk_argument; + BOX3D *box = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, query)); switch (strategy) { - case SPGOverlapStrategyNumber: - flag = BOX3D_overlaps_internal(leaf, box); - break; + case SPGOverlapStrategyNumber: + flag = BOX3D_overlaps_internal(leaf, box); + break; - case SPGContainsStrategyNumber: - flag = BOX3D_contains_internal(leaf, box); - break; + case SPGContainsStrategyNumber: + flag = BOX3D_contains_internal(leaf, box); + break; - case SPGContainedByStrategyNumber: - flag = BOX3D_contained_internal(leaf, box); - break; + case SPGContainedByStrategyNumber: + flag = BOX3D_contained_internal(leaf, box); + break; - case SPGSameStrategyNumber: - flag = BOX3D_same_internal(leaf, box); - break; + case SPGSameStrategyNumber: + flag = BOX3D_same_internal(leaf, box); + break; - case SPGLeftStrategyNumber: - flag = BOX3D_left_internal(leaf, box); - break; + case SPGLeftStrategyNumber: + flag = BOX3D_left_internal(leaf, box); + break; - case SPGOverLeftStrategyNumber: - flag = BOX3D_overleft_internal(leaf, box); - break; + case SPGOverLeftStrategyNumber: + flag = BOX3D_overleft_internal(leaf, box); + break; - case SPGRightStrategyNumber: - flag = BOX3D_right_internal(leaf, box); - break; + case SPGRightStrategyNumber: + flag = BOX3D_right_internal(leaf, box); + break; - case SPGOverRightStrategyNumber: - flag = BOX3D_overright_internal(leaf, box); - break; + case SPGOverRightStrategyNumber: + flag = BOX3D_overright_internal(leaf, box); + break; - case SPGAboveStrategyNumber: - flag = BOX3D_above_internal(leaf, box); - break; + case SPGAboveStrategyNumber: + flag = BOX3D_above_internal(leaf, box); + break; - case SPGOverAboveStrategyNumber: - flag = BOX3D_overabove_internal(leaf, box); - break; + case SPGOverAboveStrategyNumber: + flag = BOX3D_overabove_internal(leaf, box); + break; - case SPGBelowStrategyNumber: - flag = BOX3D_below_internal(leaf, box); - break; + case SPGBelowStrategyNumber: + flag = BOX3D_below_internal(leaf, box); + break; - case SPGOverBelowStrategyNumber: - flag = BOX3D_overbelow_internal(leaf, box); - break; + case SPGOverBelowStrategyNumber: + flag = BOX3D_overbelow_internal(leaf, box); + break; - case SPGBackStrategyNumber: - flag = BOX3D_back_internal(leaf, box); - break; + case SPGBackStrategyNumber: + flag = BOX3D_back_internal(leaf, box); + break; - case SPGOverBackStrategyNumber: - flag = BOX3D_overback_internal(leaf, box); - break; + case SPGOverBackStrategyNumber: + flag = BOX3D_overback_internal(leaf, box); + break; - case SPGFrontStrategyNumber: - flag = BOX3D_front_internal(leaf, box); - break; + case SPGFrontStrategyNumber: + flag = BOX3D_front_internal(leaf, box); + break; - case SPGOverFrontStrategyNumber: - flag = BOX3D_overfront_internal(leaf, box); - break; + case SPGOverFrontStrategyNumber: + flag = BOX3D_overfront_internal(leaf, box); + break; - default: - elog(ERROR, "unrecognized strategy: %d", strategy); + default: + elog(ERROR, "unrecognized strategy: %d", strategy); } /* If any check is failed, we have found our answer. */ @@ -769,13 +762,12 @@ gserialized_spgist_leaf_consistent_3d(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(gserialized_spgist_compress_3d); -PGDLLEXPORT Datum -gserialized_spgist_compress_3d(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum gserialized_spgist_compress_3d(PG_FUNCTION_ARGS) { - BOX3D *result = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(0))); + BOX3D *result = DatumGetBox3DP(DirectFunctionCall1(LWGEOM_to_BOX3D, PG_GETARG_DATUM(0))); /* Is the bounding box is null */ - if ( result == LW_FAILURE ) + if (result == LW_FAILURE) { PG_RETURN_NULL(); } diff --git a/postgis/gserialized_spgist_3d.h b/postgis/gserialized_spgist_3d.h index 051e5cba5..d470bdfe8 100644 --- a/postgis/gserialized_spgist_3d.h +++ b/postgis/gserialized_spgist_3d.h @@ -41,30 +41,7 @@ #define SPGSubEqualStrategyNumber 25 /* for inet <<= */ #define SPGSuperStrategyNumber 26 /* for inet << */ #define SPGSuperEqualStrategyNumber 27 /* for inet >>= */ -#define SPGOverFrontStrategyNumber 28 /* for &> */ -#define SPGOverBackStrategyNumber 31 /* for /&> */ - -/***************************************************************************** - * BOX3D operators - *****************************************************************************/ - - -bool BOX3D_contains_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_contained_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_overlaps_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_same_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_left_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_overleft_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_right_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_overright_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_below_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_overbelow_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_above_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_overabove_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_front_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_overfront_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_back_internal(BOX3D *box1, BOX3D *box2); -bool BOX3D_overback_internal(BOX3D *box1, BOX3D *box2); -double BOX3D_distance_internal(BOX3D *box1, BOX3D *box2); +#define SPGOverFrontStrategyNumber 28 /* for &> */ +#define SPGOverBackStrategyNumber 31 /* for /&> */ diff --git a/postgis/lwgeom_box3d.c b/postgis/lwgeom_box3d.c index 9f9ab0854..07d3f2674 100644 --- a/postgis/lwgeom_box3d.c +++ b/postgis/lwgeom_box3d.c @@ -18,24 +18,21 @@ * ********************************************************************** * - * ^copyright^ + * Copyright 2009 Mark Cave-Ayland + * Copyright 2009-2017 Paul Ramsey + * Copyright 2018 Darafei Praliaskouski * **********************************************************************/ - #include "postgres.h" #include "fmgr.h" #include "utils/elog.h" #include "utils/geo_decls.h" -/** needed for sp-gist support PostgreSQL 11+ **/ -#if POSTGIS_PGSQL_VERSION > 100 -#include "gserialized_spgist_3d.h" -#endif - #include "../postgis_config.h" #include "lwgeom_pg.h" #include "liblwgeom.h" +#include "lwgeom_box3d.h" #include #include @@ -44,45 +41,7 @@ #include #define SHOW_DIGS_DOUBLE 15 -#define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 +1) - -/* forward defs */ -Datum BOX3D_in(PG_FUNCTION_ARGS); -Datum BOX3D_out(PG_FUNCTION_ARGS); -Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS); -Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS); -Datum BOX3D_expand(PG_FUNCTION_ARGS); -Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS); -Datum BOX3D_to_BOX(PG_FUNCTION_ARGS); -Datum BOX3D_xmin(PG_FUNCTION_ARGS); -Datum BOX3D_ymin(PG_FUNCTION_ARGS); -Datum BOX3D_zmin(PG_FUNCTION_ARGS); -Datum BOX3D_xmax(PG_FUNCTION_ARGS); -Datum BOX3D_ymax(PG_FUNCTION_ARGS); -Datum BOX3D_zmax(PG_FUNCTION_ARGS); -Datum BOX3D_combine(PG_FUNCTION_ARGS); -Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS); - -/** needed for sp-gist support PostgreSQL 11+ **/ -#if POSTGIS_PGSQL_VERSION > 100 -Datum BOX3D_contains(PG_FUNCTION_ARGS); -Datum BOX3D_contained(PG_FUNCTION_ARGS); -Datum BOX3D_overlaps(PG_FUNCTION_ARGS); -Datum BOX3D_same(PG_FUNCTION_ARGS); -Datum BOX3D_left(PG_FUNCTION_ARGS); -Datum BOX3D_overleft(PG_FUNCTION_ARGS); -Datum BOX3D_right(PG_FUNCTION_ARGS) ; -Datum BOX3D_overright(PG_FUNCTION_ARGS); -Datum BOX3D_below(PG_FUNCTION_ARGS); -Datum BOX3D_overbelow(PG_FUNCTION_ARGS); -Datum BOX3D_above(PG_FUNCTION_ARGS); -Datum BOX3D_overabove(PG_FUNCTION_ARGS); -Datum BOX3D_front(PG_FUNCTION_ARGS); -Datum BOX3D_overfront(PG_FUNCTION_ARGS); -Datum BOX3D_back(PG_FUNCTION_ARGS); -Datum BOX3D_overback(PG_FUNCTION_ARGS); -Datum BOX3D_distance(PG_FUNCTION_ARGS); -#endif +#define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 + 1) /** * BOX3D_in - takes a string rep of BOX3D and returns internal rep @@ -91,7 +50,6 @@ Datum BOX3D_distance(PG_FUNCTION_ARGS); * "BOX3D(x1 y1 z1,x2 y2 z2)" * or "BOX3D(x1 y1,x2 y2)" z1 and z2 = 0.0 * - * */ PG_FUNCTION_INFO_V1(BOX3D_in); @@ -99,31 +57,34 @@ Datum BOX3D_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); int nitems; - BOX3D *box = (BOX3D *) palloc(sizeof(BOX3D)); + BOX3D *box = (BOX3D *)palloc(sizeof(BOX3D)); box->zmin = 0; box->zmax = 0; - - /*printf( "box3d_in gets '%s'\n",str); */ - - if (strstr(str,"BOX3D(") != str ) + if (strstr(str, "BOX3D(") != str) { pfree(box); - elog(ERROR,"BOX3D parser - doesn't start with BOX3D("); + elog(ERROR, "BOX3D parser - doesn't start with BOX3D("); PG_RETURN_NULL(); } - nitems = sscanf(str,"BOX3D(%le %le %le ,%le %le %le)", - &box->xmin, &box->ymin, &box->zmin, - &box->xmax, &box->ymax, &box->zmax); - if (nitems != 6 ) + nitems = sscanf(str, + "BOX3D(%le %le %le ,%le %le %le)", + &box->xmin, + &box->ymin, + &box->zmin, + &box->xmax, + &box->ymax, + &box->zmax); + if (nitems != 6) { - nitems = sscanf(str,"BOX3D(%le %le ,%le %le)", - &box->xmin, &box->ymin, &box->xmax, &box->ymax); + nitems = sscanf(str, "BOX3D(%le %le ,%le %le)", &box->xmin, &box->ymin, &box->xmax, &box->ymax); if (nitems != 4) { pfree(box); - elog(ERROR,"BOX3D parser - couldn't parse. It should look like: BOX3D(xmin ymin zmin,xmax ymax zmax) or BOX3D(xmin ymin,xmax ymax)"); + elog( + ERROR, + "BOX3D parser - couldn't parse. It should look like: BOX3D(xmin ymin zmin,xmax ymax zmax) or BOX3D(xmin ymin,xmax ymax)"); PG_RETURN_NULL(); } } @@ -150,7 +111,6 @@ Datum BOX3D_in(PG_FUNCTION_ARGS) PG_RETURN_POINTER(box); } - /** * Takes an internal rep of a BOX3D and returns a string rep. * @@ -160,31 +120,34 @@ Datum BOX3D_in(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(BOX3D_out); Datum BOX3D_out(PG_FUNCTION_ARGS) { - BOX3D *bbox = (BOX3D *) PG_GETARG_POINTER(0); + BOX3D *bbox = (BOX3D *)PG_GETARG_POINTER(0); int size; char *result; if (bbox == NULL) { result = palloc(5); - strcat(result,"NULL"); + strcat(result, "NULL"); PG_RETURN_CSTRING(result); } + /* double digits + "BOX3D"+ "()" + commas + null */ + size = MAX_DIGS_DOUBLE * 6 + 5 + 2 + 4 + 5 + 1; - /*double digits+ "BOX3D"+ "()" + commas +null */ - size = MAX_DIGS_DOUBLE*6+5+2+4+5+1; - - result = (char *) palloc(size); + result = (char *)palloc(size); - sprintf(result, "BOX3D(%.15g %.15g %.15g,%.15g %.15g %.15g)", - bbox->xmin, bbox->ymin, bbox->zmin, - bbox->xmax,bbox->ymax,bbox->zmax); + sprintf(result, + "BOX3D(%.15g %.15g %.15g,%.15g %.15g %.15g)", + bbox->xmin, + bbox->ymin, + bbox->zmin, + bbox->xmax, + bbox->ymax, + bbox->zmax); PG_RETURN_CSTRING(result); } - PG_FUNCTION_INFO_V1(BOX3D_to_BOX2D); Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS) { @@ -196,7 +159,8 @@ Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS) static void box3d_to_box_p(BOX3D *box, BOX *out) { - if ( ! box ) return; + if (!box) + return; out->low.x = box->xmin; out->low.y = box->ymin; @@ -215,7 +179,6 @@ Datum BOX3D_to_BOX(PG_FUNCTION_ARGS) PG_RETURN_POINTER(box); } - PG_FUNCTION_INFO_V1(BOX3D_to_LWGEOM); Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) { @@ -228,20 +191,18 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) * Alter BOX3D cast so that a valid geometry is always * returned depending upon the size of the BOX3D. The * code makes the following assumptions: - * - If the BOX3D is a single point then return a - * POINT geometry - * - If the BOX3D represents a line in any of X, Y - * or Z dimension, return a LINESTRING geometry - * - If the BOX3D represents a plane in the X, Y, - * or Z dimension, return a POLYGON geometry + * - If the BOX3D is a single point then return a POINT geometry + * - If the BOX3D represents a line in any of X, Y or Z dimension, + * return a LINESTRING geometry + * - If the BOX3D represents a plane in the X, Y, or Z dimension, + * return a POLYGON geometry * - Otherwise return a POLYHEDRALSURFACE geometry */ pa = ptarray_construct_empty(LW_TRUE, LW_FALSE, 5); /* BOX3D is a point */ - if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) && - (box->zmin == box->zmax) ) + if ((box->xmin == box->xmax) && (box->ymin == box->ymax) && (box->zmin == box->zmax)) { LWPOINT *lwpt = lwpoint_construct(SRID_UNKNOWN, NULL, pa); @@ -254,15 +215,9 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) lwpoint_free(lwpt); } /* BOX3D is a line */ - else if (((box->xmin == box->xmax || - box->ymin == box->ymax) && - box->zmin == box->zmax) || - ((box->xmin == box->xmax || - box->zmin == box->zmax) && - box->ymin == box->ymax) || - ((box->ymin == box->ymax || - box->zmin == box->zmax) && - box->xmin == box->xmax)) + else if (((box->xmin == box->xmax || box->ymin == box->ymax) && box->zmin == box->zmax) || + ((box->xmin == box->xmax || box->zmin == box->zmax) && box->ymin == box->ymax) || + ((box->ymin == box->ymax || box->zmin == box->zmax) && box->xmin == box->xmax)) { LWLINE *lwline = lwline_construct(SRID_UNKNOWN, NULL, pa); @@ -285,13 +240,12 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) LWPOLY *lwpoly; /* Initialize the 4 vertices of the polygon */ - points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 }; - points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin, 0.0 }; - points[2] = (POINT4D) { box->xmin, box->ymax, box->zmax, 0.0 }; - points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax, 0.0 }; + points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0}; + points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0}; + points[2] = (POINT4D){box->xmin, box->ymax, box->zmax, 0.0}; + points[3] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0}; - lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[0], &points[1], &points[2], &points[3]); + lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]); result = geometry_serialize(lwpoly_as_lwgeom(lwpoly)); lwpoly_free(lwpoly); } @@ -302,13 +256,12 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) LWPOLY *lwpoly; /* Initialize the 4 vertices of the polygon */ - points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 }; - points[1] = (POINT4D) { box->xmax, box->ymin, box->zmin, 0.0 }; - points[2] = (POINT4D) { box->xmax, box->ymin, box->zmax, 0.0 }; - points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax, 0.0 }; + points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0}; + points[1] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0}; + points[2] = (POINT4D){box->xmax, box->ymin, box->zmax, 0.0}; + points[3] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0}; - lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[0], &points[1], &points[2], &points[3]); + lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]); result = geometry_serialize(lwpoly_as_lwgeom(lwpoly)); lwpoly_free(lwpoly); } @@ -319,13 +272,12 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) LWPOLY *lwpoly; /* Initialize the 4 vertices of the polygon */ - points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 }; - points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin, 0.0 }; - points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin, 0.0 }; - points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin, 0.0 }; + points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0}; + points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0}; + points[2] = (POINT4D){box->xmax, box->ymax, box->zmin, 0.0}; + points[3] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0}; - lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[0], &points[1], &points[2], &points[3]); + lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]); result = geometry_serialize(lwpoly_as_lwgeom(lwpoly)); lwpoly_free(lwpoly); } @@ -334,45 +286,44 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) { POINT4D points[8]; static const int ngeoms = 6; - LWGEOM **geoms = (LWGEOM **) lwalloc(sizeof(LWGEOM *) * ngeoms); + LWGEOM **geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms); LWGEOM *geom = NULL; /* Initialize the 8 vertices of the box */ - points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 }; - points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin, 0.0 }; - points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin, 0.0 }; - points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin, 0.0 }; - points[4] = (POINT4D) { box->xmin, box->ymin, box->zmax, 0.0 }; - points[5] = (POINT4D) { box->xmin, box->ymax, box->zmax, 0.0 }; - points[6] = (POINT4D) { box->xmax, box->ymax, box->zmax, 0.0 }; - points[7] = (POINT4D) { box->xmax, box->ymin, box->zmax, 0.0 }; + points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0}; + points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0}; + points[2] = (POINT4D){box->xmax, box->ymax, box->zmin, 0.0}; + points[3] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0}; + points[4] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0}; + points[5] = (POINT4D){box->xmin, box->ymax, box->zmax, 0.0}; + points[6] = (POINT4D){box->xmax, box->ymax, box->zmax, 0.0}; + points[7] = (POINT4D){box->xmax, box->ymin, box->zmax, 0.0}; /* add bottom polygon */ - geoms[0] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[0], &points[1], &points[2], &points[3])); + geoms[0] = lwpoly_as_lwgeom( + lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3])); /* add top polygon */ - geoms[1] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[4], &points[7], &points[6], &points[5])); + geoms[1] = lwpoly_as_lwgeom( + lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[4], &points[7], &points[6], &points[5])); /* add left polygon */ - geoms[2] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[0], &points[4], &points[5], &points[1])); + geoms[2] = lwpoly_as_lwgeom( + lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[4], &points[5], &points[1])); /* add right polygon */ - geoms[3] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[3], &points[2], &points[6], &points[7])); + geoms[3] = lwpoly_as_lwgeom( + lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[3], &points[2], &points[6], &points[7])); /* add front polygon */ - geoms[4] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[0], &points[3], &points[7], &points[4])); + geoms[4] = lwpoly_as_lwgeom( + lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[3], &points[7], &points[4])); /* add back polygon */ - geoms[5] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, - &points[1], &points[5], &points[6], &points[2])); + geoms[5] = lwpoly_as_lwgeom( + lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[1], &points[5], &points[6], &points[2])); - geom = (LWGEOM *) lwcollection_construct(POLYHEDRALSURFACETYPE, - SRID_UNKNOWN, NULL, ngeoms, geoms); + geom = (LWGEOM *)lwcollection_construct(POLYHEDRALSURFACETYPE, SRID_UNKNOWN, NULL, ngeoms, geoms); FLAGS_SET_SOLID(geom->flags, 1); result = geometry_serialize(geom); - lwcollection_free((LWCOLLECTION *) geom); + lwcollection_free((LWCOLLECTION *)geom); } gserialized_set_srid(result, box->srid); @@ -411,7 +362,8 @@ Datum BOX3D_expand(PG_FUNCTION_ARGS) BOX3D *result = (BOX3D *)palloc(sizeof(BOX3D)); memcpy(result, box, sizeof(BOX3D)); - if (PG_NARGS() == 2) { + if (PG_NARGS() == 2) + { /* Expand the box the same amount in all directions */ double d = PG_GETARG_FLOAT8(1); expand_box3d(result, d); @@ -431,8 +383,7 @@ Datum BOX3D_expand(PG_FUNCTION_ARGS) /** * convert a GSERIALIZED to BOX3D * - * NOTE: the bounding box is *always* recomputed as the cache - * is a box2d, not a box3d... + * NOTE: the bounding box is always recomputed as the cache is a BOX2D, not a BOX3D. * */ PG_FUNCTION_INFO_V1(LWGEOM_to_BOX3D); @@ -444,7 +395,7 @@ Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS) BOX3D *result; int rv = lwgeom_calculate_gbox(lwgeom, &gbox); - if ( rv == LW_FAILURE ) + if (rv == LW_FAILURE) PG_RETURN_NULL(); result = box3d_from_gbox(&gbox); @@ -497,15 +448,15 @@ Datum BOX3D_zmax(PG_FUNCTION_ARGS) } /** -* Used in the ST_Extent and ST_Extent3D aggregates, does not read the -* serialized cached bounding box (since that is floating point) -* but calculates the box in full from the underlying geometry. -*/ + * Used in the ST_Extent and ST_Extent3D aggregates, does not read the + * serialized cached bounding box (since that is floating point) + * but calculates the box in full from the underlying geometry. + */ PG_FUNCTION_INFO_V1(BOX3D_combine); Datum BOX3D_combine(PG_FUNCTION_ARGS) { - BOX3D *box = (BOX3D*)PG_GETARG_POINTER(0); - GSERIALIZED *geom = PG_ARGISNULL(1) ? NULL : (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_POINTER(1)); + BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0); + GSERIALIZED *geom = PG_ARGISNULL(1) ? NULL : (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_POINTER(1)); LWGEOM *lwgeom = NULL; BOX3D *result = NULL; GBOX gbox; @@ -513,28 +464,33 @@ Datum BOX3D_combine(PG_FUNCTION_ARGS) int rv; /* Can't do anything with null inputs */ - if ((box == NULL) && (geom == NULL)) { PG_RETURN_NULL(); } + if (!box && !geom) + { + PG_RETURN_NULL(); + } /* Null geometry but non-null box, return the box */ - else if (geom == NULL) + else if (!geom) { result = palloc(sizeof(BOX3D)); memcpy(result, box, sizeof(BOX3D)); PG_RETURN_POINTER(result); } - /* Deserialize geometry and *calculate* the box */ - /* We can't use the cached box because it's float, we *must* calculate */ + /* + * Deserialize geometry and *calculate* the box + * We can't use the cached box because it's float, we *must* calculate + */ lwgeom = lwgeom_from_gserialized(geom); srid = lwgeom->srid; rv = lwgeom_calculate_gbox(lwgeom, &gbox); lwgeom_free(lwgeom); /* If we couldn't calculate the box, return what we know */ - if ( rv == LW_FAILURE ) + if (rv == LW_FAILURE) { PG_FREE_IF_COPY(geom, 1); /* No geom box, no input box, so null return */ - if ( box == NULL ) + if (!box) PG_RETURN_NULL(); result = palloc(sizeof(BOX3D)); memcpy(result, box, sizeof(BOX3D)); @@ -542,7 +498,7 @@ Datum BOX3D_combine(PG_FUNCTION_ARGS) } /* Null box and non-null geometry, just return the geometry box */ - if ( box == NULL ) + if (!box) { PG_FREE_IF_COPY(geom, 1); result = box3d_from_gbox(&gbox); @@ -566,8 +522,8 @@ Datum BOX3D_combine(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(BOX3D_combine_BOX3D); Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS) { - BOX3D *box0 = (BOX3D*)(PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0)); - BOX3D *box1 = (BOX3D*)(PG_ARGISNULL(1) ? NULL : PG_GETARG_POINTER(1)); + BOX3D *box0 = (BOX3D *)(PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0)); + BOX3D *box1 = (BOX3D *)(PG_ARGISNULL(1) ? NULL : PG_GETARG_POINTER(1)); BOX3D *result; if (box0 && !box1) @@ -603,8 +559,7 @@ Datum BOX3D_construct(PG_FUNCTION_ARGS) minpoint = lwgeom_from_gserialized(min); maxpoint = lwgeom_from_gserialized(max); - if ( minpoint->type != POINTTYPE || - maxpoint->type != POINTTYPE ) + if (minpoint->type != POINTTYPE || maxpoint->type != POINTTYPE) { elog(ERROR, "BOX3D_construct: args must be points"); PG_RETURN_NULL(); @@ -635,22 +590,17 @@ Datum BOX3D_construct(PG_FUNCTION_ARGS) *****************************************************************************/ /* contains? */ - bool BOX3D_contains_internal(BOX3D *box1, BOX3D *box2) { - return (box1->xmax >= box2->xmax && - box1->xmin <= box2->xmin && - box1->ymax >= box2->ymax && - box1->ymin <= box2->ymin && - box1->zmax >= box2->zmax && - box1->zmin <= box2->zmin); + return (box1->xmax >= box2->xmax && box1->xmin <= box2->xmin) && + (box1->ymax >= box2->ymax && box1->ymin <= box2->ymin) && + (box1->zmax >= box2->zmax && box1->zmin <= box2->zmin); } PG_FUNCTION_INFO_V1(BOX3D_contains); -PGDLLEXPORT Datum -BOX3D_contains(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_contains(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -659,7 +609,6 @@ BOX3D_contains(PG_FUNCTION_ARGS) } /* contained by? */ - bool BOX3D_contained_internal(BOX3D *box1, BOX3D *box2) { @@ -668,8 +617,7 @@ BOX3D_contained_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_contained); -PGDLLEXPORT Datum -BOX3D_contained(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_contained(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -678,22 +626,17 @@ BOX3D_contained(PG_FUNCTION_ARGS) } /* overlaps? */ - bool BOX3D_overlaps_internal(BOX3D *box1, BOX3D *box2) { - return (box1->xmin <= box2->xmax && - box2->xmin <= box1->xmax && - box1->ymin <= box2->ymax && - box2->ymin <= box1->ymax && - box1->zmin <= box2->zmax && - box2->zmin <= box1->zmax); + return (box1->xmin <= box2->xmax && box2->xmin <= box1->xmax) && + (box1->ymin <= box2->ymax && box2->ymin <= box1->ymax) && + (box1->zmin <= box2->zmax && box2->zmin <= box1->zmax); } PG_FUNCTION_INFO_V1(BOX3D_overlaps); -PGDLLEXPORT Datum -BOX3D_overlaps(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_overlaps(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -702,22 +645,17 @@ BOX3D_overlaps(PG_FUNCTION_ARGS) } /* same? */ - bool BOX3D_same_internal(BOX3D *box1, BOX3D *box2) { - return (FPeq(box1->xmax, box2->xmax) && - FPeq(box1->xmin, box2->xmin) && - FPeq(box1->ymax, box2->ymax) && - FPeq(box1->ymin, box2->ymin) && - FPeq(box1->zmax, box2->zmax) && - FPeq(box1->zmin, box2->zmin)); + return (FPeq(box1->xmax, box2->xmax) && FPeq(box1->xmin, box2->xmin)) && + (FPeq(box1->ymax, box2->ymax) && FPeq(box1->ymin, box2->ymin)) && + (FPeq(box1->zmax, box2->zmax) && FPeq(box1->zmin, box2->zmin)); } PG_FUNCTION_INFO_V1(BOX3D_same); -PGDLLEXPORT Datum -BOX3D_same(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_same(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -726,7 +664,6 @@ BOX3D_same(PG_FUNCTION_ARGS) } /* strictly left of? */ - bool BOX3D_left_internal(BOX3D *box1, BOX3D *box2) { @@ -735,8 +672,7 @@ BOX3D_left_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_left); -PGDLLEXPORT Datum -BOX3D_left(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_left(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -745,7 +681,6 @@ BOX3D_left(PG_FUNCTION_ARGS) } /* does not extend to right of? */ - bool BOX3D_overleft_internal(BOX3D *box1, BOX3D *box2) { @@ -754,8 +689,7 @@ BOX3D_overleft_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_overleft); -PGDLLEXPORT Datum -BOX3D_overleft(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_overleft(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -764,7 +698,6 @@ BOX3D_overleft(PG_FUNCTION_ARGS) } /* strictly right of? */ - bool BOX3D_right_internal(BOX3D *box1, BOX3D *box2) { @@ -773,8 +706,7 @@ BOX3D_right_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_right); -PGDLLEXPORT Datum -BOX3D_right(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_right(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -783,7 +715,6 @@ BOX3D_right(PG_FUNCTION_ARGS) } /* does not extend to left of? */ - bool BOX3D_overright_internal(BOX3D *box1, BOX3D *box2) { @@ -792,8 +723,7 @@ BOX3D_overright_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_overright); -PGDLLEXPORT Datum -BOX3D_overright(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_overright(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -802,7 +732,6 @@ BOX3D_overright(PG_FUNCTION_ARGS) } /* strictly below of? */ - bool BOX3D_below_internal(BOX3D *box1, BOX3D *box2) { @@ -811,8 +740,7 @@ BOX3D_below_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_below); -PGDLLEXPORT Datum -BOX3D_below(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_below(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -821,7 +749,6 @@ BOX3D_below(PG_FUNCTION_ARGS) } /* does not extend above of? */ - bool BOX3D_overbelow_internal(BOX3D *box1, BOX3D *box2) { @@ -830,8 +757,7 @@ BOX3D_overbelow_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_overbelow); -PGDLLEXPORT Datum -BOX3D_overbelow(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_overbelow(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -840,7 +766,6 @@ BOX3D_overbelow(PG_FUNCTION_ARGS) } /* strictly above of? */ - bool BOX3D_above_internal(BOX3D *box1, BOX3D *box2) { @@ -849,8 +774,7 @@ BOX3D_above_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_above); -PGDLLEXPORT Datum -BOX3D_above(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_above(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -859,7 +783,6 @@ BOX3D_above(PG_FUNCTION_ARGS) } /* does not extend below of? */ - bool BOX3D_overabove_internal(BOX3D *box1, BOX3D *box2) { @@ -868,8 +791,7 @@ BOX3D_overabove_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_overabove); -PGDLLEXPORT Datum -BOX3D_overabove(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_overabove(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -878,7 +800,6 @@ BOX3D_overabove(PG_FUNCTION_ARGS) } /* strictly in before of? */ - bool BOX3D_front_internal(BOX3D *box1, BOX3D *box2) { @@ -887,8 +808,7 @@ BOX3D_front_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_front); -PGDLLEXPORT Datum -BOX3D_front(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_front(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -897,7 +817,6 @@ BOX3D_front(PG_FUNCTION_ARGS) } /* does not extend to the after of? */ - bool BOX3D_overfront_internal(BOX3D *box1, BOX3D *box2) { @@ -906,8 +825,7 @@ BOX3D_overfront_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_overfront); -PGDLLEXPORT Datum -BOX3D_overfront(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_overfront(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -916,7 +834,6 @@ BOX3D_overfront(PG_FUNCTION_ARGS) } /* strictly after of? */ - bool BOX3D_back_internal(BOX3D *box1, BOX3D *box2) { @@ -925,8 +842,7 @@ BOX3D_back_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_back); -PGDLLEXPORT Datum -BOX3D_back(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_back(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -935,7 +851,6 @@ BOX3D_back(PG_FUNCTION_ARGS) } /* does not extend to the before of? */ - bool BOX3D_overback_internal(BOX3D *box1, BOX3D *box2) { @@ -944,8 +859,7 @@ BOX3D_overback_internal(BOX3D *box1, BOX3D *box2) PG_FUNCTION_INFO_V1(BOX3D_overback); -PGDLLEXPORT Datum -BOX3D_overback(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_overback(PG_FUNCTION_ARGS) { BOX3D *box1 = PG_GETARG_BOX3D_P(0); BOX3D *box2 = PG_GETARG_BOX3D_P(1); @@ -954,60 +868,58 @@ BOX3D_overback(PG_FUNCTION_ARGS) } /* Minimum distance between 2 bounding boxes */ - double BOX3D_distance_internal(BOX3D *box1, BOX3D *box2) { - double sqrDist = 0; - double d; - - if (BOX3D_overlaps_internal(box1, box2)) - return 0.0; - - /* X axis */ - if (box1->xmax < box2->xmin) - { - d = box1->xmax - box2->xmin; - sqrDist += d * d; - } - else if (box1->xmin > box2->xmax) - { - d = box1->xmin - box2->xmax; - sqrDist += d * d; - } - /* Y axis */ - if (box1->ymax < box2->ymin) - { - d = box1->ymax - box2->ymin; - sqrDist += d * d; - } - else if (box1->ymin > box2->ymax) - { - d = box1->ymin - box2->ymax; - sqrDist += d * d; - } - /* Z axis */ - if (box1->zmax < box2->zmin) - { - d = box1->zmax - box2->zmin; - sqrDist += d * d; - } - else if (box1->zmin > box2->zmax) - { - d = box1->zmin - box2->zmax; - sqrDist += d * d; - } - - return sqrt(sqrDist); + double sqrDist = 0; + double d; + + if (BOX3D_overlaps_internal(box1, box2)) + return 0.0; + + /* X axis */ + if (box1->xmax < box2->xmin) + { + d = box1->xmax - box2->xmin; + sqrDist += d * d; + } + else if (box1->xmin > box2->xmax) + { + d = box1->xmin - box2->xmax; + sqrDist += d * d; + } + /* Y axis */ + if (box1->ymax < box2->ymin) + { + d = box1->ymax - box2->ymin; + sqrDist += d * d; + } + else if (box1->ymin > box2->ymax) + { + d = box1->ymin - box2->ymax; + sqrDist += d * d; + } + /* Z axis */ + if (box1->zmax < box2->zmin) + { + d = box1->zmax - box2->zmin; + sqrDist += d * d; + } + else if (box1->zmin > box2->zmax) + { + d = box1->zmin - box2->zmax; + sqrDist += d * d; + } + + return sqrt(sqrDist); } PG_FUNCTION_INFO_V1(BOX3D_distance); -PGDLLEXPORT Datum -BOX3D_distance(PG_FUNCTION_ARGS) +PGDLLEXPORT Datum BOX3D_distance(PG_FUNCTION_ARGS) { - BOX3D *box1 = PG_GETARG_BOX3D_P(0); - BOX3D *box2 = PG_GETARG_BOX3D_P(1); - PG_RETURN_FLOAT8(BOX3D_distance_internal(box1, box2)); + BOX3D *box1 = PG_GETARG_BOX3D_P(0); + BOX3D *box2 = PG_GETARG_BOX3D_P(1); + PG_RETURN_FLOAT8(BOX3D_distance_internal(box1, box2)); } #endif diff --git a/postgis/lwgeom_box3d.h b/postgis/lwgeom_box3d.h new file mode 100644 index 000000000..bcacb533a --- /dev/null +++ b/postgis/lwgeom_box3d.h @@ -0,0 +1,85 @@ +/********************************************************************** + * + * PostGIS - Spatial Types for PostgreSQL + * http://postgis.net + * + * PostGIS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * PostGIS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PostGIS. If not, see . + * + ********************************************************************** + * + * Copyright 2009 Mark Cave-Ayland + * Copyright 2009-2017 Paul Ramsey + * Copyright 2018 Darafei Praliaskouski + * + **********************************************************************/ + +/* forward defs */ +Datum BOX3D_in(PG_FUNCTION_ARGS); +Datum BOX3D_out(PG_FUNCTION_ARGS); +Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS); +Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS); +Datum BOX3D_expand(PG_FUNCTION_ARGS); +Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS); +Datum BOX3D_to_BOX(PG_FUNCTION_ARGS); +Datum BOX3D_xmin(PG_FUNCTION_ARGS); +Datum BOX3D_ymin(PG_FUNCTION_ARGS); +Datum BOX3D_zmin(PG_FUNCTION_ARGS); +Datum BOX3D_xmax(PG_FUNCTION_ARGS); +Datum BOX3D_ymax(PG_FUNCTION_ARGS); +Datum BOX3D_zmax(PG_FUNCTION_ARGS); +Datum BOX3D_combine(PG_FUNCTION_ARGS); +Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS); + +/***************************************************************************** + * BOX3D operators + *****************************************************************************/ + +bool BOX3D_contains_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_contained_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_overlaps_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_same_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_left_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_overleft_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_right_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_overright_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_below_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_overbelow_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_above_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_overabove_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_front_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_overfront_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_back_internal(BOX3D *box1, BOX3D *box2); +bool BOX3D_overback_internal(BOX3D *box1, BOX3D *box2); +double BOX3D_distance_internal(BOX3D *box1, BOX3D *box2); + +/** needed for sp-gist support PostgreSQL 11+ **/ +#if POSTGIS_PGSQL_VERSION > 100 +Datum BOX3D_contains(PG_FUNCTION_ARGS); +Datum BOX3D_contained(PG_FUNCTION_ARGS); +Datum BOX3D_overlaps(PG_FUNCTION_ARGS); +Datum BOX3D_same(PG_FUNCTION_ARGS); +Datum BOX3D_left(PG_FUNCTION_ARGS); +Datum BOX3D_overleft(PG_FUNCTION_ARGS); +Datum BOX3D_right(PG_FUNCTION_ARGS); +Datum BOX3D_overright(PG_FUNCTION_ARGS); +Datum BOX3D_below(PG_FUNCTION_ARGS); +Datum BOX3D_overbelow(PG_FUNCTION_ARGS); +Datum BOX3D_above(PG_FUNCTION_ARGS); +Datum BOX3D_overabove(PG_FUNCTION_ARGS); +Datum BOX3D_front(PG_FUNCTION_ARGS); +Datum BOX3D_overfront(PG_FUNCTION_ARGS); +Datum BOX3D_back(PG_FUNCTION_ARGS); +Datum BOX3D_overback(PG_FUNCTION_ARGS); +Datum BOX3D_distance(PG_FUNCTION_ARGS); +#endif