Datum spg_quad_leaf_consistent(PG_FUNCTION_ARGS) { /*int level = PG_GETARG_INT32(0);*/ Point *query = PG_GETARG_POINT_P(1); Point *datum = PG_GETARG_POINT_P(2); bool res; res = SPTEST(eq, datum, query); PG_RETURN_BOOL(res); }
Datum spg_quad_leaf_consistent(PG_FUNCTION_ARGS) { spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0); spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1); Point *query = DatumGetPointP(in->query); Point *datum = DatumGetPointP(in->leafDatum); bool res; /* all tests are exact */ out->recheck = false; /* leafDatum is what it is... */ out->leafValue = in->leafDatum; switch (in->strategy) { case RTLeftStrategyNumber: res = SPTEST(point_left, datum, query); break; case RTRightStrategyNumber: res = SPTEST(point_right, datum, query); break; case RTSameStrategyNumber: res = SPTEST(point_eq, datum, query); break; case RTBelowStrategyNumber: res = SPTEST(point_below, datum, query); break; case RTAboveStrategyNumber: res = SPTEST(point_above, datum, query); break; case RTContainedByStrategyNumber: /* * For this operator, the query is a box not a point. We cheat to * the extent of assuming that DatumGetPointP won't do anything * that would be bad for a pointer-to-box. */ res = SPTEST(box_contain_pt, query, datum); break; default: elog(ERROR, "unrecognized strategy number: %d", in->strategy); res = false; break; } PG_RETURN_BOOL(res); }
/* * Determine which quadrant a point falls into, relative to the centroid. * * Quadrants are identified like this: * * 4 | 1 * ----+----- * 3 | 2 * * Points on one of the axes are taken to lie in the lowest-numbered * adjacent quadrant. */ static int2 getQuadrant(Point *centroid, Point *tst) { if ((SPTEST(point_above, tst, centroid) || SPTEST(point_horiz, tst, centroid)) && (SPTEST(point_right, tst, centroid) || SPTEST(point_vert, tst, centroid))) return 1; if (SPTEST(point_below, tst, centroid) && (SPTEST(point_right, tst, centroid) || SPTEST(point_vert, tst, centroid))) return 2; if ((SPTEST(point_below, tst, centroid) || SPTEST(point_horiz, tst, centroid)) && SPTEST(point_left, tst, centroid)) return 3; if (SPTEST(point_above, tst, centroid) && SPTEST(point_left, tst, centroid)) return 4; elog(ERROR, "getQuadrant: impossible case"); return 0; }
Datum spg_quad_inner_consistent(PG_FUNCTION_ARGS) { spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); Point *query, *centroid; BOX *boxQuery; query = DatumGetPointP(in->query); Assert(in->hasPrefix); centroid = DatumGetPointP(in->prefixDatum); if (in->allTheSame) { /* Report that all nodes should be visited */ int i; out->nNodes = in->nNodes; out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); for (i = 0; i < in->nNodes; i++) out->nodeNumbers[i] = i; PG_RETURN_VOID(); } Assert(in->nNodes == 4); out->nodeNumbers = (int *) palloc(sizeof(int) * 4); switch (in->strategy) { case RTLeftStrategyNumber: setNodes(out, SPTEST(point_left, centroid, query), 3, 4); break; case RTRightStrategyNumber: setNodes(out, SPTEST(point_right, centroid, query), 1, 2); break; case RTSameStrategyNumber: out->nNodes = 1; out->nodeNumbers[0] = getQuadrant(centroid, query) - 1; break; case RTBelowStrategyNumber: setNodes(out, SPTEST(point_below, centroid, query), 2, 3); break; case RTAboveStrategyNumber: setNodes(out, SPTEST(point_above, centroid, query), 1, 4); break; case RTContainedByStrategyNumber: /* * For this operator, the query is a box not a point. We cheat to * the extent of assuming that DatumGetPointP won't do anything * that would be bad for a pointer-to-box. */ boxQuery = DatumGetBoxP(in->query); if (DatumGetBool(DirectFunctionCall2(box_contain_pt, PointerGetDatum(boxQuery), PointerGetDatum(centroid)))) { /* centroid is in box, so descend to all quadrants */ setNodes(out, true, 0, 0); } else { /* identify quadrant(s) containing all corners of box */ Point p; int i, r = 0; p = boxQuery->low; r |= 1 << (getQuadrant(centroid, &p) - 1); p.y = boxQuery->high.y; r |= 1 << (getQuadrant(centroid, &p) - 1); p = boxQuery->high; r |= 1 << (getQuadrant(centroid, &p) - 1); p.x = boxQuery->low.x; r |= 1 << (getQuadrant(centroid, &p) - 1); /* we must descend into those quadrant(s) */ out->nNodes = 0; for (i = 0; i < 4; i++) { if (r & (1 << i)) { out->nodeNumbers[out->nNodes] = i; out->nNodes++; } } } break; default: elog(ERROR, "unrecognized strategy number: %d", in->strategy); break; } PG_RETURN_VOID(); }
static int2 getQuadrant(Point *centroid, Point *tst) { if ( (SPTEST(above, tst, centroid) || SPTEST(horiz, tst, centroid)) && (SPTEST(right, tst, centroid) || SPTEST(vert, tst, centroid)) ) return 1; if ( SPTEST(below, tst, centroid) && (SPTEST(right, tst, centroid) || SPTEST(vert, tst, centroid)) ) return 2; if ( (SPTEST(below, tst, centroid) || SPTEST(horiz, tst, centroid))&& SPTEST(left, tst, centroid) ) return 3; if ( SPTEST(above, tst, centroid) && SPTEST(left, tst, centroid) ) return 4; elog(ERROR, "getQuadrant: could not be here"); return 0; }