/*****************************************************************************
**
** Function name:
**
** MyShapeUnion
**
** Description:
**
** This is an R-Tree support function which enables
** the server to maintain an R-Tree index. It computes the
** union of two objects' bounding boxes.
**
** Special Comments:
**
** Because MyShape and its subtypes are variable length opaque
** datatypes, the UDT instances are passed in from the server
** wrapped in mi_lvarchars.
**
** Parameters:
**
** mi_lvarchar *in1, *in2 UDT instances to be unioned together.
** mi_lvarchar *out Resulting union.
** MI_FPARAM *fp UDR function parameter & state info.
**
** Return value:
**
** mi_integer MI_OK if success, MI_ERROR if problems.
**
*****************************************************************************/
UDREXPORT mi_integer
MyShapeUnion (mi_lvarchar *shape_in1,
mi_lvarchar *shape_in2,
mi_lvarchar *shape_out,
MI_FPARAM *fp)
{
MyShapeHdr *h1;
MyShapeHdr *h2;
MyShapeHdr *h3;
SHAPE_TRACE_ENTER (MyShapeUnion);
h1 = (MyShapeHdr *) mi_get_vardata (shape_in1);
h2 = (MyShapeHdr *) mi_get_vardata (shape_in2);
h3 = (MyShapeHdr *) mi_get_vardata (shape_out);
CheckVersion (h1->version);
CheckVersion (h2->version);
if (h1 == h2)
{
/*
* This is a 'self-union', which is how the R-Tree determines how
* big your header structure is. This situation will occur just
* once, on the first index insert operation.
*/
h3->version = SHAPE_VERSION;
h3->tag = MyHeaderTag;
h3->xmin = h1->xmin;
h3->ymin = h1->ymin;
h3->xmax = h1->xmax;
h3->ymax = h1->ymax;
}
else
{
/*
* CAUTION! h1 and h3 may both reference the same structure!
* Likewise, h2 and h3 may both reference the same structure!
* This is because the R-Tree reuses variables to save memory.
* This means we have to be careful not to prematurely overwrite
* any elements of h1 or h2 as we assign values to h3.
* The following algorithm is safe in this regard.
*/
h3->version = SHAPE_VERSION;
h3->tag = MyHeaderTag;
h3->xmin = (h1->xmin < h2->xmin) ? h1->xmin : h2->xmin;
h3->ymin = (h1->ymin < h2->ymin) ? h1->ymin : h2->ymin;
h3->xmax = (h1->xmax > h2->xmax) ? h1->xmax : h2->xmax;
h3->ymax = (h1->ymax > h2->ymax) ? h1->ymax : h2->ymax;
}
/*
* Set the size of the mi_lvarchar to tell the R-Tree how
* big each element to be stored on internal node pages will be.
* IMPORTANT NOTE: You must do this in every Union() call,
* not just the first one (where h1 == h2).
*/
mi_set_varlen (shape_out, sizeof(MyShapeHdr));
SHAPE_TRACE_EXIT (MyShapeUnion);
return MI_OK;
}