PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ LWGEOM_angle()

Datum LWGEOM_angle ( PG_FUNCTION_ARGS  )

Definition at line 2667 of file lwgeom_functions_basic.c.

2668 {
2669  GSERIALIZED *seri_geoms[4];
2670  LWGEOM *geom_unser;
2671  LWPOINT *lwpoint;
2672  POINT2D points[4];
2673  double az1, az2;
2674  double result;
2675  int32_t srids[4];
2676  int i = 0;
2677  int j = 0;
2678  int err_code = 0;
2679  int n_args = PG_NARGS();
2680 
2681  /* no deserialize, checking for common error first*/
2682  for (i = 0; i < n_args; i++)
2683  {
2684  seri_geoms[i] = PG_GETARG_GSERIALIZED_P(i);
2685  if (gserialized_is_empty(seri_geoms[i]))
2686  { /* empty geom */
2687  if (i == 3)
2688  {
2689  n_args = 3;
2690  }
2691  else
2692  {
2693  err_code = 1;
2694  break;
2695  }
2696  }
2697  else
2698  {
2699  if (gserialized_get_type(seri_geoms[i]) != POINTTYPE)
2700  { /* geom type */
2701  err_code = 2;
2702  break;
2703  }
2704  else
2705  {
2706  srids[i] = gserialized_get_srid(seri_geoms[i]);
2707  if (srids[0] != srids[i])
2708  { /* error on srid*/
2709  err_code = 3;
2710  break;
2711  }
2712  }
2713  }
2714  }
2715  if (err_code > 0)
2716  switch (err_code)
2717  {
2718  default: /*always executed*/
2719  for (j = 0; j <= i; j++)
2720  PG_FREE_IF_COPY(seri_geoms[j], j);
2721  /*FALLTHROUGH*/
2722  case 1:
2723  lwpgerror("Empty geometry");
2724  PG_RETURN_NULL();
2725  break;
2726 
2727  case 2:
2728  lwpgerror("Argument must be POINT geometries");
2729  PG_RETURN_NULL();
2730  break;
2731 
2732  case 3:
2733  lwpgerror("Operation on mixed SRID geometries");
2734  PG_RETURN_NULL();
2735  break;
2736  }
2737  /* extract points */
2738  for (i = 0; i < n_args; i++)
2739  {
2740  geom_unser = lwgeom_from_gserialized(seri_geoms[i]);
2741  lwpoint = lwgeom_as_lwpoint(geom_unser);
2742  if (!lwpoint)
2743  {
2744  for (j = 0; j < n_args; j++)
2745  PG_FREE_IF_COPY(seri_geoms[j], j);
2746  lwpgerror("Error unserializing geometry");
2747  PG_RETURN_NULL();
2748  }
2749 
2750  if (!getPoint2d_p(lwpoint->point, 0, &points[i]))
2751  {
2752  /* // can't free serialized geom, it might be needed by lw
2753  for (j=0;j<n_args;j++)
2754  PG_FREE_IF_COPY(seri_geoms[j], j); */
2755  lwpgerror("Error extracting point");
2756  PG_RETURN_NULL();
2757  }
2758  /* lwfree(geom_unser);don't do, lw may rely on this memory
2759  lwpoint_free(lwpoint); dont do , this memory is needed ! */
2760  }
2761  /* // can't free serialized geom, it might be needed by lw
2762  for (j=0;j<n_args;j++)
2763  PG_FREE_IF_COPY(seri_geoms[j], j); */
2764 
2765  /* compute azimuth for the 2 pairs of points
2766  * note that angle is not defined identically for 3 points or 4 points*/
2767  if (n_args == 3)
2768  { /* we rely on azimuth to complain if points are identical */
2769  if (!azimuth_pt_pt(&points[0], &points[1], &az1))
2770  PG_RETURN_NULL();
2771  if (!azimuth_pt_pt(&points[2], &points[1], &az2))
2772  PG_RETURN_NULL();
2773  }
2774  else
2775  {
2776  if (!azimuth_pt_pt(&points[0], &points[1], &az1))
2777  PG_RETURN_NULL();
2778  if (!azimuth_pt_pt(&points[2], &points[3], &az2))
2779  PG_RETURN_NULL();
2780  }
2781  result = az2 - az1;
2782  result += (result < 0) * 2 * M_PI; /* we dont want negative angle*/
2783  PG_RETURN_FLOAT8(result);
2784 }
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:155
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:268
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
Definition: gserialized.c:181
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:118
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:342
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:102
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwinline.h:127
POINTARRAY * point
Definition: liblwgeom.h:471

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: