PostGIS  3.0.0dev-r@@SVN_REVISION@@

◆ 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 804 of file lwgeodetic.c.

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.

805 {
806  GEOGRAPHIC_EDGE g;
808  double slon = fabs((e->start).lon) + fabs((e->end).lon);
809  double dlon = fabs(fabs((e->start).lon) - fabs((e->end).lon));
810  double slat = (e->start).lat + (e->end).lat;
811 
812  LWDEBUGF(4, "e.start == GPOINT(%.6g %.6g) ", (e->start).lat, (e->start).lon);
813  LWDEBUGF(4, "e.end == GPOINT(%.6g %.6g) ", (e->end).lat, (e->end).lon);
814  LWDEBUGF(4, "p == GPOINT(%.6g %.6g) ", p->lat, p->lon);
815 
816  /* Copy values into working registers */
817  g = *e;
818  q = *p;
819 
820  /* Vertical plane, we need to do this calculation in latitude */
821  if ( FP_EQUALS( g.start.lon, g.end.lon ) )
822  {
823  LWDEBUG(4, "vertical plane, we need to do this calculation in latitude");
824  /* Supposed to be co-planar... */
825  if ( ! FP_EQUALS( q.lon, g.start.lon ) )
826  return LW_FALSE;
827 
828  if ( ( g.start.lat <= q.lat && q.lat <= g.end.lat ) ||
829  ( g.end.lat <= q.lat && q.lat <= g.start.lat ) )
830  {
831  return LW_TRUE;
832  }
833  else
834  {
835  return LW_FALSE;
836  }
837  }
838 
839  /* Over the pole, we need normalize latitude and do this calculation in latitude */
840  if ( FP_EQUALS( slon, M_PI ) && ( SIGNUM(g.start.lon) != SIGNUM(g.end.lon) || FP_EQUALS(dlon, M_PI) ) )
841  {
842  LWDEBUG(4, "over the pole...");
843  /* Antipodal, everything (or nothing?) is inside */
844  if ( FP_EQUALS( slat, 0.0 ) )
845  return LW_TRUE;
846 
847  /* Point *is* the north pole */
848  if ( slat > 0.0 && FP_EQUALS(q.lat, M_PI_2 ) )
849  return LW_TRUE;
850 
851  /* Point *is* the south pole */
852  if ( slat < 0.0 && FP_EQUALS(q.lat, -1.0 * M_PI_2) )
853  return LW_TRUE;
854 
855  LWDEBUG(4, "coplanar?...");
856 
857  /* Supposed to be co-planar... */
858  if ( ! FP_EQUALS( q.lon, g.start.lon ) )
859  return LW_FALSE;
860 
861  LWDEBUG(4, "north or south?...");
862 
863  /* Over north pole, test based on south pole */
864  if ( slat > 0.0 )
865  {
866  LWDEBUG(4, "over the north pole...");
867  if ( q.lat > FP_MIN(g.start.lat, g.end.lat) )
868  return LW_TRUE;
869  else
870  return LW_FALSE;
871  }
872  else
873  /* Over south pole, test based on north pole */
874  {
875  LWDEBUG(4, "over the south pole...");
876  if ( q.lat < FP_MAX(g.start.lat, g.end.lat) )
877  return LW_TRUE;
878  else
879  return LW_FALSE;
880  }
881  }
882 
883  /* Dateline crossing, flip everything to the opposite hemisphere */
884  else if ( slon > M_PI && ( SIGNUM(g.start.lon) != SIGNUM(g.end.lon) ) )
885  {
886  LWDEBUG(4, "crosses dateline, flip longitudes...");
887  if ( g.start.lon > 0.0 )
888  g.start.lon -= M_PI;
889  else
890  g.start.lon += M_PI;
891  if ( g.end.lon > 0.0 )
892  g.end.lon -= M_PI;
893  else
894  g.end.lon += M_PI;
895 
896  if ( q.lon > 0.0 )
897  q.lon -= M_PI;
898  else
899  q.lon += M_PI;
900  }
901 
902  if ( ( g.start.lon <= q.lon && q.lon <= g.end.lon ) ||
903  ( g.end.lon <= q.lon && q.lon <= g.start.lon ) )
904  {
905  LWDEBUG(4, "true, this edge contains point");
906  return LW_TRUE;
907  }
908 
909  LWDEBUG(4, "false, this edge does not contain point");
910  return LW_FALSE;
911 }
Two-point great circle segment from a to b.
Definition: lwgeodetic.h:56
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define FP_MIN(A, B)
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:47
#define LW_FALSE
Definition: liblwgeom.h:76
GEOGRAPHIC_POINT start
Definition: lwgeodetic.h:58
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
GEOGRAPHIC_POINT end
Definition: lwgeodetic.h:59
#define FP_EQUALS(A, B)
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
#define SIGNUM(n)
Macro that returns: -1 if n < 0, 1 if n > 0, 0 if n == 0.
#define FP_MAX(A, B)