Datum geo_distance(PG_FUNCTION_ARGS) { Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); float8 result; result = geo_distance_internal(pt1, pt2); PG_RETURN_FLOAT8(result); }
Datum makepoint(PG_FUNCTION_ARGS) { Point *pointx = PG_GETARG_POINT_P(0); Point *pointy = PG_GETARG_POINT_P(1); Point *new_point = (Point *) palloc(sizeof(Point)); new_point->x = pointx->x; new_point->y = pointy->y; PG_RETURN_POINT_P(new_point); }
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 earth_dist_points(PG_FUNCTION_ARGS) { Point *p1,*p2; double result; p1 = PG_GETARG_POINT_P(0); p2 = PG_GETARG_POINT_P(1); result = earth_points_distance(p1,p2); PG_RETURN_FLOAT8(result); }
/* * The inexact GiST distance method for geometric types that store bounding * boxes. * * Compute lossy distance from point to index entries. The result is inexact * because index entries are bounding boxes, not the exact shapes of the * indexed geometric types. We use distance from point to MBR of index entry. * This is a lower bound estimate of distance from point to indexed geometric * type. */ Datum gist_bbox_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool *recheck = (bool *) PG_GETARG_POINTER(4); double distance; StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; /* Bounding box distance is always inexact. */ *recheck = true; switch (strategyGroup) { case PointStrategyNumberGroup: distance = computeDistance(false, DatumGetBoxP(entry->key), PG_GETARG_POINT_P(1)); break; default: elog(ERROR, "unknown strategy number: %d", strategy); distance = 0.0; /* keep compiler quiet */ } PG_RETURN_FLOAT8(distance); }
Datum pt_in_widget(PG_FUNCTION_ARGS) { Point *point = PG_GETARG_POINT_P(0); WIDGET *widget = (WIDGET *) PG_GETARG_POINTER(1); PG_RETURN_BOOL(point_dt(point, &widget->center) < widget->radius); }
Datum pt_in_widget(PG_FUNCTION_ARGS) { Point *point = PG_GETARG_POINT_P(0); WIDGET *widget = (WIDGET *) PG_GETARG_POINTER(1); float8 distance; distance = DatumGetFloat8(DirectFunctionCall2(point_distance, PointPGetDatum(point), PointPGetDatum(&widget->center))); PG_RETURN_BOOL(distance < widget->radius); }
Datum earth_get_square(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); double dist = PG_GETARG_FLOAT8(1); BOX *box; if(!( (earth_check_point(pt) == 0) && (earth_check_dist(dist) == 0))) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("attempt to get a box form a dist:%.10f rad for a point:(lat=%.10f, lon=%.10f) out of range",dist,pt->x,pt->y))); box = earth_get_box_internal(pt, dist); PG_RETURN_BOX_P(box); }
Datum earth_point_to_box_s0(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); BOX *box; if(earth_check_point(pt) != 0) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("attempt to get a box form a point out of range"))); box = palloc(sizeof(BOX)); box->low.x = pt->x; box->low.y = pt->y; box->high.x = pt->x; box->high.y = pt->y; PG_RETURN_BOX_P(box); }
Datum gist_point_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); double distance; StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; switch (strategyGroup) { case PointStrategyNumberGroup: distance = computeDistance(GIST_LEAF(entry), DatumGetBoxP(entry->key), PG_GETARG_POINT_P(1)); break; default: elog(ERROR, "unknown strategy number: %d", strategy); distance = 0.0; /* keep compiler quiet */ } PG_RETURN_FLOAT8(distance); }
Datum regress_dist_ptpath(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); PATH *path = PG_GETARG_PATH_P(1); float8 result = 0.0; /* keep compiler quiet */ float8 tmp; int i; LSEG lseg; switch (path->npts) { case 0: PG_RETURN_NULL(); case 1: result = point_dt(pt, &path->p[0]); break; default: /* * the distance from a point to a path is the smallest distance * from the point to any of its constituent segments. */ Assert(path->npts > 1); for (i = 0; i < path->npts - 1; ++i) { regress_lseg_construct(&lseg, &path->p[i], &path->p[i + 1]); tmp = DatumGetFloat8(DirectFunctionCall2(dist_ps, PointPGetDatum(pt), LsegPGetDatum(&lseg))); if (i == 0 || tmp < result) result = tmp; } break; } PG_RETURN_FLOAT8(result); }
Datum gist_point_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool result; bool *recheck = (bool *) PG_GETARG_POINTER(4); StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; switch (strategyGroup) { case PointStrategyNumberGroup: result = gist_point_consistent_internal(strategy % GeoStrategyNumberOffset, GIST_LEAF(entry), DatumGetBoxP(entry->key), PG_GETARG_POINT_P(1)); *recheck = false; break; case BoxStrategyNumberGroup: result = DatumGetBool(DirectFunctionCall5( gist_box_consistent, PointerGetDatum(entry), PG_GETARG_DATUM(1), Int16GetDatum(RTOverlapStrategyNumber), 0, PointerGetDatum(recheck))); break; case PolygonStrategyNumberGroup: { POLYGON *query = PG_GETARG_POLYGON_P(1); result = DatumGetBool(DirectFunctionCall5( gist_poly_consistent, PointerGetDatum(entry), PolygonPGetDatum(query), Int16GetDatum(RTOverlapStrategyNumber), 0, PointerGetDatum(recheck))); if (GIST_LEAF(entry) && result) { /* * We are on leaf page and quick check shows overlapping * of polygon's bounding box and point */ BOX *box = DatumGetBoxP(entry->key); Assert(box->high.x == box->low.x && box->high.y == box->low.y); result = DatumGetBool(DirectFunctionCall2( poly_contain_pt, PolygonPGetDatum(query), PointPGetDatum(&box->high))); *recheck = false; } } break; case CircleStrategyNumberGroup: { CIRCLE *query = PG_GETARG_CIRCLE_P(1); result = DatumGetBool(DirectFunctionCall5( gist_circle_consistent, PointerGetDatum(entry), CirclePGetDatum(query), Int16GetDatum(RTOverlapStrategyNumber), 0, PointerGetDatum(recheck))); if (GIST_LEAF(entry) && result) { /* * We are on leaf page and quick check shows overlapping * of polygon's bounding box and point */ BOX *box = DatumGetBoxP(entry->key); Assert(box->high.x == box->low.x && box->high.y == box->low.y); result = DatumGetBool(DirectFunctionCall2( circle_contain_pt, CirclePGetDatum(query), PointPGetDatum(&box->high))); *recheck = false; } } break; default: result = false; /* silence compiler warning */ elog(ERROR, "unknown strategy number: %d", strategy); } PG_RETURN_BOOL(result); }
Datum gist_point_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool *recheck = (bool *) PG_GETARG_POINTER(4); bool result; StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; switch (strategyGroup) { case PointStrategyNumberGroup: result = gist_point_consistent_internal(strategy % GeoStrategyNumberOffset, GIST_LEAF(entry), DatumGetBoxP(entry->key), PG_GETARG_POINT_P(1)); *recheck = false; break; case BoxStrategyNumberGroup: { /* * The only operator___ in this group is point <@ box (on_pb), so * we needn't examine strategy again. * * For historical reasons, on_pb uses exact rather than fuzzy * comparisons. We could use box_overlap when at an internal * page, but that would lead to possibly visiting child pages * uselessly, because box_overlap uses fuzzy comparisons. * Instead we write a non-fuzzy overlap test. The same code * will also serve for leaf-page tests, since leaf keys have * high == low. */ BOX *query, *key; query = PG_GETARG_BOX_P(1); key = DatumGetBoxP(entry->key); result = (key->high.x >= query->low.x && key->low.x <= query->high.x && key->high.y >= query->low.y && key->low.y <= query->high.y); *recheck = false; } break; case PolygonStrategyNumberGroup: { POLYGON *query = PG_GETARG_POLYGON_P(1); result = DatumGetBool(DirectFunctionCall5( gist_poly_consistent, PointerGetDatum(entry), PolygonPGetDatum(query), Int16GetDatum(RTOverlapStrategyNumber), 0, PointerGetDatum(recheck))); if (GIST_LEAF(entry) && result) { /* * We are on leaf page and quick check shows overlapping * of polygon's bounding box and point */ BOX *box = DatumGetBoxP(entry->key); Assert(box->high.x == box->low.x && box->high.y == box->low.y); result = DatumGetBool(DirectFunctionCall2( poly_contain_pt, PolygonPGetDatum(query), PointPGetDatum(&box->high))); *recheck = false; } } break; case CircleStrategyNumberGroup: { CIRCLE *query = PG_GETARG_CIRCLE_P(1); result = DatumGetBool(DirectFunctionCall5( gist_circle_consistent, PointerGetDatum(entry), CirclePGetDatum(query), Int16GetDatum(RTOverlapStrategyNumber), 0, PointerGetDatum(recheck))); if (GIST_LEAF(entry) && result) { /* * We are on leaf page and quick check shows overlapping * of polygon's bounding box and point */ BOX *box = DatumGetBoxP(entry->key); Assert(box->high.x == box->low.x && box->high.y == box->low.y); result = DatumGetBool(DirectFunctionCall2( circle_contain_pt, CirclePGetDatum(query), PointPGetDatum(&box->high))); *recheck = false; } } break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); result = false; /* keep compiler quiet */ break; } PG_RETURN_BOOL(result); }