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));
}
Beispiel #2
0
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));
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
 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 );
 }
Beispiel #6
0
 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 ) ;
   }
 }
Beispiel #7
0
  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 );
  }
Beispiel #8
0
/* 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);
}
Beispiel #9
0
long point_below(Point *pt1, Point *pt2)
{
    return( FPlt(pt1->y, pt2->y) );
}
Beispiel #10
0
long point_left(Point *pt1, Point *pt2)
{
    return( FPlt(pt1->x, pt2->x) );
}
Beispiel #11
0
/*	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)) );
}
Beispiel #12
0
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();
}
Beispiel #13
0
  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;
  }