PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ LWGEOM_angle()

Datum LWGEOM_angle ( PG_FUNCTION_ARGS  )

Definition at line 2585 of file lwgeom_functions_basic.c.

2586 {
2587  GSERIALIZED *seri_geoms[4];
2588  LWGEOM *geom_unser;
2589  LWPOINT *lwpoint;
2590  POINT2D points[4];
2591  double az1, az2;
2592  double result;
2593  int32_t srids[4];
2594  int i = 0;
2595  int j = 0;
2596  int err_code = 0;
2597  int n_args = PG_NARGS();
2598 
2599  /* no deserialize, checking for common error first*/
2600  for (i = 0; i < n_args; i++)
2601  {
2602  seri_geoms[i] = PG_GETARG_GSERIALIZED_P(i);
2603  if (gserialized_is_empty(seri_geoms[i]))
2604  { /* empty geom */
2605  if (i == 3)
2606  {
2607  n_args = 3;
2608  }
2609  else
2610  {
2611  err_code = 1;
2612  break;
2613  }
2614  }
2615  else
2616  {
2617  if (gserialized_get_type(seri_geoms[i]) != POINTTYPE)
2618  { /* geom type */
2619  err_code = 2;
2620  break;
2621  }
2622  else
2623  {
2624  srids[i] = gserialized_get_srid(seri_geoms[i]);
2625  if (srids[0] != srids[i])
2626  { /* error on srid*/
2627  err_code = 3;
2628  break;
2629  }
2630  }
2631  }
2632  }
2633  if (err_code > 0)
2634  switch (err_code)
2635  {
2636  default: /*always executed*/
2637  for (j = 0; j <= i; j++)
2638  PG_FREE_IF_COPY(seri_geoms[j], j);
2639  /*FALLTHROUGH*/
2640  case 1:
2641  lwpgerror("Empty geometry");
2642  PG_RETURN_NULL();
2643  break;
2644 
2645  case 2:
2646  lwpgerror("Argument must be POINT geometries");
2647  PG_RETURN_NULL();
2648  break;
2649 
2650  case 3:
2651  lwpgerror("Operation on mixed SRID geometries");
2652  PG_RETURN_NULL();
2653  break;
2654  }
2655  /* extract points */
2656  for (i = 0; i < n_args; i++)
2657  {
2658  geom_unser = lwgeom_from_gserialized(seri_geoms[i]);
2659  lwpoint = lwgeom_as_lwpoint(geom_unser);
2660  if (!lwpoint)
2661  {
2662  for (j = 0; j < n_args; j++)
2663  PG_FREE_IF_COPY(seri_geoms[j], j);
2664  lwpgerror("Error unserializing geometry");
2665  PG_RETURN_NULL();
2666  }
2667 
2668  if (!getPoint2d_p(lwpoint->point, 0, &points[i]))
2669  {
2670  /* // can't free serialized geom, it might be needed by lw
2671  for (j=0;j<n_args;j++)
2672  PG_FREE_IF_COPY(seri_geoms[j], j); */
2673  lwpgerror("Error extracting point");
2674  PG_RETURN_NULL();
2675  }
2676  /* lwfree(geom_unser);don't do, lw may rely on this memory
2677  lwpoint_free(lwpoint); dont do , this memory is needed ! */
2678  }
2679  /* // can't free serialized geom, it might be needed by lw
2680  for (j=0;j<n_args;j++)
2681  PG_FREE_IF_COPY(seri_geoms[j], j); */
2682 
2683  /* compute azimuth for the 2 pairs of points
2684  * note that angle is not defined identically for 3 points or 4 points*/
2685  if (n_args == 3)
2686  { /* we rely on azimuth to complain if points are identical */
2687  if (!azimuth_pt_pt(&points[0], &points[1], &az1))
2688  PG_RETURN_NULL();
2689  if (!azimuth_pt_pt(&points[2], &points[1], &az2))
2690  PG_RETURN_NULL();
2691  }
2692  else
2693  {
2694  if (!azimuth_pt_pt(&points[0], &points[1], &az1))
2695  PG_RETURN_NULL();
2696  if (!azimuth_pt_pt(&points[2], &points[3], &az2))
2697  PG_RETURN_NULL();
2698  }
2699  result = az2 - az1;
2700  result += (result < 0) * 2 * M_PI; /* we dont want negative angle*/
2701  PG_RETURN_FLOAT8(result);
2702 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:267
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:2509
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:343
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:117
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwinline.h:131
POINTARRAY * point
Definition: liblwgeom.h:486

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

Here is the call graph for this function: