📄 geo_ops.c
字号:
PG_RETURN_BOOL(FPgt(box1->low.x, box2->high.x));}/* box_overright - is the left edge of box1 at or right of * the left edge of box2? * * This is "greater than or equal" for time ranges, when time ranges * are stored as rectangles. */Datumbox_overright(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPge(box1->low.x, box2->low.x));}/* box_below - is box1 strictly below box2? */Datumbox_below(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPlt(box1->high.y, box2->low.y));}/* box_overbelow - is the upper edge of box1 at or below * the upper edge of box2? */Datumbox_overbelow(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPle(box1->high.y, box2->high.y));}/* box_above - is box1 strictly above box2? */Datumbox_above(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPgt(box1->low.y, box2->high.y));}/* box_overabove - is the lower edge of box1 at or above * the lower edge of box2? */Datumbox_overabove(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPge(box1->low.y, box2->low.y));}/* box_contained - is box1 contained by box2? */Datumbox_contained(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x) && FPge(box1->low.x, box2->low.x) && FPle(box1->high.y, box2->high.y) && FPge(box1->low.y, box2->low.y));}/* box_contain - does box1 contain box2? */Datumbox_contain(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPge(box1->high.x, box2->high.x) && FPle(box1->low.x, box2->low.x) && FPge(box1->high.y, box2->high.y) && FPle(box1->low.y, box2->low.y));}/* box_positionop - * is box1 entirely {above,below} box2? * * box_below_eq and box_above_eq are obsolete versions that (probably * erroneously) accept the equal-boundaries case. Since these are not * in sync with the box_left and box_right code, they are deprecated and * not supported in the PG 8.1 rtree operator class extension. */Datumbox_below_eq(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));}Datumbox_above_eq(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));}/* box_relop - is area(box1) relop area(box2), within * our accuracy constraint? */Datumbox_lt(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPlt(box_ar(box1), box_ar(box2)));}Datumbox_gt(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPgt(box_ar(box1), box_ar(box2)));}Datumbox_eq(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPeq(box_ar(box1), box_ar(box2)));}Datumbox_le(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPle(box_ar(box1), box_ar(box2)));}Datumbox_ge(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(FPge(box_ar(box1), box_ar(box2)));}/*---------------------------------------------------------- * "Arithmetic" operators on boxes. *---------------------------------------------------------*//* box_area - returns the area of the box. */Datumbox_area(PG_FUNCTION_ARGS){ BOX *box = PG_GETARG_BOX_P(0); PG_RETURN_FLOAT8(box_ar(box));}/* box_width - returns the width of the box * (horizontal magnitude). */Datumbox_width(PG_FUNCTION_ARGS){ BOX *box = PG_GETARG_BOX_P(0); PG_RETURN_FLOAT8(box->high.x - box->low.x);}/* box_height - returns the height of the box * (vertical magnitude). */Datumbox_height(PG_FUNCTION_ARGS){ BOX *box = PG_GETARG_BOX_P(0); PG_RETURN_FLOAT8(box->high.y - box->low.y);}/* box_distance - returns the distance between the * center points of two boxes. */Datumbox_distance(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); Point a, b; box_cn(&a, box1); box_cn(&b, box2); PG_RETURN_FLOAT8(HYPOT(a.x - b.x, a.y - b.y));}/* box_center - returns the center point of the box. */Datumbox_center(PG_FUNCTION_ARGS){ BOX *box = PG_GETARG_BOX_P(0); Point *result = (Point *) palloc(sizeof(Point)); box_cn(result, box); PG_RETURN_POINT_P(result);}/* box_ar - returns the area of the box. */static doublebox_ar(BOX *box){ return box_wd(box) * box_ht(box);}/* box_cn - stores the centerpoint of the box into *center. */static voidbox_cn(Point *center, BOX *box){ center->x = (box->high.x + box->low.x) / 2.0; center->y = (box->high.y + box->low.y) / 2.0;}/* box_wd - returns the width (length) of the box * (horizontal magnitude). */static doublebox_wd(BOX *box){ return box->high.x - box->low.x;}/* box_ht - returns the height of the box * (vertical magnitude). */static doublebox_ht(BOX *box){ return box->high.y - box->low.y;}/*---------------------------------------------------------- * Funky operations. *---------------------------------------------------------*//* box_intersect - * returns the overlapping portion of two boxes, * or NULL if they do not intersect. */Datumbox_intersect(PG_FUNCTION_ARGS){ BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); BOX *result; if (!box_ov(box1, box2)) PG_RETURN_NULL(); result = (BOX *) palloc(sizeof(BOX)); result->high.x = Min(box1->high.x, box2->high.x); result->low.x = Max(box1->low.x, box2->low.x); result->high.y = Min(box1->high.y, box2->high.y); result->low.y = Max(box1->low.y, box2->low.y); PG_RETURN_BOX_P(result);}/* box_diagonal - * returns a line segment which happens to be the * positive-slope diagonal of "box". */Datumbox_diagonal(PG_FUNCTION_ARGS){ BOX *box = PG_GETARG_BOX_P(0); LSEG *result = (LSEG *) palloc(sizeof(LSEG)); statlseg_construct(result, &box->high, &box->low); PG_RETURN_LSEG_P(result);}/*********************************************************************** ** ** Routines for 2D lines. ** Lines are not intended to be used as ADTs per se, ** but their ops are useful tools for other ADT ops. Thus, ** there are few relops. ** ***********************************************************************/Datumline_in(PG_FUNCTION_ARGS){#ifdef ENABLE_LINE_TYPE char *str = PG_GETARG_CSTRING(0);#endif LINE *line;#ifdef ENABLE_LINE_TYPE /* when fixed, modify "not implemented", catalog/pg_type.h and SGML */ LSEG lseg; int isopen; char *s; if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg.p[0]))) || (*s != '\0')) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type line: \"%s\"", str))); line = (LINE *) palloc(sizeof(LINE)); line_construct_pts(line, &lseg.p[0], &lseg.p[1]);#else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("type \"line\" not yet implemented"))); line = NULL;#endif PG_RETURN_LINE_P(line);}Datumline_out(PG_FUNCTION_ARGS){#ifdef ENABLE_LINE_TYPE LINE *line = PG_GETARG_LINE_P(0);#endif char *result;#ifdef ENABLE_LINE_TYPE /* when fixed, modify "not implemented", catalog/pg_type.h and SGML */ LSEG lseg; if (FPzero(line->B)) { /* vertical */ /* use "x = C" */ result->A = -1; result->B = 0; result->C = pt1->x;#ifdef GEODEBUG printf("line_out- line is vertical\n");#endif#ifdef NOT_USED result->m = DBL_MAX;#endif } else if (FPzero(line->A)) { /* horizontal */ /* use "x = C" */ result->A = 0; result->B = -1; result->C = pt1->y;#ifdef GEODEBUG printf("line_out- line is horizontal\n");#endif#ifdef NOT_USED result->m = 0.0;#endif } else { } if (FPzero(line->A)) /* horizontal? */ { } else if (FPzero(line->B)) /* vertical? */ { } else { } return path_encode(TRUE, 2, (Point *) &(ls->p[0]));#else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("type \"line\" not yet implemented"))); result = NULL;#endif PG_RETURN_CSTRING(result);}/* * line_recv - converts external binary format to line */Datumline_recv(PG_FUNCTION_ARGS){ ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("type \"line\" not yet implemented"))); return 0;}/* * line_send - converts line to binary format */Datumline_send(PG_FUNCTION_ARGS){ ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("type \"line\" not yet implemented"))); return 0;}/*---------------------------------------------------------- * Conversion routines from one line formula to internal. * Internal form: Ax+By+C=0 *---------------------------------------------------------*//* line_construct_pm() * point-slope */static LINE *line_construct_pm(Point *pt, double m){ LINE *result = (LINE *) palloc(sizeof(LINE)); /* use "mx - y + yinter = 0" */ result->A = m; result->B = -1.0; if (m == DBL_MAX) result->C = pt->y; else result->C = pt->y - m * pt->x;#ifdef NOT_USED result->m = m;#endif return result;}/* * Fill already-allocated LINE struct from two points on the line */static voidline_construct_pts(LINE *line, Point *pt1, Point *pt2){ if (FPeq(pt1->x, pt2->x)) { /* vertical */ /* use "x = C" */ line->A = -1; line->B = 0; line->C = pt1->x;#ifdef NOT_USED line->m = DBL_MAX;#endif#ifdef GEODEBUG printf("line_construct_pts- line is vertical\n");#endif } else if (FPeq(pt1->y, pt2->y)) { /* horizontal */ /* use "y = C" */ line->A = 0; line->B = -1; line->C = pt1->y;#ifdef NOT_USED line->m = 0.0;#endif#ifdef GEODEBUG printf("line_construct_pts- line is horizontal\n");#endif } else { /* use "mx - y + yinter = 0" */ line->A = (pt2->y - pt1->y) / (pt2->x - pt1->x); line->B = -1.0; line->C = pt1->y - line->A * pt1->x;#ifdef NOT_USED line->m = line->A;#endif#ifdef GEODEBUG printf("line_construct_pts- line is neither vertical nor horizontal (diffs x=%.*g, y=%.*g\n", DBL_DIG, (pt2->x - pt1->x), DBL_DIG, (pt2->y - pt1->y));#endif }}/* line_construct_pp() * two points */Datumline_construct_pp(PG_FUNCTION_ARGS){ Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); LINE *result = (LINE *) palloc(sizeof(LINE)); line_construct_pts(result, pt1, pt2); PG_RETURN_LINE_P(result);}/*---------------------------------------------------------- * Relative position routines. *---------------------------------------------------------*/Datumline_intersect(PG_FUNCTION_ARGS){ LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); PG_RETURN_BOOL(!DatumGetBool(DirectFunctionCall2(line_parallel, LinePGetDatum(l1), LinePGetDatum(l2))));}Datumline_parallel(PG_FUNCTION_ARGS){ LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1);#ifdef NOT_USED PG_RETURN_BOOL(FPeq(l1->m, l2->m));#endif if (FPzero(l1->B)) PG_RETURN_BOOL(FPzero(l2->B)); PG_RETURN_BOOL(FPeq(l2->A, l1->A * (l2->B / l1->B)));}Datumline_perp(PG_FUNCTION_ARGS){ LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1);#ifdef NOT_USED if (l1->m) PG_RETURN_BOOL(FPeq(l2->m / l1->m, -1.0)); else if (l2->m) PG_RETURN_BOOL(FPeq(l1->m / l2->m, -1.0));#endif if (FPzero(l1->A)) PG_RETURN_BOOL(FPzero(l2->B)); else if (FPzero(l1->B)) PG_RETURN_BOOL(FPzero(l2->A)); PG_RETURN_BOOL(FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0));}Datumline_vertical(PG_FUNCTION_ARGS){ LINE *line = PG_GETARG_LINE_P(0); PG_RETURN_BOOL(FPzero(line->B));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -