From aa79e331595860489cdbbdce2d5f35a7d1f33783 Mon Sep 17 00:00:00 2001 From: Emre Hasegeli Date: Wed, 25 May 2016 17:53:19 +0200 Subject: [PATCH] Stop using FP macros on geo_ops.c --- src/backend/access/gist/gistproc.c | 17 +- src/backend/access/spgist/spgkdtreeproc.c | 24 +-- src/backend/utils/adt/geo_ops.c | 312 +++++++++++++++--------------- src/backend/utils/adt/geo_spgist.c | 24 +-- src/include/utils/geo_decls.h | 16 -- src/test/regress/expected/point.out | 8 +- 6 files changed, 193 insertions(+), 208 deletions(-) diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c index e8213e2..7fb4437 100644 --- a/src/backend/access/gist/gistproc.c +++ b/src/backend/access/gist/gistproc.c @@ -1295,44 +1295,41 @@ computeDistance(bool isLeaf, BOX *box, Point *point) static bool gist_point_consistent_internal(StrategyNumber strategy, bool isLeaf, BOX *key, Point *query) { bool result = false; switch (strategy) { case RTLeftStrategyNumber: - result = FPlt(key->low.x, query->x); + result = key->low.x < query->x; break; case RTRightStrategyNumber: - result = FPgt(key->high.x, query->x); + result = key->high.x > query->x; break; case RTAboveStrategyNumber: - result = FPgt(key->high.y, query->y); + result = key->high.y > query->y; break; case RTBelowStrategyNumber: - result = FPlt(key->low.y, query->y); + result = key->low.y < query->y; break; case RTSameStrategyNumber: if (isLeaf) { /* key.high must equal key.low, so we can disregard it */ - result = (FPeq(key->low.x, query->x) && - FPeq(key->low.y, query->y)); + result = key->low.x == query->x && key->low.y == query->y; } else { - result = (FPle(query->x, key->high.x) && - FPge(query->x, key->low.x) && - FPle(query->y, key->high.y) && - FPge(query->y, key->low.y)); + result = query->x <= key->high.x && query->x >= key->low.x && + query->y <= key->high.y && query->y >= key->low.y; } break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); result = false; /* keep compiler quiet */ break; } return result; } diff --git a/src/backend/access/spgist/spgkdtreeproc.c b/src/backend/access/spgist/spgkdtreeproc.c index 1ab9335..4b3be5d 100644 --- a/src/backend/access/spgist/spgkdtreeproc.c +++ b/src/backend/access/spgist/spgkdtreeproc.c @@ -175,72 +175,72 @@ spg_kd_inner_consistent(PG_FUNCTION_ARGS) which = (1 << 1) | (1 << 2); 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 ((in->level % 2) != 0 && FPlt(query->x, coord)) + if ((in->level % 2) != 0 && query->x < coord) which &= (1 << 1); break; case RTRightStrategyNumber: - if ((in->level % 2) != 0 && FPgt(query->x, coord)) + if ((in->level % 2) != 0 && query->x > coord) which &= (1 << 2); break; case RTSameStrategyNumber: if ((in->level % 2) != 0) { - if (FPlt(query->x, coord)) + if (query->x < coord) which &= (1 << 1); - else if (FPgt(query->x, coord)) + else if (query->x > coord) which &= (1 << 2); } else { - if (FPlt(query->y, coord)) + if (query->y < coord) which &= (1 << 1); - else if (FPgt(query->y, coord)) + else if (query->y > coord) which &= (1 << 2); } break; case RTBelowStrategyNumber: - if ((in->level % 2) == 0 && FPlt(query->y, coord)) + if ((in->level % 2) == 0 && query->y < coord) which &= (1 << 1); break; case RTAboveStrategyNumber: - if ((in->level % 2) == 0 && FPgt(query->y, coord)) + if ((in->level % 2) == 0 && query->y > coord) which &= (1 << 2); 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->scankeys[i].sk_argument); if ((in->level % 2) != 0) { - if (FPlt(boxQuery->high.x, coord)) + if (boxQuery->high.x < coord) which &= (1 << 1); - else if (FPgt(boxQuery->low.x, coord)) + else if (boxQuery->low.x > coord) which &= (1 << 2); } else { - if (FPlt(boxQuery->high.y, coord)) + if (boxQuery->high.y < coord) which &= (1 << 1); - else if (FPgt(boxQuery->low.y, coord)) + else if (boxQuery->low.y > coord) which &= (1 << 2); } break; default: elog(ERROR, "unrecognized strategy number: %d", in->scankeys[i].sk_strategy); break; } if (which == 0) diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index 657bcee..7e553e6 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -499,246 +499,246 @@ box_copy(BOX *box) *---------------------------------------------------------*/ /* box_same - are two boxes identical? */ Datum box_same(PG_FUNCTION_ARGS) { BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(FPeq(box1->high.x, box2->high.x) && - FPeq(box1->low.x, box2->low.x) && - FPeq(box1->high.y, box2->high.y) && - FPeq(box1->low.y, box2->low.y)); + PG_RETURN_BOOL(box1->high.x == box2->high.x && + box1->low.x == box2->low.x && + box1->high.y == box2->high.y && + box1->low.y == box2->low.y); } /* box_overlap - does box1 overlap box2? */ Datum box_overlap(PG_FUNCTION_ARGS) { BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); PG_RETURN_BOOL(box_ov(box1, box2)); } static bool box_ov(BOX *box1, BOX *box2) { - return (FPle(box1->low.x, box2->high.x) && - FPle(box2->low.x, box1->high.x) && - FPle(box1->low.y, box2->high.y) && - FPle(box2->low.y, box1->high.y)); + return (box1->low.x <= box2->high.x && + box2->low.x <= box1->high.x && + box1->low.y <= box2->high.y && + box2->low.y <= box1->high.y); } /* box_left - is box1 strictly left of box2? */ Datum box_left(PG_FUNCTION_ARGS) { BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(FPlt(box1->high.x, box2->low.x)); + PG_RETURN_BOOL(box1->high.x < box2->low.x); } /* box_overleft - is the right edge of box1 at or left of * the right edge of box2? * * This is "less than or equal" for the end of a time range, * when time ranges are stored as rectangles. */ Datum box_overleft(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)); + PG_RETURN_BOOL(box1->high.x <= box2->high.x); } /* box_right - is box1 strictly right of box2? */ Datum box_right(PG_FUNCTION_ARGS) { BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(FPgt(box1->low.x, box2->high.x)); + PG_RETURN_BOOL(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. */ Datum box_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)); + PG_RETURN_BOOL(box1->low.x >= box2->low.x); } /* box_below - is box1 strictly below box2? */ Datum box_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)); + PG_RETURN_BOOL(box1->high.y < box2->low.y); } /* box_overbelow - is the upper edge of box1 at or below * the upper edge of box2? */ Datum box_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)); + PG_RETURN_BOOL(box1->high.y <= box2->high.y); } /* box_above - is box1 strictly above box2? */ Datum box_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)); + PG_RETURN_BOOL(box1->low.y > box2->high.y); } /* box_overabove - is the lower edge of box1 at or above * the lower edge of box2? */ Datum box_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)); + PG_RETURN_BOOL(box1->low.y >= box2->low.y); } /* box_contained - is box1 contained by box2? */ Datum box_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)); + PG_RETURN_BOOL(box1->high.x <= box2->high.x && + box1->low.x >= box2->low.x && + box1->high.y <= box2->high.y && + box1->low.y >= box2->low.y); } /* box_contain - does box1 contain box2? */ Datum box_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)); + PG_RETURN_BOOL(box1->high.x >= box2->high.x && + box1->low.x <= box2->low.x && + box1->high.y >= box2->high.y && + 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. */ Datum box_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)); + PG_RETURN_BOOL(box1->high.y <= box2->low.y); } Datum box_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)); + PG_RETURN_BOOL(box1->low.y >= box2->high.y); } /* box_relop - is area(box1) relop area(box2), within * our accuracy constraint? */ Datum box_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))); + PG_RETURN_BOOL(box_ar(box1) < box_ar(box2)); } Datum box_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))); + PG_RETURN_BOOL(box_ar(box1) > box_ar(box2)); } Datum box_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))); + PG_RETURN_BOOL(box_ar(box1) == box_ar(box2)); } Datum box_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))); + PG_RETURN_BOOL(box_ar(box1) <= box_ar(box2)); } Datum box_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))); + PG_RETURN_BOOL(box_ar(box1) >= box_ar(box2)); } /*---------------------------------------------------------- * "Arithmetic" operators on boxes. *---------------------------------------------------------*/ /* box_area - returns the area of the box. */ Datum @@ -927,29 +927,29 @@ line_in(PG_FUNCTION_ARGS) s = str; while (isspace((unsigned char) *s)) s++; if (*s == '{') { if (!line_decode(s + 1, str, line)) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "line", str))); - if (FPzero(line->A) && FPzero(line->B)) + if (line->A == 0 && line->B == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid line specification: A and B cannot both be zero"))); } else { path_decode(s, true, 2, &(lseg.p[0]), &isopen, NULL, "line", str); - if (FPeq(lseg.p[0].x, lseg.p[1].x) && FPeq(lseg.p[0].y, lseg.p[1].y)) + if (lseg.p[0].x == lseg.p[1].x && lseg.p[0].y == lseg.p[1].y) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid line specification: must be two distinct points"))); line_construct_pts(line, &lseg.p[0], &lseg.p[1]); } PG_RETURN_LINE_P(line); } @@ -1029,31 +1029,31 @@ line_construct_pm(Point *pt, double m) return result; } /* * Fill already-allocated LINE struct from two points on the line */ static void line_construct_pts(LINE *line, Point *pt1, Point *pt2) { - if (FPeq(pt1->x, pt2->x)) + if (pt1->x == pt2->x) { /* vertical */ /* use "x = C" */ line->A = -1; line->B = 0; line->C = pt1->x; #ifdef GEODEBUG printf("line_construct_pts- line is vertical\n"); #endif } - else if (FPeq(pt1->y, pt2->y)) + else if (pt1->y == pt2->y) { /* horizontal */ /* use "y = C" */ line->A = 0; line->B = -1; line->C = pt1->y; #ifdef GEODEBUG printf("line_construct_pts- line is horizontal\n"); #endif } else @@ -1101,75 +1101,77 @@ line_intersect(PG_FUNCTION_ARGS) LinePGetDatum(l1), LinePGetDatum(l2)))); } Datum line_parallel(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); - if (FPzero(l1->B)) - PG_RETURN_BOOL(FPzero(l2->B)); + if (l1->B == 0) + PG_RETURN_BOOL(l2->B == 0); - PG_RETURN_BOOL(FPeq(l2->A, l1->A * (l2->B / l1->B))); + PG_RETURN_BOOL(l2->A * l1->B == l1->A * l2->B); } Datum line_perp(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); - if (FPzero(l1->A)) - PG_RETURN_BOOL(FPzero(l2->B)); - else if (FPzero(l1->B)) - PG_RETURN_BOOL(FPzero(l2->A)); + if (l1->A == 0) + PG_RETURN_BOOL(l2->B == 0); + else if (l1->B == 0) + PG_RETURN_BOOL(l2->A == 0); - PG_RETURN_BOOL(FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0)); + PG_RETURN_BOOL(l1->A * l2->B == l1->B * l2->A * -1.0); } Datum line_vertical(PG_FUNCTION_ARGS) { LINE *line = PG_GETARG_LINE_P(0); - PG_RETURN_BOOL(FPzero(line->B)); + PG_RETURN_BOOL(line->B == 0); } Datum line_horizontal(PG_FUNCTION_ARGS) { LINE *line = PG_GETARG_LINE_P(0); - PG_RETURN_BOOL(FPzero(line->A)); + PG_RETURN_BOOL(line->A == 0); } Datum line_eq(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); double k; - if (!FPzero(l2->A)) - k = l1->A / l2->A; - else if (!FPzero(l2->B)) - k = l1->B / l2->B; - else if (!FPzero(l2->C)) - k = l1->C / l2->C; - else - k = 1.0; + if (l1->A == l2->A) + PG_RETURN_BOOL(l1->B == l2->B && l1->C == l2->C); - PG_RETURN_BOOL(FPeq(l1->A, k * l2->A) && - FPeq(l1->B, k * l2->B) && - FPeq(l1->C, k * l2->C)); + if (l1->A != 0) + PG_RETURN_BOOL(l1->A * l2->B == l2->A * l1->B && + l1->A * l2->C == l2->A * l1->C); + if (l2->B != 0) + PG_RETURN_BOOL(l1->B * l2->A == l2->B * l1->A && + l1->B * l2->C == l2->B * l1->C); + if (l2->C != 0) + PG_RETURN_BOOL(l1->C * l2->A == l2->C * l1->A && + l1->C * l2->B == l2->C * l1->B); + + PG_RETURN_BOOL(false); } /*---------------------------------------------------------- * Line arithmetic routines. *---------------------------------------------------------*/ /* line_distance() * Distance between two lines. */ @@ -1178,21 +1180,21 @@ line_distance(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); float8 result; Point *tmp; if (!DatumGetBool(DirectFunctionCall2(line_parallel, LinePGetDatum(l1), LinePGetDatum(l2)))) PG_RETURN_FLOAT8(0.0); - if (FPzero(l1->B)) /* vertical? */ + if (l1->B == 0) /* vertical? */ PG_RETURN_FLOAT8(fabs(l1->C - l2->C)); tmp = point_construct(0.0, l1->C); result = dist_pl_internal(tmp, l2); PG_RETURN_FLOAT8(result); } /* line_interpt() * Point where two lines l1, l2 intersect (if any) */ Datum @@ -1224,26 +1226,26 @@ line_interpt_internal(LINE *l1, LINE *l2) /* * NOTE: if the lines are identical then we will find they are parallel * and report "no intersection". This is a little weird, but since * there's no *unique* intersection, maybe it's appropriate behavior. */ if (DatumGetBool(DirectFunctionCall2(line_parallel, LinePGetDatum(l1), LinePGetDatum(l2)))) return NULL; - if (FPzero(l1->B)) /* l1 vertical? */ + if (l1->B == 0) /* l1 vertical? */ { x = l1->C; y = (l2->A * x + l2->C); } - else if (FPzero(l2->B)) /* l2 vertical? */ + else if (l2->B == 0) /* l2 vertical? */ { x = l2->C; y = (l1->A * x + l1->C); } else { x = (l1->C - l2->C) / (l2->A - l1->A); y = (l1->A * x + l1->C); } result = point_construct(x, y); @@ -1816,84 +1818,84 @@ point_copy(Point *pt) * that results may, strictly speaking, be a lie (unless * EPSILON = 0.0). *---------------------------------------------------------*/ Datum point_left(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPlt(pt1->x, pt2->x)); + PG_RETURN_BOOL(pt1->x < pt2->x); } Datum point_right(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPgt(pt1->x, pt2->x)); + PG_RETURN_BOOL(pt1->x > pt2->x); } Datum point_above(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPgt(pt1->y, pt2->y)); + PG_RETURN_BOOL(pt1->y > pt2->y); } Datum point_below(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPlt(pt1->y, pt2->y)); + PG_RETURN_BOOL(pt1->y < pt2->y); } Datum point_vert(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPeq(pt1->x, pt2->x)); + PG_RETURN_BOOL(pt1->x == pt2->x); } Datum point_horiz(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPeq(pt1->y, pt2->y)); + PG_RETURN_BOOL(pt1->y == pt2->y); } Datum point_eq(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y)); + PG_RETURN_BOOL(pt1->x == pt2->x && pt1->y == pt2->y); } Datum point_ne(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPne(pt1->x, pt2->x) || FPne(pt1->y, pt2->y)); + PG_RETURN_BOOL(pt1->x != pt2->x || pt1->y != pt2->y); } /*---------------------------------------------------------- * "Arithmetic" operators on points. *---------------------------------------------------------*/ Datum point_distance(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); @@ -1918,21 +1920,21 @@ point_slope(PG_FUNCTION_ARGS) Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); PG_RETURN_FLOAT8(point_sl(pt1, pt2)); } double point_sl(Point *pt1, Point *pt2) { - return (FPeq(pt1->x, pt2->x) + return (pt1->x == pt2->x ? (double) DBL_MAX : (pt1->y - pt2->y) / (pt1->x - pt2->x)); } /*********************************************************************** ** ** Routines for 2D line segments. ** ***********************************************************************/ @@ -2072,20 +2074,21 @@ lseg_intersect_internal(LSEG *l1, LSEG *l2) retval = false; return retval; } Datum lseg_parallel(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); + /* The slopes are lossy. We cannot exact match them. */ PG_RETURN_BOOL(FPeq(point_sl(&l1->p[0], &l1->p[1]), point_sl(&l2->p[0], &l2->p[1]))); } /* lseg_perp() * Determine if two line segments are perpendicular. * * This code did not get the correct answer for * '((0,0),(0,1))'::lseg ?-| '((0,0),(1,0))'::lseg * So, modified it to check explicitly for slope of vertical line @@ -2099,107 +2102,108 @@ lseg_perp(PG_FUNCTION_ARGS) LSEG *l2 = PG_GETARG_LSEG_P(1); double m1, m2; m1 = point_sl(&(l1->p[0]), &(l1->p[1])); m2 = point_sl(&(l2->p[0]), &(l2->p[1])); #ifdef GEODEBUG printf("lseg_perp- slopes are %g and %g\n", m1, m2); #endif - if (FPzero(m1)) - PG_RETURN_BOOL(FPeq(m2, DBL_MAX)); - else if (FPzero(m2)) - PG_RETURN_BOOL(FPeq(m1, DBL_MAX)); + if (m1 == 0) + PG_RETURN_BOOL(m2 == DBL_MAX); + else if (m2 == 0) + PG_RETURN_BOOL(m1 == DBL_MAX); - PG_RETURN_BOOL(FPeq(m1 / m2, -1.0)); + /* The slopes are lossy. We cannot exact match them. */ + PG_RETURN_BOOL(FPeq(m1, m2 * -1.0)); } Datum lseg_vertical(PG_FUNCTION_ARGS) { LSEG *lseg = PG_GETARG_LSEG_P(0); - PG_RETURN_BOOL(FPeq(lseg->p[0].x, lseg->p[1].x)); + PG_RETURN_BOOL(lseg->p[0].x == lseg->p[1].x); } Datum lseg_horizontal(PG_FUNCTION_ARGS) { LSEG *lseg = PG_GETARG_LSEG_P(0); - PG_RETURN_BOOL(FPeq(lseg->p[0].y, lseg->p[1].y)); + PG_RETURN_BOOL(lseg->p[0].y == lseg->p[1].y); } Datum lseg_eq(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPeq(l1->p[0].x, l2->p[0].x) && - FPeq(l1->p[0].y, l2->p[0].y) && - FPeq(l1->p[1].x, l2->p[1].x) && - FPeq(l1->p[1].y, l2->p[1].y)); + PG_RETURN_BOOL(l1->p[0].x == l2->p[0].x && + l1->p[0].y == l2->p[0].y && + l1->p[1].x == l2->p[1].x && + l1->p[1].y == l2->p[1].y); } Datum lseg_ne(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(!FPeq(l1->p[0].x, l2->p[0].x) || - !FPeq(l1->p[0].y, l2->p[0].y) || - !FPeq(l1->p[1].x, l2->p[1].x) || - !FPeq(l1->p[1].y, l2->p[1].y)); + PG_RETURN_BOOL(l1->p[0].x != l2->p[0].x || + l1->p[0].y != l2->p[0].y || + l1->p[1].x != l2->p[1].x || + l1->p[1].y != l2->p[1].y); } Datum lseg_lt(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) < + point_dt(&l2->p[0], &l2->p[1])); } Datum lseg_le(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) <= + point_dt(&l2->p[0], &l2->p[1])); } Datum lseg_gt(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) > + point_dt(&l2->p[0], &l2->p[1])); } Datum lseg_ge(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) >= + point_dt(&l2->p[0], &l2->p[1])); } /*---------------------------------------------------------- * Line arithmetic routines. *---------------------------------------------------------*/ /* lseg_distance - * If two segments don't intersect, then the closest * point will be from one of the endpoints to the other @@ -2278,21 +2282,22 @@ lseg_interpt_internal(LSEG *l1, LSEG *l2) if (!on_ps_internal(result, l1) || !on_ps_internal(result, l2)) { pfree(result); return NULL; } /* * If there is an intersection, then check explicitly for matching * endpoints since there may be rounding effects with annoying lsb - * residue. - tgl 1997-07-09 + * residue. We are fuzzy matching them to be compatible with + * on_ps_internal(). */ if ((FPeq(l1->p[0].x, l2->p[0].x) && FPeq(l1->p[0].y, l2->p[0].y)) || (FPeq(l1->p[0].x, l2->p[1].x) && FPeq(l1->p[0].y, l2->p[1].y))) { result->x = l1->p[0].x; result->y = l1->p[0].y; } else if ((FPeq(l1->p[1].x, l2->p[0].x) && FPeq(l1->p[1].y, l2->p[0].y)) || (FPeq(l1->p[1].x, l2->p[1].x) && FPeq(l1->p[1].y, l2->p[1].y))) { @@ -2714,27 +2719,27 @@ Datum close_pl(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); LINE *line = PG_GETARG_LINE_P(1); Point *result; LINE *tmp; double invm; result = (Point *) palloc(sizeof(Point)); - if (FPzero(line->B)) /* vertical? */ + if (line->B == 0) /* vertical? */ { result->x = line->C; result->y = pt->y; PG_RETURN_POINT_P(result); } - if (FPzero(line->A)) /* horizontal? */ + if (line->A == 0) /* horizontal? */ { result->x = pt->x; result->y = line->C; PG_RETURN_POINT_P(result); } /* drop a perpendicular and find the intersection point */ /* invert and flip the sign on the slope to get a perpendicular */ invm = line->B / line->A; tmp = line_construct_pm(pt, invm); @@ -2759,51 +2764,51 @@ close_ps(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); LSEG *lseg = PG_GETARG_LSEG_P(1); Point *result = NULL; LINE *tmp; double invm; int xh, yh; #ifdef GEODEBUG - printf("close_sp:pt->x %f pt->y %f\nlseg(0).x %f lseg(0).y %f lseg(1).x %f lseg(1).y %f\n", + printf("close_ps:spt->x %f pt->y %f\nlseg(0).x %f lseg(0).y %f lseg(1).x %f lseg(1).y %f\n", pt->x, pt->y, lseg->p[0].x, lseg->p[0].y, lseg->p[1].x, lseg->p[1].y); #endif /* xh (or yh) is the index of upper x( or y) end point of lseg */ /* !xh (or !yh) is the index of lower x( or y) end point of lseg */ xh = lseg->p[0].x < lseg->p[1].x; yh = lseg->p[0].y < lseg->p[1].y; - if (FPeq(lseg->p[0].x, lseg->p[1].x)) /* vertical? */ + if (lseg->p[0].x == lseg->p[1].x) /* vertical? */ { #ifdef GEODEBUG printf("close_ps- segment is vertical\n"); #endif /* first check if point is below or above the entire lseg. */ if (pt->y < lseg->p[!yh].y) result = point_copy(&lseg->p[!yh]); /* below the lseg */ else if (pt->y > lseg->p[yh].y) result = point_copy(&lseg->p[yh]); /* above the lseg */ if (result != NULL) PG_RETURN_POINT_P(result); /* point lines along (to left or right) of the vertical lseg. */ result = (Point *) palloc(sizeof(Point)); result->x = lseg->p[0].x; result->y = pt->y; PG_RETURN_POINT_P(result); } - else if (FPeq(lseg->p[0].y, lseg->p[1].y)) /* horizontal? */ + else if (lseg->p[0].y == lseg->p[1].y) /* horizontal? */ { #ifdef GEODEBUG printf("close_ps- segment is horizontal\n"); #endif /* first check if point is left or right of the entire lseg. */ if (pt->x < lseg->p[!xh].x) result = point_copy(&lseg->p[!xh]); /* left of the lseg */ else if (pt->x > lseg->p[xh].x) result = point_copy(&lseg->p[xh]); /* right of the lseg */ if (result != NULL) @@ -3118,40 +3123,41 @@ close_lb(PG_FUNCTION_ARGS) /* on_pl - * Does the point satisfy the equation? */ Datum on_pl(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); LINE *line = PG_GETARG_LINE_P(1); - PG_RETURN_BOOL(FPzero(line->A * pt->x + line->B * pt->y + line->C)); + PG_RETURN_BOOL(line->A * pt->x + line->B * pt->y + line->C == 0); } /* on_ps - - * Determine colinearity by detecting a triangle inequality. + * Determine collinearity by detecting a triangle inequality. * This algorithm seems to behave nicely even with lsb residues - tgl 1997-07-09 */ Datum on_ps(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); LSEG *lseg = PG_GETARG_LSEG_P(1); PG_RETURN_BOOL(on_ps_internal(pt, lseg)); } static bool on_ps_internal(Point *pt, LSEG *lseg) { + /* The distances are lossy. We cannot exact match them. */ return FPeq(point_dt(pt, &lseg->p[0]) + point_dt(pt, &lseg->p[1]), point_dt(&lseg->p[0], &lseg->p[1])); } Datum on_pb(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); BOX *box = PG_GETARG_BOX_P(1); @@ -3191,22 +3197,21 @@ on_ppath(PG_FUNCTION_ARGS) b; /*-- OPEN --*/ if (!path->closed) { n = path->npts - 1; a = point_dt(pt, &path->p[0]); for (i = 0; i < n; i++) { b = point_dt(pt, &path->p[i + 1]); - if (FPeq(a + b, - point_dt(&path->p[i], &path->p[i + 1]))) + if (a + b == point_dt(&path->p[i], &path->p[i + 1])) PG_RETURN_BOOL(true); a = b; } PG_RETURN_BOOL(false); } /*-- CLOSED --*/ PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0); } @@ -3810,21 +3815,21 @@ poly_overlap(PG_FUNCTION_ARGS) static bool touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start) { /* point a is on s, b is not */ LSEG t; t.p[0] = *a; t.p[1] = *b; -#define POINTEQ(pt1, pt2) (FPeq((pt1)->x, (pt2)->x) && FPeq((pt1)->y, (pt2)->y)) +#define POINTEQ(pt1, pt2) ((pt1)->x == (pt2)->x && (pt1)->y == (pt2)->y) if (POINTEQ(a, s->p)) { if (on_ps_internal(s->p + 1, &t)) return lseg_inside_poly(b, s->p + 1, poly, start); } else if (POINTEQ(a, s->p + 1)) { if (on_ps_internal(s->p, &t)) return lseg_inside_poly(b, s->p, poly, start); } @@ -4648,216 +4653,218 @@ circle_send(PG_FUNCTION_ARGS) *---------------------------------------------------------*/ /* circles identical? */ Datum circle_same(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPeq(circle1->radius, circle2->radius) && - FPeq(circle1->center.x, circle2->center.x) && - FPeq(circle1->center.y, circle2->center.y)); + PG_RETURN_BOOL(circle1->radius == circle2->radius && + circle1->center.x == circle2->center.x && + circle1->center.y == circle2->center.y); } /* circle_overlap - does circle1 overlap circle2? */ Datum circle_overlap(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center), - circle1->radius + circle2->radius)); + PG_RETURN_BOOL(point_dt(&circle1->center, &circle2->center) <= + circle1->radius + circle2->radius); } /* circle_overleft - is the right edge of circle1 at or left of * the right edge of circle2? */ Datum circle_overleft(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((circle1->center.x + circle1->radius), - (circle2->center.x + circle2->radius))); + PG_RETURN_BOOL(circle1->center.x + circle1->radius <= + circle2->center.x + circle2->radius); } /* circle_left - is circle1 strictly left of circle2? */ Datum circle_left(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPlt((circle1->center.x + circle1->radius), - (circle2->center.x - circle2->radius))); + PG_RETURN_BOOL(circle1->center.x + circle1->radius < + circle2->center.x - circle2->radius); } /* circle_right - is circle1 strictly right of circle2? */ Datum circle_right(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPgt((circle1->center.x - circle1->radius), - (circle2->center.x + circle2->radius))); + PG_RETURN_BOOL(circle1->center.x - circle1->radius > + circle2->center.x + circle2->radius); } /* circle_overright - is the left edge of circle1 at or right of * the left edge of circle2? */ Datum circle_overright(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPge((circle1->center.x - circle1->radius), - (circle2->center.x - circle2->radius))); + PG_RETURN_BOOL(circle1->center.x - circle1->radius >= + circle2->center.x - circle2->radius); } /* circle_contained - is circle1 contained by circle2? */ Datum circle_contained(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle1->radius), circle2->radius)); + PG_RETURN_BOOL(point_dt(&circle1->center, &circle2->center) + + circle1->radius <= circle2->radius); } /* circle_contain - does circle1 contain circle2? */ Datum circle_contain(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle2->radius), circle1->radius)); + PG_RETURN_BOOL(point_dt(&circle1->center, &circle2->center) + + circle2->radius <= circle1->radius); } /* circle_below - is circle1 strictly below circle2? */ Datum circle_below(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPlt((circle1->center.y + circle1->radius), - (circle2->center.y - circle2->radius))); + PG_RETURN_BOOL(circle1->center.y + circle1->radius < + circle2->center.y - circle2->radius); } /* circle_above - is circle1 strictly above circle2? */ Datum circle_above(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPgt((circle1->center.y - circle1->radius), - (circle2->center.y + circle2->radius))); + PG_RETURN_BOOL(circle1->center.y - circle1->radius > + circle2->center.y + circle2->radius); } /* circle_overbelow - is the upper edge of circle1 at or below * the upper edge of circle2? */ Datum circle_overbelow(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((circle1->center.y + circle1->radius), - (circle2->center.y + circle2->radius))); + PG_RETURN_BOOL(circle1->center.y + circle1->radius <= + circle2->center.y + circle2->radius); } /* circle_overabove - is the lower edge of circle1 at or above * the lower edge of circle2? */ Datum circle_overabove(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPge((circle1->center.y - circle1->radius), - (circle2->center.y - circle2->radius))); + PG_RETURN_BOOL(circle1->center.y - circle1->radius >= + circle2->center.y - circle2->radius); } /* circle_relop - is area(circle1) relop area(circle2), within * our accuracy constraint? */ Datum circle_eq(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPeq(circle_ar(circle1), circle_ar(circle2))); + PG_RETURN_BOOL(circle_ar(circle1) == circle_ar(circle2)); } Datum circle_ne(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPne(circle_ar(circle1), circle_ar(circle2))); + PG_RETURN_BOOL(circle_ar(circle1) != circle_ar(circle2)); } Datum circle_lt(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPlt(circle_ar(circle1), circle_ar(circle2))); + PG_RETURN_BOOL(circle_ar(circle1) < circle_ar(circle2)); } Datum circle_gt(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPgt(circle_ar(circle1), circle_ar(circle2))); + PG_RETURN_BOOL(circle_ar(circle1) > circle_ar(circle2)); } Datum circle_le(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle(circle_ar(circle1), circle_ar(circle2))); + PG_RETURN_BOOL(circle_ar(circle1) <= circle_ar(circle2)); } Datum circle_ge(PG_FUNCTION_ARGS) { CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPge(circle_ar(circle1), circle_ar(circle2))); + PG_RETURN_BOOL(circle_ar(circle1) >= circle_ar(circle2)); } /*---------------------------------------------------------- * "Arithmetic" operators on circles. *---------------------------------------------------------*/ static CIRCLE * circle_copy(CIRCLE *circle) { @@ -5146,21 +5153,21 @@ circle_poly(PG_FUNCTION_ARGS) { int32 npts = PG_GETARG_INT32(0); CIRCLE *circle = PG_GETARG_CIRCLE_P(1); POLYGON *poly; int base_size, size; int i; double angle; double anglestep; - if (FPzero(circle->radius)) + if (circle->radius == 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot convert circle with radius zero to polygon"))); if (npts < 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("must request at least 2 points"))); base_size = sizeof(poly->p[0]) * npts; @@ -5305,110 +5312,107 @@ point_inside(Point *p, int npts, Point *plist) * Wow, that is one confusing API, but it is used above, and when summed, * can tell is if a point is in a polygon. */ static int lseg_crossing(double x, double y, double prev_x, double prev_y) { double z; int y_sign; - if (FPzero(y)) + if (y == 0) { /* y == 0, on X axis */ - if (FPzero(x)) /* (x,y) is (0,0)? */ + if (x == 0) /* (x,y) is (0,0)? */ return POINT_ON_POLYGON; - else if (FPgt(x, 0)) + else if (x > 0) { /* x > 0 */ - if (FPzero(prev_y)) /* y and prev_y are zero */ + if (prev_y == 0) /* y and prev_y are zero */ /* prev_x > 0? */ - return FPgt(prev_x, 0) ? 0 : POINT_ON_POLYGON; - return FPlt(prev_y, 0) ? 1 : -1; + return prev_x > 0 ? 0 : POINT_ON_POLYGON; + return prev_y < 0 ? 1 : -1; } else { /* x < 0, x not on positive X axis */ - if (FPzero(prev_y)) + if (prev_y == 0) /* prev_x < 0? */ - return FPlt(prev_x, 0) ? 0 : POINT_ON_POLYGON; + return prev_x < 0 ? 0 : POINT_ON_POLYGON; return 0; } } else { /* y != 0 */ /* compute y crossing direction from previous point */ - y_sign = FPgt(y, 0) ? 1 : -1; + y_sign = y > 0 ? 1 : -1; - if (FPzero(prev_y)) + if (prev_y == 0) /* previous point was on X axis, so new point is either off or on */ - return FPlt(prev_x, 0) ? 0 : y_sign; - else if (FPgt(y_sign * prev_y, 0)) + return prev_x < 0 ? 0 : y_sign; + else if (y_sign * prev_y > 0) /* both above or below X axis */ return 0; /* same sign */ else { /* y and prev_y cross X-axis */ - if (FPge(x, 0) && FPgt(prev_x, 0)) + if (x >= 0 && prev_x > 0) /* both non-negative so cross positive X-axis */ return 2 * y_sign; - if (FPlt(x, 0) && FPle(prev_x, 0)) + if (x < 0 && prev_x <= 0) /* both non-positive so do not cross positive X-axis */ return 0; /* x and y cross axises, see URL above point_inside() */ z = (x - prev_x) * y - (y - prev_y) * x; - if (FPzero(z)) + if (z == 0) return POINT_ON_POLYGON; - return FPgt((y_sign * z), 0) ? 0 : 2 * y_sign; + return y_sign * z > 0 ? 0 : 2 * y_sign; } } } static bool plist_same(int npts, Point *p1, Point *p2) { int i, ii, j; /* find match for first point */ for (i = 0; i < npts; i++) { - if ((FPeq(p2[i].x, p1[0].x)) - && (FPeq(p2[i].y, p1[0].y))) + if (p2[i].x == p1[0].x && p2[i].y == p1[0].y) { /* match found? then look forward through remaining points */ for (ii = 1, j = i + 1; ii < npts; ii++, j++) { if (j >= npts) j = 0; - if ((!FPeq(p2[j].x, p1[ii].x)) - || (!FPeq(p2[j].y, p1[ii].y))) + if (p2[j].x != p1[ii].x || p2[j].y != p1[ii].y) { #ifdef GEODEBUG printf("plist_same- %d failed forward match with %d\n", j, ii); #endif break; } } #ifdef GEODEBUG printf("plist_same- ii = %d/%d after forward match\n", ii, npts); #endif if (ii == npts) return TRUE; /* match not found forwards? then look backwards */ for (ii = 1, j = i - 1; ii < npts; ii++, j--) { if (j < 0) j = (npts - 1); - if ((!FPeq(p2[j].x, p1[ii].x)) - || (!FPeq(p2[j].y, p1[ii].y))) + if (p2[j].x != p1[ii].x || p2[j].y != p1[ii].y) { #ifdef GEODEBUG printf("plist_same- %d failed reverse match with %d\n", j, ii); #endif break; } } #ifdef GEODEBUG printf("plist_same- ii = %d/%d after reverse match\n", ii, npts); #endif diff --git a/src/backend/utils/adt/geo_spgist.c b/src/backend/utils/adt/geo_spgist.c index 83d509e..4b82f89 100644 --- a/src/backend/utils/adt/geo_spgist.c +++ b/src/backend/utils/adt/geo_spgist.c @@ -225,80 +225,80 @@ nextRectBox(RectBox *rect_box, RangeBox *centroid, uint8 quadrant) else next_rect_box->range_box_y.right.high = centroid->right.high; return next_rect_box; } /* Can any range from range_box overlap with this argument? */ static bool overlap2D(RangeBox *range_box, Range *query) { - return FPge(range_box->right.high, query->low) && - FPle(range_box->left.low, query->high); + return range_box->right.high >= query->low && + range_box->left.low <= query->high; } /* Can any rectangle from rect_box overlap with this argument? */ static bool overlap4D(RectBox *rect_box, RangeBox *query) { return overlap2D(&rect_box->range_box_x, &query->left) && overlap2D(&rect_box->range_box_y, &query->right); } /* Can any range from range_box contain this argument? */ static bool contain2D(RangeBox *range_box, Range *query) { - return FPge(range_box->right.high, query->high) && - FPle(range_box->left.low, query->low); + return range_box->right.high >= query->high && + range_box->left.low <= query->low; } /* Can any rectangle from rect_box contain this argument? */ static bool contain4D(RectBox *rect_box, RangeBox * query) { return contain2D(&rect_box->range_box_x, &query->left) && contain2D(&rect_box->range_box_y, &query->right); } /* Can any range from range_box be contained by this argument? */ static bool contained2D(RangeBox *range_box, Range *query) { - return FPle(range_box->left.low, query->high) && - FPge(range_box->left.high, query->low) && - FPle(range_box->right.low, query->high) && - FPge(range_box->right.high, query->low); + return range_box->left.low <= query->high && + range_box->left.high >= query->low && + range_box->right.low <= query->high && + range_box->right.high >= query->low; } /* Can any rectangle from rect_box be contained by this argument? */ static bool contained4D(RectBox *rect_box, RangeBox *query) { return contained2D(&rect_box->range_box_x, &query->left) && contained2D(&rect_box->range_box_y, &query->right); } /* Can any range from range_box to be lower than this argument? */ static bool lower2D(RangeBox *range_box, Range *query) { - return FPlt(range_box->left.low, query->low) && - FPlt(range_box->right.low, query->low); + return range_box->left.low < query->low && + range_box->right.low < query->low; } /* Can any range from range_box to be higher than this argument? */ static bool higher2D(RangeBox *range_box, Range *query) { - return FPgt(range_box->left.high, query->high) && - FPgt(range_box->right.high, query->high); + return range_box->left.high > query->high && + range_box->right.high > query->high; } /* Can any rectangle from rect_box be left of this argument? */ static bool left4D(RectBox *rect_box, RangeBox *query) { return lower2D(&rect_box->range_box_x, &query->left); } /* Can any rectangle from rect_box does not extend the right of this argument? */ diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h index acf3202..163bc57 100644 --- a/src/include/utils/geo_decls.h +++ b/src/include/utils/geo_decls.h @@ -25,37 +25,21 @@ #include "fmgr.h" /*-------------------------------------------------------------------- * Useful floating point utilities and constants. *-------------------------------------------------------------------*/ #define EPSILON 1.0E-06 -#ifdef EPSILON -#define FPzero(A) (fabs(A) <= EPSILON) #define FPeq(A,B) (fabs((A) - (B)) <= EPSILON) -#define FPne(A,B) (fabs((A) - (B)) > EPSILON) -#define FPlt(A,B) ((B) - (A) > EPSILON) -#define FPle(A,B) ((A) - (B) <= EPSILON) -#define FPgt(A,B) ((A) - (B) > EPSILON) -#define FPge(A,B) ((B) - (A) <= EPSILON) -#else -#define FPzero(A) ((A) == 0) -#define FPeq(A,B) ((A) == (B)) -#define FPne(A,B) ((A) != (B)) -#define FPlt(A,B) ((A) < (B)) -#define FPle(A,B) ((A) <= (B)) -#define FPgt(A,B) ((A) > (B)) -#define FPge(A,B) ((A) >= (B)) -#endif #define HYPOT(A, B) pg_hypot(A, B) /*--------------------------------------------------------------------- * Point - (x,y) *-------------------------------------------------------------------*/ typedef struct { double x, y; diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out index bfc0962..6319652 100644 --- a/src/test/regress/expected/point.out +++ b/src/test/regress/expected/point.out @@ -249,49 +249,49 @@ SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS dista CREATE TEMP TABLE point_gist_tbl(f1 point); INSERT INTO point_gist_tbl SELECT '(0,0)' FROM generate_series(0,1000); CREATE INDEX point_gist_tbl_index ON point_gist_tbl USING gist (f1); INSERT INTO point_gist_tbl VALUES ('(0.0000009,0.0000009)'); SET enable_seqscan TO true; SET enable_indexscan TO false; SET enable_bitmapscan TO false; SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point; count ------- - 1002 + 1 (1 row) SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box; count ------- 1 (1 row) SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point; count ------- - 1 + 0 (1 row) SET enable_seqscan TO false; SET enable_indexscan TO true; SET enable_bitmapscan TO true; SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point; count ------- - 1002 + 1 (1 row) SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box; count ------- 1 (1 row) SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point; count ------- - 1 + 0 (1 row) RESET enable_seqscan; RESET enable_indexscan; RESET enable_bitmapscan; -- 2.7.4 (Apple Git-66)