Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS) { SPOLY * poly = ( SPOLY * ) PG_GETARG_POINTER ( 0 ) ; if ( poly == NULL ){ PG_RETURN_NULL ( ); } poly = PG_GETARG_SPOLY( 0 ); if ( poly->npts < 3 ){ elog ( NOTICE , "spoly(spoint): At least 3 points required" ); FREE ( poly ); PG_RETURN_NULL ( ); } // Skip if distance is equal 180deg if ( FPeq ( spoint_dist ( &poly->p[0], &poly->p[ poly->npts - 1 ]) , PI ) ) { elog ( NOTICE , "spoly(spoint): Cannot close polygon. Distance between first and last point is 180deg" ); FREE ( poly ); PG_RETURN_NULL ( ); } if ( !spherepoly_check ( poly ) ){ elog ( NOTICE , "spoly(spoint): a line segment overlaps or polygon too large" ); FREE ( poly ) ; PG_RETURN_NULL(); } PG_RETURN_POINTER ( poly ); }
Datum spheretrans_poly(PG_FUNCTION_ARGS) { SPOLY * sp = PG_GETARG_SPOLY ( 0 ) ; SEuler * se = ( SEuler * ) PG_GETARG_POINTER ( 1 ) ; SPOLY * out = ( SPOLY * ) MALLOC ( VARSIZE(sp) ); PG_RETURN_POINTER ( euler_spoly_trans ( out , sp, se ) ); }
Datum spherepoly_circ(PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 0 ) ; int32 i; SLine l; float8 sum = 0.0; for ( i=0; i<poly->npts; i++ ){ sum += ( spoly_segment ( &l , poly , i ) )->length ; } PG_RETURN_FLOAT8 ( sum ); }
Datum spherepoly_add_point(PG_FUNCTION_ARGS) { SPOLY * poly = ( SPOLY * ) PG_GETARG_POINTER ( 0 ) ; SPoint * p = ( SPoint * ) PG_GETARG_POINTER ( 1 ) ; int32 size = 0 ; SPOLY * poly_new = NULL; if ( p == NULL ){ PG_RETURN_POINTER ( poly ); } if ( poly == NULL ){ size = offsetof(SPOLY, p[0]) + sizeof(SPoint) ; poly = ( SPOLY * ) MALLOC ( size ); memcpy( (void*) &poly->p[0] , (void*) p, sizeof(SPoint) ); #if PG_VERSION_NUM < 80300 poly->size = size; #else SET_VARSIZE(poly, size); #endif poly->npts = 1; PG_RETURN_POINTER ( poly ); } poly = PG_GETARG_SPOLY( 0 ); // skip if equal if ( spoint_eq (p, &poly->p[ poly->npts - 1 ]) ){ PG_RETURN_POINTER ( poly ); } // Skip if distance is equal 180deg if ( FPeq ( spoint_dist ( p, &poly->p[ poly->npts - 1 ]) , PI ) ) { elog ( NOTICE , "spoly(spoint): Skip point, distance of previous point is 180deg" ); } size = offsetof(SPOLY, p[0]) + sizeof(SPoint) * ( poly->npts + 1 ); poly_new = palloc( size ); memcpy( (void*) poly , (void*) poly_new, VARSIZE(poly) ); poly_new->npts++; #if PG_VERSION_NUM < 80300 poly_new->size = size ; #else SET_VARSIZE( poly_new, size ); #endif memcpy( (void*) &poly_new->p[poly->npts] , (void*) p, sizeof(SPoint) ); PG_RETURN_POINTER ( poly_new ); }
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 ); }
Datum spherepoly_out(PG_FUNCTION_ARGS) { SPOLY *poly = PG_GETARG_SPOLY(0); int32 i; char *out = (char *) palloc(128 * poly->npts); char *tmp; strcpy(out, "{"); for (i = 0; i < poly->npts; i++) { if (i > 0) { strcat(out, ","); } tmp = DatumGetPointer(DirectFunctionCall1(spherepoint_out, PointerGetDatum(&poly->p[i]))); strcat(out, tmp); pfree(tmp); } strcat(out, "}"); PG_RETURN_CSTRING(out); }
Datum spherepoly_cont_ellipse_com (PG_FUNCTION_ARGS) { SELLIPSE * ell = ( SELLIPSE * ) PG_GETARG_POINTER ( 0 ) ; SPOLY * poly = PG_GETARG_SPOLY( 1 ) ; PG_RETURN_BOOL ( poly_ellipse_pos ( poly, ell ) == PGS_POLY_CONT_ELLIPSE ); }
Datum spherepoly_cont_point_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 1 ) ; SPoint * sp = ( SPoint * ) PG_GETARG_POINTER ( 0 ) ; PG_RETURN_BOOL ( !spoly_contains_point ( poly , sp ) ); }
Datum spherepoly_cont_poly_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly1 = PG_GETARG_SPOLY( 1 ) ; SPOLY * poly2 = PG_GETARG_SPOLY( 0 ) ; PG_RETURN_BOOL ( poly_poly_pos ( poly1, poly2, FALSE ) != PGS_POLY_CONT ); }
Datum spherepoly_overlap_poly_neg (PG_FUNCTION_ARGS) { SPOLY * poly1 = PG_GETARG_SPOLY( 0 ) ; SPOLY * poly2 = PG_GETARG_SPOLY( 1 ) ; PG_RETURN_BOOL ( poly_poly_pos ( poly1, poly2, FALSE ) == PGS_POLY_AVOID ); }
Datum spherepoly_cont_line_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 1 ) ; SLine * line = ( SLine * ) PG_GETARG_POINTER ( 0 ) ; PG_RETURN_BOOL ( poly_line_pos ( poly, line ) != PGS_POLY_CONT_LINE ); }
Datum spherepoly_overlap_line_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 1 ) ; SLine * line = ( SLine * ) PG_GETARG_POINTER ( 0 ) ; PG_RETURN_BOOL ( poly_line_pos ( poly, line ) == PGS_LINE_POLY_AVOID ); }
Datum spherecircle_cont_poly_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 0 ) ; SCIRCLE * circ = ( SCIRCLE * ) PG_GETARG_POINTER ( 1 ) ; PG_RETURN_BOOL ( poly_circle_pos ( poly, circ ) != PGS_CIRCLE_CONT_POLY ); }
Datum spherepoly_overlap_circle_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 1 ) ; SCIRCLE * circ = ( SCIRCLE * ) PG_GETARG_POINTER ( 0 ) ; PG_RETURN_BOOL ( poly_circle_pos ( poly, circ ) == PGS_CIRCLE_POLY_AVOID ); }
Datum spherepoly_cont_circle_com (PG_FUNCTION_ARGS) { SCIRCLE * circ = ( SCIRCLE * ) PG_GETARG_POINTER ( 0 ) ; SPOLY * poly = PG_GETARG_SPOLY( 1 ) ; PG_RETURN_BOOL ( poly_circle_pos ( poly, circ ) == PGS_POLY_CONT_CIRCLE ); }
Datum sphereellipse_cont_poly_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 0 ) ; SELLIPSE * ell = ( SELLIPSE * ) PG_GETARG_POINTER ( 1 ) ; PG_RETURN_BOOL ( poly_ellipse_pos ( poly, ell ) != PGS_ELLIPSE_CONT_POLY ); }
Datum spherepoly_overlap_ellipse_com_neg (PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 1 ) ; SELLIPSE * ell = ( SELLIPSE * ) PG_GETARG_POINTER ( 0 ) ; PG_RETURN_BOOL ( poly_ellipse_pos ( poly, ell ) == PGS_ELLIPSE_POLY_AVOID ); }
Datum spherepoly_npts(PG_FUNCTION_ARGS) { SPOLY * poly = PG_GETARG_SPOLY( 0 ) ; PG_RETURN_INT32 ( poly->npts ); }
Datum spherepoly_equal_neg(PG_FUNCTION_ARGS) { SPOLY * p1 = PG_GETARG_SPOLY( 0 ) ; SPOLY * p2 = PG_GETARG_SPOLY( 1 ) ; PG_RETURN_BOOL ( !spoly_eq ( p1, p2, FALSE ) ); }