PostGIS  2.5.1dev-r@@SVN_REVISION@@

◆ LWGEOM_angle()

Datum LWGEOM_angle ( PG_FUNCTION_ARGS  )

Definition at line 2440 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(), optimistic_overlap(), PG_FUNCTION_INFO_V1(), LWPOINT::point, and POINTTYPE.

Referenced by LWGEOM_azimuth().

2441 {
2442  GSERIALIZED * seri_geoms[4];
2443  LWGEOM *geom_unser;
2444  LWPOINT *lwpoint;
2445  POINT2D points[4];
2446  double az1,az2 ;
2447  double result;
2448  int srids[4];
2449  int i = 0 ;
2450  int j = 0;
2451  int err_code = 0;
2452  int n_args = PG_NARGS();
2453 
2454  /* no deserialize, checking for common error first*/
2455  for(i=0; i<n_args; i++)
2456  {
2457  seri_geoms[i] = PG_GETARG_GSERIALIZED_P(i);
2458  if (gserialized_is_empty(seri_geoms[i]) )
2459  {/* empty geom */
2460  if (i==3)
2461  {
2462  n_args = 3 ;
2463  }
2464  else
2465  {
2466  err_code = 1 ;
2467  break ;
2468  }
2469  } else
2470  {
2471  if(gserialized_get_type(seri_geoms[i]) != POINTTYPE)
2472  {/* geom type */
2473  err_code = 2 ;
2474  break;
2475  }
2476  else
2477  {
2478  srids[i] = gserialized_get_srid(seri_geoms[i]) ;
2479  if(srids[0] != srids[i])
2480  {/* error on srid*/
2481  err_code = 3 ;
2482  break;
2483  }
2484  }
2485  }
2486  }
2487  if (err_code >0)
2488  switch (err_code){
2489  default: /*always executed*/
2490  for (j=0;j<=i;j++)
2491  PG_FREE_IF_COPY(seri_geoms[j], j);
2492  /*FALLTHROUGH*/
2493  case 1:
2494  lwpgerror("Empty geometry");
2495  PG_RETURN_NULL() ;
2496  break;
2497 
2498  case 2:
2499  lwpgerror("Argument must be POINT geometries");
2500  PG_RETURN_NULL();
2501  break;
2502 
2503  case 3:
2504  lwpgerror("Operation on mixed SRID geometries");
2505  PG_RETURN_NULL();
2506  break;
2507  }
2508  /* extract points */
2509  for(i=0; i<n_args; i++)
2510  {
2511  geom_unser = lwgeom_from_gserialized(seri_geoms[i]) ;
2512  lwpoint = lwgeom_as_lwpoint(geom_unser);
2513  if (!lwpoint)
2514  {
2515  for (j=0;j<n_args;j++)
2516  PG_FREE_IF_COPY(seri_geoms[j], j);
2517  lwpgerror("Error unserializing geometry");
2518  PG_RETURN_NULL() ;
2519  }
2520 
2521  if ( ! getPoint2d_p(lwpoint->point, 0, &points[i]) )
2522  {
2523  /* // can't free serialized geom, it might be needed by lw
2524  for (j=0;j<n_args;j++)
2525  PG_FREE_IF_COPY(seri_geoms[j], j); */
2526  lwpgerror("Error extracting point");
2527  PG_RETURN_NULL();
2528  }
2529  /* lwfree(geom_unser);don't do, lw may rely on this memory
2530  lwpoint_free(lwpoint); dont do , this memory is needed ! */
2531  }
2532  /* // can't free serialized geom, it might be needed by lw
2533  for (j=0;j<n_args;j++)
2534  PG_FREE_IF_COPY(seri_geoms[j], j); */
2535 
2536  /* compute azimuth for the 2 pairs of points
2537  * note that angle is not defined identically for 3 points or 4 points*/
2538  if (n_args == 3)
2539  {/* we rely on azimuth to complain if points are identical */
2540  if ( ! azimuth_pt_pt(&points[0], &points[1], &az1) )
2541  PG_RETURN_NULL();
2542  if ( ! azimuth_pt_pt(&points[2], &points[1], &az2) )
2543  PG_RETURN_NULL();
2544  } else
2545  {
2546  if ( ! azimuth_pt_pt(&points[0], &points[1], &az1) )
2547  PG_RETURN_NULL();
2548  if ( ! azimuth_pt_pt(&points[2], &points[3], &az2) )
2549  PG_RETURN_NULL();
2550  }
2551  result = az2-az1 ;
2552  result += (result<0) * 2 * M_PI ; /* we dont want negative angle*/
2553  PG_RETURN_FLOAT8(result);
2554 }
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:161
POINTARRAY * point
Definition: liblwgeom.h:413
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:2416
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:
Here is the caller graph for this function: