PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ gserialized_distance_nd()

Datum gserialized_distance_nd ( PG_FUNCTION_ARGS  )

Definition at line 644 of file gserialized_gist_nd.c.

645 {
646  /* Feature-to-feature distance */
647  GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P(0);
648  GSERIALIZED *geom2 = PG_GETARG_GSERIALIZED_P(1);
649  LWGEOM *lw1 = lwgeom_from_gserialized(geom1);
650  LWGEOM *lw2 = lwgeom_from_gserialized(geom2);
651  LWGEOM *closest;
652  double distance;
653 
654  /* Find an exact shortest line w/ the dimensions we support */
655  if (lwgeom_has_z(lw1) && lwgeom_has_z(lw2))
656  {
657  closest = lwgeom_closest_line_3d(lw1, lw2);
658  distance = lwgeom_length(closest);
659  }
660  else
661  {
662  closest = lwgeom_closest_line(lw1, lw2);
663  distance = lwgeom_length_2d(closest);
664  }
665 
666  /* Can only add the M term if both objects have M */
667  if (lwgeom_has_m(lw1) && lwgeom_has_m(lw2))
668  {
669  double m1 = 0, m2 = 0;
670  int usebox = false;
671  /* Un-sqrt the distance so we can add extra terms */
673 
674  if (lwgeom_get_type(lw1) == POINTTYPE)
675  {
676  POINT4D p;
677  lwpoint_getPoint4d_p((LWPOINT *)lw1, &p);
678  m1 = p.m;
679  }
680  else if (lwgeom_get_type(lw1) == LINETYPE)
681  {
682  LWPOINT *lwp1 = lwline_get_lwpoint(lwgeom_as_lwline(closest), 0);
683  m1 = lwgeom_interpolate_point(lw1, lwp1);
684  lwpoint_free(lwp1);
685  }
686  else
687  usebox = true;
688 
689  if (lwgeom_get_type(lw2) == POINTTYPE)
690  {
691  POINT4D p;
692  lwpoint_getPoint4d_p((LWPOINT *)lw2, &p);
693  m2 = p.m;
694  }
695  else if (lwgeom_get_type(lw2) == LINETYPE)
696  {
697  LWPOINT *lwp2 = lwline_get_lwpoint(lwgeom_as_lwline(closest), 1);
698  m2 = lwgeom_interpolate_point(lw2, lwp2);
699  lwpoint_free(lwp2);
700  }
701  else
702  usebox = true;
703 
704  if (usebox)
705  {
706  GBOX b1, b2;
707  if (gserialized_get_gbox_p(geom1, &b1) && gserialized_get_gbox_p(geom2, &b2))
708  {
709  double d;
710  /* Disjoint left */
711  if (b1.mmin > b2.mmax)
712  d = b1.mmin - b2.mmax;
713  /* Disjoint right */
714  else if (b2.mmin > b1.mmax)
715  d = b2.mmin - b1.mmax;
716  /* Not Disjoint */
717  else
718  d = 0;
719  distance += d * d;
720  }
721  }
722  else
723  distance += (m2 - m1) * (m2 - m1);
724 
725  distance = sqrt(distance);
726  }
727 
728  lwgeom_free(closest);
729 
730  PG_FREE_IF_COPY(geom1, 0);
731  PG_FREE_IF_COPY(geom2, 1);
732  PG_RETURN_FLOAT8(distance);
733 }
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Read the box from the GSERIALIZED or calculate it if necessary.
Definition: gserialized.c:65
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
Definition: lwpoint.c:57
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:161
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:213
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1138
#define LINETYPE
Definition: liblwgeom.h:117
double lwgeom_interpolate_point(const LWGEOM *lwin, const LWPOINT *lwpt)
Find the measure value at the location on the line closest to the point.
double lwgeom_length(const LWGEOM *geom)
Definition: lwgeom.c:1930
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:916
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:116
LWGEOM * lwgeom_closest_line(const LWGEOM *lw1, const LWGEOM *lw2)
Definition: measures.c:40
double lwgeom_length_2d(const LWGEOM *geom)
Definition: lwgeom.c:1952
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:923
LWGEOM * lwgeom_closest_line_3d(const LWGEOM *lw1, const LWGEOM *lw2)
Definition: measures3d.c:76
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
Definition: lwline.c:309
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition: lwinline.h:135
static double distance(double x1, double y1, double x2, double y2)
Definition: lwtree.c:1032
double mmax
Definition: liblwgeom.h:347
double mmin
Definition: liblwgeom.h:346
double m
Definition: liblwgeom.h:400

References distance(), gserialized_get_gbox_p(), LINETYPE, lwgeom_as_lwline(), lwgeom_closest_line(), lwgeom_closest_line_3d(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_get_type(), lwgeom_has_m(), lwgeom_has_z(), lwgeom_interpolate_point(), lwgeom_length(), lwgeom_length_2d(), lwline_get_lwpoint(), lwpoint_free(), lwpoint_getPoint4d_p(), POINT4D::m, GBOX::mmax, GBOX::mmin, and POINTTYPE.

Here is the call graph for this function: