PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ LWGEOM_angle()

Datum LWGEOM_angle ( PG_FUNCTION_ARGS  )

Definition at line 2468 of file lwgeom_functions_basic.c.

2469 {
2470  GSERIALIZED *seri_geoms[4];
2471  LWGEOM *geom_unser;
2472  LWPOINT *lwpoint;
2473  POINT2D points[4];
2474  double az1, az2;
2475  double result;
2476  int32_t srids[4];
2477  int i = 0;
2478  int j = 0;
2479  int err_code = 0;
2480  int n_args = PG_NARGS();
2481 
2482  /* no deserialize, checking for common error first*/
2483  for (i = 0; i < n_args; i++)
2484  {
2485  seri_geoms[i] = PG_GETARG_GSERIALIZED_P(i);
2486  if (gserialized_is_empty(seri_geoms[i]))
2487  { /* empty geom */
2488  if (i == 3)
2489  {
2490  n_args = 3;
2491  }
2492  else
2493  {
2494  err_code = 1;
2495  break;
2496  }
2497  }
2498  else
2499  {
2500  if (gserialized_get_type(seri_geoms[i]) != POINTTYPE)
2501  { /* geom type */
2502  err_code = 2;
2503  break;
2504  }
2505  else
2506  {
2507  srids[i] = gserialized_get_srid(seri_geoms[i]);
2508  if (srids[0] != srids[i])
2509  { /* error on srid*/
2510  err_code = 3;
2511  break;
2512  }
2513  }
2514  }
2515  }
2516  if (err_code > 0)
2517  switch (err_code)
2518  {
2519  default: /*always executed*/
2520  for (j = 0; j <= i; j++)
2521  PG_FREE_IF_COPY(seri_geoms[j], j);
2522  /*FALLTHROUGH*/
2523  case 1:
2524  lwpgerror("Empty geometry");
2525  PG_RETURN_NULL();
2526  break;
2527 
2528  case 2:
2529  lwpgerror("Argument must be POINT geometries");
2530  PG_RETURN_NULL();
2531  break;
2532 
2533  case 3:
2534  lwpgerror("Operation on mixed SRID geometries");
2535  PG_RETURN_NULL();
2536  break;
2537  }
2538  /* extract points */
2539  for (i = 0; i < n_args; i++)
2540  {
2541  geom_unser = lwgeom_from_gserialized(seri_geoms[i]);
2542  lwpoint = lwgeom_as_lwpoint(geom_unser);
2543  if (!lwpoint)
2544  {
2545  for (j = 0; j < n_args; j++)
2546  PG_FREE_IF_COPY(seri_geoms[j], j);
2547  lwpgerror("Error unserializing geometry");
2548  PG_RETURN_NULL();
2549  }
2550 
2551  if (!getPoint2d_p(lwpoint->point, 0, &points[i]))
2552  {
2553  /* // can't free serialized geom, it might be needed by lw
2554  for (j=0;j<n_args;j++)
2555  PG_FREE_IF_COPY(seri_geoms[j], j); */
2556  lwpgerror("Error extracting point");
2557  PG_RETURN_NULL();
2558  }
2559  /* lwfree(geom_unser);don't do, lw may rely on this memory
2560  lwpoint_free(lwpoint); dont do , this memory is needed ! */
2561  }
2562  /* // can't free serialized geom, it might be needed by lw
2563  for (j=0;j<n_args;j++)
2564  PG_FREE_IF_COPY(seri_geoms[j], j); */
2565 
2566  /* compute azimuth for the 2 pairs of points
2567  * note that angle is not defined identically for 3 points or 4 points*/
2568  if (n_args == 3)
2569  { /* we rely on azimuth to complain if points are identical */
2570  if (!azimuth_pt_pt(&points[0], &points[1], &az1))
2571  PG_RETURN_NULL();
2572  if (!azimuth_pt_pt(&points[2], &points[1], &az2))
2573  PG_RETURN_NULL();
2574  }
2575  else
2576  {
2577  if (!azimuth_pt_pt(&points[0], &points[1], &az1))
2578  PG_RETURN_NULL();
2579  if (!azimuth_pt_pt(&points[2], &points[3], &az2))
2580  PG_RETURN_NULL();
2581  }
2582  result = az2 - az1;
2583  result += (result < 0) * 2 * M_PI; /* we dont want negative angle*/
2584  PG_RETURN_FLOAT8(result);
2585 }
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
Definition: gserialized.c:126
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
Definition: gserialized.c:152
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized.c:89
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition: measures.c:2461
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:349
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:116
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwinline.h:121
POINTARRAY * point
Definition: liblwgeom.h:457

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: