PostGIS  2.5.0dev-r@@SVN_REVISION@@
Datum LWGEOM_angle ( PG_FUNCTION_ARGS  )

Definition at line 2437 of file lwgeom_functions_basic.c.

References azimuth_pt_pt(), getPoint2d_p(), gserialized_get_srid(), gserialized_get_type(), gserialized_is_empty(), lwgeom_as_lwpoint(), lwgeom_from_gserialized(), LWPOINT::point, and POINTTYPE.

2438 {
2439  GSERIALIZED * seri_geoms[4];
2440  LWGEOM *geom_unser;
2441  LWPOINT *lwpoint;
2442  POINT2D points[4];
2443  double az1,az2 ;
2444  double result;
2445  int srids[4];
2446  int i = 0 ;
2447  int j = 0;
2448  int err_code = 0;
2449  int n_args = PG_NARGS();
2450 
2451  /* no deserialize, checking for common error first*/
2452  for(i=0; i<n_args; i++)
2453  {
2454  seri_geoms[i] = PG_GETARG_GSERIALIZED_P(i);
2455  if (gserialized_is_empty(seri_geoms[i]) )
2456  {/* empty geom */
2457  if (i==3)
2458  {
2459  n_args = 3 ;
2460  }
2461  else
2462  {
2463  err_code = 1 ;
2464  break ;
2465  }
2466  } else
2467  {
2468  if(gserialized_get_type(seri_geoms[i]) != POINTTYPE)
2469  {/* geom type */
2470  err_code = 2 ;
2471  break;
2472  }
2473  else
2474  {
2475  srids[i] = gserialized_get_srid(seri_geoms[i]) ;
2476  if(srids[0] != srids[i])
2477  {/* error on srid*/
2478  err_code = 3 ;
2479  break;
2480  }
2481  }
2482  }
2483  }
2484  if (err_code >0)
2485  switch (err_code){
2486  default: /*always executed*/
2487  for (j=0;j<=i;j++)
2488  PG_FREE_IF_COPY(seri_geoms[j], j);
2489 
2490  case 1:
2491  lwpgerror("Empty geometry");
2492  PG_RETURN_NULL() ;
2493  break;
2494 
2495  case 2:
2496  lwpgerror("Argument must be POINT geometries");
2497  PG_RETURN_NULL();
2498  break;
2499 
2500  case 3:
2501  lwpgerror("Operation on mixed SRID geometries");
2502  PG_RETURN_NULL();
2503  break;
2504  }
2505  /* extract points */
2506  for(i=0; i<n_args; i++)
2507  {
2508  geom_unser = lwgeom_from_gserialized(seri_geoms[i]) ;
2509  lwpoint = lwgeom_as_lwpoint(geom_unser);
2510  if (!lwpoint)
2511  {
2512  for (j=0;j<n_args;j++)
2513  PG_FREE_IF_COPY(seri_geoms[j], j);
2514  lwpgerror("Error unserializing geometry");
2515  PG_RETURN_NULL() ;
2516  }
2517 
2518  if ( ! getPoint2d_p(lwpoint->point, 0, &points[i]) )
2519  {
2520  /* // can't free serialized geom, it might be needed by lw
2521  for (j=0;j<n_args;j++)
2522  PG_FREE_IF_COPY(seri_geoms[j], j); */
2523  lwpgerror("Error extracting point");
2524  PG_RETURN_NULL();
2525  }
2526  /* lwfree(geom_unser);don't do, lw may rely on this memory
2527  lwpoint_free(lwpoint); dont do , this memory is needed ! */
2528  }
2529  /* // can't free serialized geom, it might be needed by lw
2530  for (j=0;j<n_args;j++)
2531  PG_FREE_IF_COPY(seri_geoms[j], j); */
2532 
2533  /* compute azimuth for the 2 pairs of points
2534  * note that angle is not defined identically for 3 points or 4 points*/
2535  if (n_args == 3)
2536  {/* we rely on azimuth to complain if points are identical */
2537  if ( ! azimuth_pt_pt(&points[0], &points[1], &az1) )
2538  PG_RETURN_NULL();
2539  if ( ! azimuth_pt_pt(&points[2], &points[1], &az2) )
2540  PG_RETURN_NULL();
2541  } else
2542  {
2543  if ( ! azimuth_pt_pt(&points[0], &points[1], &az1) )
2544  PG_RETURN_NULL();
2545  if ( ! azimuth_pt_pt(&points[2], &points[3], &az2) )
2546  PG_RETURN_NULL();
2547  }
2548  result = az2-az1 ;
2549  result += (result<0) * 2 * M_PI ; /* we dont want negative angle*/
2550  PG_RETURN_FLOAT8(result);
2551 }
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
Definition: g_serialized.c:86
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:160
POINTARRAY * point
Definition: liblwgeom.h:410
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
Definition: g_serialized.c:178
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:338
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition: measures.c:2422
int32_t gserialized_get_srid(const GSERIALIZED *s)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
Definition: g_serialized.c:99

Here is the call graph for this function: