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

◆ edge_contains_coplanar_point()

int edge_contains_coplanar_point ( const GEOGRAPHIC_EDGE e,
const GEOGRAPHIC_POINT p 
)

True if the longitude of p is within the range of the longitude of the ends of e.

Definition at line 835 of file lwgeodetic.c.

836{
839 double slon = fabs((e->start).lon) + fabs((e->end).lon);
840 double dlon = fabs(fabs((e->start).lon) - fabs((e->end).lon));
841 double slat = (e->start).lat + (e->end).lat;
842
843 LWDEBUGF(4, "e.start == GPOINT(%.6g %.6g) ", (e->start).lat, (e->start).lon);
844 LWDEBUGF(4, "e.end == GPOINT(%.6g %.6g) ", (e->end).lat, (e->end).lon);
845 LWDEBUGF(4, "p == GPOINT(%.6g %.6g) ", p->lat, p->lon);
846
847 /* Copy values into working registers */
848 g = *e;
849 q = *p;
850
851 /* Vertical plane, we need to do this calculation in latitude */
852 if ( FP_EQUALS( g.start.lon, g.end.lon ) )
853 {
854 LWDEBUG(4, "vertical plane, we need to do this calculation in latitude");
855 /* Supposed to be co-planar... */
856 if ( ! FP_EQUALS( q.lon, g.start.lon ) )
857 return LW_FALSE;
858
859 if ( ( g.start.lat <= q.lat && q.lat <= g.end.lat ) ||
860 ( g.end.lat <= q.lat && q.lat <= g.start.lat ) )
861 {
862 return LW_TRUE;
863 }
864 else
865 {
866 return LW_FALSE;
867 }
868 }
869
870 /* Over the pole, we need normalize latitude and do this calculation in latitude */
871 if ( FP_EQUALS( slon, M_PI ) && ( SIGNUM(g.start.lon) != SIGNUM(g.end.lon) || FP_EQUALS(dlon, M_PI) ) )
872 {
873 LWDEBUG(4, "over the pole...");
874 /* Antipodal, everything (or nothing?) is inside */
875 if ( FP_EQUALS( slat, 0.0 ) )
876 return LW_TRUE;
877
878 /* Point *is* the north pole */
879 if ( slat > 0.0 && FP_EQUALS(q.lat, M_PI_2 ) )
880 return LW_TRUE;
881
882 /* Point *is* the south pole */
883 if ( slat < 0.0 && FP_EQUALS(q.lat, -1.0 * M_PI_2) )
884 return LW_TRUE;
885
886 LWDEBUG(4, "coplanar?...");
887
888 /* Supposed to be co-planar... */
889 if ( ! FP_EQUALS( q.lon, g.start.lon ) )
890 return LW_FALSE;
891
892 LWDEBUG(4, "north or south?...");
893
894 /* Over north pole, test based on south pole */
895 if ( slat > 0.0 )
896 {
897 LWDEBUG(4, "over the north pole...");
898 if ( q.lat > FP_MIN(g.start.lat, g.end.lat) )
899 return LW_TRUE;
900 else
901 return LW_FALSE;
902 }
903 else
904 /* Over south pole, test based on north pole */
905 {
906 LWDEBUG(4, "over the south pole...");
907 if ( q.lat < FP_MAX(g.start.lat, g.end.lat) )
908 return LW_TRUE;
909 else
910 return LW_FALSE;
911 }
912 }
913
914 /* Dateline crossing, flip everything to the opposite hemisphere */
915 else if ( slon > M_PI && ( SIGNUM(g.start.lon) != SIGNUM(g.end.lon) ) )
916 {
917 LWDEBUG(4, "crosses dateline, flip longitudes...");
918 if ( g.start.lon > 0.0 )
919 g.start.lon -= M_PI;
920 else
921 g.start.lon += M_PI;
922 if ( g.end.lon > 0.0 )
923 g.end.lon -= M_PI;
924 else
925 g.end.lon += M_PI;
926
927 if ( q.lon > 0.0 )
928 q.lon -= M_PI;
929 else
930 q.lon += M_PI;
931 }
932
933 if ( ( g.start.lon <= q.lon && q.lon <= g.end.lon ) ||
934 ( g.end.lon <= q.lon && q.lon <= g.start.lon ) )
935 {
936 LWDEBUG(4, "true, this edge contains point");
937 return LW_TRUE;
938 }
939
940 LWDEBUG(4, "false, this edge does not contain point");
941 return LW_FALSE;
942}
#define LW_FALSE
Definition liblwgeom.h:108
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
#define SIGNUM(n)
Macro that returns: -1 if n < 0, 1 if n > 0, 0 if n == 0.
#define FP_MAX(A, B)
#define FP_MIN(A, B)
#define FP_EQUALS(A, B)
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
GEOGRAPHIC_POINT start
Definition lwgeodetic.h:64
GEOGRAPHIC_POINT end
Definition lwgeodetic.h:65
Two-point great circle segment from a to b.
Definition lwgeodetic.h:63
Point in spherical coordinates on the world.
Definition lwgeodetic.h:54

References GEOGRAPHIC_EDGE::end, FP_EQUALS, FP_MAX, FP_MIN, GEOGRAPHIC_POINT::lat, GEOGRAPHIC_POINT::lon, LW_FALSE, LW_TRUE, LWDEBUG, LWDEBUGF, SIGNUM, and GEOGRAPHIC_EDGE::start.