PostGIS  2.2.7dev-r@@SVN_REVISION@@
double edge_distance_to_point ( const GEOGRAPHIC_EDGE e,

Definition at line 1166 of file lwgeodetic.c.

References cart2geog(), dot_product(), edge_contains_point(), GEOGRAPHIC_EDGE::end, geog2cart(), geographic_point_equals(), normalize(), robust_cross_product(), sphere_distance(), GEOGRAPHIC_EDGE::start, vector_difference(), and vector_scale().

Referenced by circ_tree_contains_point(), circ_tree_distance_tree_internal(), edge_distance_to_edge(), ptarray_distance_spheroid(), and test_edge_distance_to_point().

1167 {
1168  double d1 = 1000000000.0, d2, d3, d_nearest;
1169  POINT3D n, p, k;
1170  GEOGRAPHIC_POINT gk, g_nearest;
1172  /* Zero length edge, */
1173  if ( geographic_point_equals(&(e->start), &(e->end)) )
1174  {
1175  *closest = e->start;
1176  return sphere_distance(&(e->start), gp);
1177  }
1179  robust_cross_product(&(e->start), &(e->end), &n);
1180  normalize(&n);
1181  geog2cart(gp, &p);
1182  vector_scale(&n, dot_product(&p, &n));
1183  vector_difference(&p, &n, &k);
1184  normalize(&k);
1185  cart2geog(&k, &gk);
1186  if ( edge_contains_point(e, &gk) )
1187  {
1188  d1 = sphere_distance(gp, &gk);
1189  }
1190  d2 = sphere_distance(gp, &(e->start));
1191  d3 = sphere_distance(gp, &(e->end));
1193  d_nearest = d1;
1194  g_nearest = gk;
1196  if ( d2 < d_nearest )
1197  {
1198  d_nearest = d2;
1199  g_nearest = e->start;
1200  }
1201  if ( d3 < d_nearest )
1202  {
1203  d_nearest = d3;
1204  g_nearest = e->end;
1205  }
1206  if (closest)
1207  *closest = g_nearest;
1209  return d_nearest;
1210 }
void robust_cross_product(const GEOGRAPHIC_POINT *p, const GEOGRAPHIC_POINT *q, POINT3D *a)
Computes the cross product of two vectors using their lat, lng representations.
Definition: lwgeodetic.c:584
double sphere_distance(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e)
Given two points on a unit sphere, calculate their distance apart in radians.
Definition: lwgeodetic.c:898
void normalize(POINT3D *p)
Normalize to a unit vector.
Definition: lwgeodetic.c:565
int edge_contains_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POINT *p)
Returns true if the point p is on the minor edge defined by the end points of e.
Definition: lwgeodetic.c:982
void cart2geog(const POINT3D *p, GEOGRAPHIC_POINT *g)
Convert cartesion coordinates on unit sphere to spherical coordinates.
Definition: lwgeodetic.c:364
static void vector_scale(POINT3D *n, double scale)
Scale a vector out by a factor.
Definition: lwgeodetic.c:437
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:32
static double dot_product(const POINT3D *p1, const POINT3D *p2)
Convert cartesion coordinates on unit sphere to lon/lat coordinates static void cart2ll(const POINT3D...
Definition: lwgeodetic.c:396
Definition: lwgeodetic.h:43
static void vector_difference(const POINT3D *a, const POINT3D *b, POINT3D *n)
Calculate the difference of two vectors.
Definition: lwgeodetic.c:426
Definition: lwgeodetic.h:44
void geog2cart(const GEOGRAPHIC_POINT *g, POINT3D *p)
Convert spherical coordinates to cartesion coordinates on unit sphere.
Definition: lwgeodetic.c:354
int geographic_point_equals(const GEOGRAPHIC_POINT *g1, const GEOGRAPHIC_POINT *g2)
Definition: lwgeodetic.c:146

Here is the call graph for this function:

Here is the caller graph for this function: