PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ LWGEOM_angle()

Datum LWGEOM_angle ( PG_FUNCTION_ARGS  )

Definition at line 2451 of file lwgeom_functions_basic.c.

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

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.

Here is the call graph for this function: