PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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}
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Read the box from the GSERIALIZED or calculate it if necessary.
Definition gserialized.c:94
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
Definition lwpoint.c:57
void lwpoint_free(LWPOINT *pt)
Definition lwpoint.c:213
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
LWGEOM * lwgeom_closest_line(const LWGEOM *lw1, const LWGEOM *lw2)
Definition measures.c:43
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
Definition lwline.c:319
#define LINETYPE
Definition liblwgeom.h:103
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:2066
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:962
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
double lwgeom_length_2d(const LWGEOM *geom)
Definition lwgeom.c:2088
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:207
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition lwgeom.c:969
LWGEOM * lwgeom_closest_line_3d(const LWGEOM *lw1, const LWGEOM *lw2)
Definition measures3d.c:110
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition lwinline.h:141
static double distance(double x1, double y1, double x2, double y2)
Definition lwtree.c:1032
double mmax
Definition liblwgeom.h:361
double mmin
Definition liblwgeom.h:360
double m
Definition liblwgeom.h:414

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: