/* Returns bounding box of a given quadrant inside given bounding box */ static BOX *
getQuadrantArea(BOX *bbox, Point *centroid, int quadrant)
{
BOX *result = (BOX *) palloc(sizeof(BOX));
Datum
spg_quad_choose(PG_FUNCTION_ARGS)
{
spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0);
spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1);
Point *inPoint = DatumGetPointP(in->datum),
*centroid;
if (in->allTheSame)
{
out->resultType = spgMatchNode; /* nodeN will be set by core */
out->result.matchNode.levelAdd = 0;
out->result.matchNode.restDatum = PointPGetDatum(inPoint);
PG_RETURN_VOID();
}
Datum
spg_quad_picksplit(PG_FUNCTION_ARGS)
{
spgPickSplitIn *in = (spgPickSplitIn *) PG_GETARG_POINTER(0);
spgPickSplitOut *out = (spgPickSplitOut *) PG_GETARG_POINTER(1); int i;
Point *centroid;
#ifdef USE_MEDIAN /* Use the median values of x and y as the centroid point */
Point **sorted;
sorted = palloc(sizeof(*sorted) * in->nTuples); for (i = 0; i < in->nTuples; i++)
sorted[i] = DatumGetPointP(in->datums[i]);
centroid = palloc(sizeof(*centroid));
qsort(sorted, in->nTuples, sizeof(*sorted), x_cmp);
centroid->x = sorted[in->nTuples >> 1]->x;
qsort(sorted, in->nTuples, sizeof(*sorted), y_cmp);
centroid->y = sorted[in->nTuples >> 1]->y; #else /* Use the average values of x and y as the centroid point */
centroid = palloc0(sizeof(*centroid));
for (i = 0; i < in->nTuples; i++)
{
centroid->x += DatumGetPointP(in->datums[i])->x;
centroid->y += DatumGetPointP(in->datums[i])->y;
}
if (in->allTheSame)
{ /* Report that all nodes should be visited */
out->nNodes = in->nNodes;
out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); for (i = 0; i < in->nNodes; i++)
{
out->nodeNumbers[i] = i;
if (in->norderbys > 0)
{
MemoryContext oldCtx = MemoryContextSwitchTo(in->traversalMemoryContext);
/* Use parent quadrant box as traversalValue */
BOX *quadrant = box_copy(bbox);
/* "which" is a bitmask of quadrants that satisfy all constraints */
which = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
for (i = 0; i < in->nkeys; i++)
{
Point *query = DatumGetPointP(in->scankeys[i].sk_argument);
BOX *boxQuery;
switch (in->scankeys[i].sk_strategy)
{ case RTLeftStrategyNumber: if (SPTEST(point_right, centroid, query))
which &= (1 << 3) | (1 << 4); break; case RTRightStrategyNumber: if (SPTEST(point_left, centroid, query))
which &= (1 << 1) | (1 << 2); break; case RTSameStrategyNumber:
which &= (1 << getQuadrant(centroid, query)); break; case RTBelowStrategyNumber: case RTOldBelowStrategyNumber: if (SPTEST(point_above, centroid, query))
which &= (1 << 2) | (1 << 3); break; case RTAboveStrategyNumber: case RTOldAboveStrategyNumber: if (SPTEST(point_below, centroid, query))
which &= (1 << 1) | (1 << 4); break; case RTContainedByStrategyNumber:
if (DatumGetBool(DirectFunctionCall2(box_contain_pt,
PointerGetDatum(boxQuery),
PointerGetDatum(centroid))))
{ /* centroid is in box, so all quadrants are OK */
} else
{ /* identify quadrant(s) containing all corners of box */
Point p; int r = 0;
p = boxQuery->low;
r |= 1 << getQuadrant(centroid, &p);
p.y = boxQuery->high.y;
r |= 1 << getQuadrant(centroid, &p);
p = boxQuery->high;
r |= 1 << getQuadrant(centroid, &p);
p.x = boxQuery->low.x;
r |= 1 << getQuadrant(centroid, &p);
Datum
spg_quad_leaf_consistent(PG_FUNCTION_ARGS)
{
spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0);
spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1);
Point *datum = DatumGetPointP(in->leafDatum); bool res; int i;
/* all tests are exact */
out->recheck = false;
/* leafDatum is what it is... */
out->leafValue = in->leafDatum;
/* Perform the required comparison(s) */
res = true; for (i = 0; i < in->nkeys; i++)
{
Point *query = DatumGetPointP(in->scankeys[i].sk_argument);
switch (in->scankeys[i].sk_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: case RTOldBelowStrategyNumber:
res = SPTEST(point_below, datum, query); break; case RTAboveStrategyNumber: case RTOldAboveStrategyNumber:
res = SPTEST(point_above, datum, query); break; case RTContainedByStrategyNumber:
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.