Datum BOX2D_left(PG_FUNCTION_ARGS) { BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); PG_RETURN_BOOL(FPlt(box1->xmax, box2->xmin)); }
Datum BOX2D_below(PG_FUNCTION_ARGS) { GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0); GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1); PG_RETURN_BOOL(FPlt(box1->ymax, box2->ymin)); }
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); break; case RTRightStrategyNumber: result = FPgt(key->high.x, query->x); break; case RTAboveStrategyNumber: result = FPgt(key->high.y, query->y); break; case RTBelowStrategyNumber: result = FPlt(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)); } 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)); } break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); result = false; /* keep compiler quiet */ break; } return result; }
static bool gist_point_consistent_internal(strat_nr_t strategy, bool isLeaf, BOX * key, Point * query) { bool result = false; switch (strategy) { case RTLeftStrategyNumber: result = FPlt(key->low.x, query->x); break; case RTRightStrategyNumber: result = FPgt(key->high.x, query->x); break; case RTAboveStrategyNumber: result = FPgt(key->high.y, query->y); break; case RTBelowStrategyNumber: result = FPlt(key->low.y, query->y); break; case RTSameStrategyNumber: if (isLeaf) { result = FPeq(key->low.x, query->x) && FPeq(key->low.y, query->y); } else { 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, "unknown strategy number: %d", strategy); } return result; }
Datum spherecircle_by_center (PG_FUNCTION_ARGS) { SPoint * p = ( SPoint * ) PG_GETARG_POINTER ( 0 ) ; float8 rad = PG_GETARG_FLOAT8 ( 1 ) ; SCIRCLE * c ; if ( FPgt(rad,PIH) || FPlt(rad,0.0) ){ elog ( ERROR , "radius must be not greater than 90 degrees or less than 0" ); PG_RETURN_NULL ( ); } c = ( SCIRCLE * ) MALLOC ( sizeof ( SCIRCLE ) ) ; memcpy( (void*) &c->center, (void*) p , sizeof(SPoint) ); c->radius = rad; PG_RETURN_POINTER ( c ); }
Datum spherecircle_overlap (PG_FUNCTION_ARGS) { SCIRCLE * c1 = ( SCIRCLE * ) PG_GETARG_POINTER ( 0 ) ; SCIRCLE * c2 = ( SCIRCLE * ) PG_GETARG_POINTER ( 1 ) ; float8 dist = spoint_dist ( &c1->center, &c2->center ); if ( scircle_eq( c1, c2 ) ){ PG_RETURN_BOOL ( TRUE ); } else if ( FPlt( ( c1->radius + c2->radius ) , dist ) ) { PG_RETURN_BOOL ( FALSE ); } else { PG_RETURN_BOOL ( TRUE ) ; } }
Datum spherepoly_area(PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 0 ) ; int32 i; SPoint s[poly->npts + 2]; SPoint stmp[2]; SEuler se; float8 sum = 0.0; memcpy( (void*)&s[1], (void*)&poly->p[0] , poly->npts * sizeof( SPoint ) ); memcpy( (void*)&s[0], (void*)&s[poly->npts] , sizeof( SPoint ) ); memcpy( (void*)&s[poly->npts+1], (void*)&s[1] , sizeof( SPoint ) ); se.psi = 0; se.phi_a = EULER_AXIS_Z; se.theta_a = EULER_AXIS_X; se.psi_a = EULER_AXIS_Z; for ( i=1; i<=poly->npts; i++ ){ se.phi = -PIH - s[i].lng ; se.theta = s[i].lat - PIH ; euler_spoint_trans( &stmp[0] , &s[i-1] , &se ); euler_spoint_trans( &stmp[1] , &s[i+1] , &se ); stmp[1].lng -= stmp[0].lng; if ( FPlt(stmp[1].lng,0.0) ){ stmp[1].lng += PID; } sum += stmp[1].lng ; } sum -= ( PI * ( poly->npts - 2 ) ) ; if ( FPge(sum,PID) ){ sum = 2*PID - sum; } if ( FPzero(sum) ){ sum = 0.0; } PG_RETURN_FLOAT8 ( sum ); }
/* 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); }
long point_below(Point *pt1, Point *pt2) { return( FPlt(pt1->y, pt2->y) ); }
long point_left(Point *pt1, Point *pt2) { return( FPlt(pt1->x, pt2->x) ); }
/* box_relop - is area(box1) relop area(box2), within * our accuracy constraint? */ long box_lt(BOX *box1, BOX *box2) { return( FPlt(box_ar(box1), box_ar(box2)) ); }
Datum spg_kd_inner_consistent(PG_FUNCTION_ARGS) { spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); double coord; int which; int i; Assert(in->hasPrefix); coord = DatumGetFloat8(in->prefixDatum); if (in->allTheSame) elog(ERROR, "allTheSame should not occur for k-d trees"); Assert(in->nNodes == 2); /* "which" is a bitmask of children that satisfy all constraints */ 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)) which &= (1 << 1); break; case RTRightStrategyNumber: if ((in->level % 2) != 0 && FPgt(query->x, coord)) which &= (1 << 2); break; case RTSameStrategyNumber: if ((in->level % 2) != 0) { if (FPlt(query->x, coord)) which &= (1 << 1); else if (FPgt(query->x, coord)) which &= (1 << 2); } else { if (FPlt(query->y, coord)) which &= (1 << 1); else if (FPgt(query->y, coord)) which &= (1 << 2); } break; case RTBelowStrategyNumber: if ((in->level % 2) == 0 && FPlt(query->y, coord)) which &= (1 << 1); break; case RTAboveStrategyNumber: if ((in->level % 2) == 0 && FPgt(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)) which &= (1 << 1); else if (FPgt(boxQuery->low.x, coord)) which &= (1 << 2); } else { if (FPlt(boxQuery->high.y, coord)) which &= (1 << 1); else if (FPgt(boxQuery->low.y, coord)) which &= (1 << 2); } break; default: elog(ERROR, "unrecognized strategy number: %d", in->scankeys[i].sk_strategy); break; } if (which == 0) break; /* no need to consider remaining conditions */ } /* We must descend into the children identified by which */ out->nodeNumbers = (int *) palloc(sizeof(int) * 2); out->nNodes = 0; for (i = 1; i <= 2; i++) { if (which & (1 << i)) out->nodeNumbers[out->nNodes++] = i - 1; } /* Set up level increments, too */ out->levelAdds = (int *) palloc(sizeof(int) * 2); out->levelAdds[0] = 1; out->levelAdds[1] = 1; PG_RETURN_VOID(); }
bool spoly_contains_point ( const SPOLY * pg , const SPoint * sp ) { static int32 i; static SLine sl; bool res = FALSE ; static float8 scp; static Vector3D vc, vp; // First check, if point is outside polygon (behind) spherepoly_center ( &vc , pg ); spoint_vector3d ( &vp , sp ); scp = vector3d_scalar ( &vp , &vc ); if ( FPle ( scp, 0.0 ) ){ return false; } // Check whether point is edge for ( i=0; i<pg->npts; i++ ){ if ( spoint_eq ( &pg->p[i] , sp ) ){ return TRUE; } } // Check whether point is on a line segment for ( i=0; i<pg->npts; i++ ){ spoly_segment ( &sl , pg , i ); if ( spoint_at_sline( sp, &sl ) ){ return TRUE; } } do { SEuler se, te; SPoint p , lp[2]; bool a1, a2, eqa ; int32 cntr = 0; SPOLY * tmp = ( SPOLY * ) MALLOC ( VARSIZE(pg) ); /* Make a transformation, so point is (0,0) */ se.phi_a = EULER_AXIS_Z ; se.theta_a = EULER_AXIS_X ; se.psi_a = EULER_AXIS_Z ; se.phi = PIH - sp->lng ; se.theta = - sp->lat ; se.psi = -PIH ; euler_spoly_trans ( tmp , pg , &se ); p.lng = 0.0; p.lat = 0.0; // Check, whether an edge is on equator. // If yes, rotate randomized around 0,0 cntr = 0; do { eqa = FALSE; for ( i=0; i<pg->npts; i++ ){ if ( FPzero(tmp->p[i].lat) ){ if ( FPeq( cos(tmp->p[i].lng) , -1.0 ) ){ return false; } else { eqa = TRUE; break; } } } if ( eqa ){ SPOLY * ttt = ( SPOLY * ) MALLOC ( VARSIZE(pg) ); srand( cntr ); se.phi_a = se.theta_a = se.psi_a = EULER_AXIS_X ; se.phi = ( (double) rand() / RAND_MAX ) * PID ; se.theta = 0.0 ; se.psi = 0.0 ; euler_spoly_trans ( ttt , tmp , &se ); memcpy ( (void*) tmp, (void*) ttt, VARSIZE(pg) ); FREE(ttt); } if ( cntr>10000 ){ elog(WARNING ,"Bug found in spoly_contains_point"); elog(ERROR ,"Please report it to pg_sphere team!"); return false; } cntr++; } while ( eqa ); // Count line segment crossing "equator" cntr = 0; for ( i=0; i<pg->npts; i++ ){ // create a single line from segment spoly_segment ( &sl , tmp , i ); sline_begin ( &lp[0], &sl ); sline_end ( &lp[1], &sl ); a1 = ( FPgt(lp[0].lat,0.0) && FPlt(lp[1].lat,0.0) ); a2 = ( FPlt(lp[0].lat,0.0) && FPgt(lp[1].lat,0.0) ); if ( a1 || a2 ){ // if crossing sphereline_to_euler_inv ( &te, &sl ); if ( a2 ){ // crossing ascending p.lng = PID - te.phi; } else { p.lng = PI - te.phi; } spoint_check ( &p ); if ( p.lng < PI ){ // crossing between 0 and 180 deg cntr++; } } } FREE ( tmp ); if ( cntr % 2 ){ res = TRUE; } } while (0); return res; }