PostGIS  2.5.0beta2dev-r@@SVN_REVISION@@

◆ edge_calculate_gbox_slow()

int edge_calculate_gbox_slow ( const GEOGRAPHIC_EDGE e,
GBOX gbox 
)

Definition at line 1313 of file lwgeodetic.c.

References distance(), GEOGRAPHIC_EDGE::end, FP_EQUALS, FP_IS_ZERO, gbox_init_point3d(), gbox_merge_point3d(), geog2cart(), LW_SUCCESS, LWDEBUG, normalize(), sphere_distance(), GEOGRAPHIC_EDGE::start, POINT3D::x, GBOX::xmax, GBOX::xmin, POINT3D::y, GBOX::ymax, GBOX::ymin, POINT3D::z, GBOX::zmax, and GBOX::zmin.

1314 {
1315  int steps = 1000000;
1316  int i;
1317  double dx, dy, dz;
1318  double distance = sphere_distance(&(e->start), &(e->end));
1319  POINT3D pn, p, start, end;
1320 
1321  /* Edge is zero length, just return the naive box */
1322  if ( FP_IS_ZERO(distance) )
1323  {
1324  LWDEBUG(4, "edge is zero length. returning");
1325  geog2cart(&(e->start), &start);
1326  geog2cart(&(e->end), &end);
1327  gbox_init_point3d(&start, gbox);
1328  gbox_merge_point3d(&end, gbox);
1329  return LW_SUCCESS;
1330  }
1331 
1332  /* Edge is antipodal (one point on each side of the globe),
1333  set the box to contain the whole world and return */
1334  if ( FP_EQUALS(distance, M_PI) )
1335  {
1336  LWDEBUG(4, "edge is antipodal. setting to maximum size box, and returning");
1337  gbox->xmin = gbox->ymin = gbox->zmin = -1.0;
1338  gbox->xmax = gbox->ymax = gbox->zmax = 1.0;
1339  return LW_SUCCESS;
1340  }
1341 
1342  /* Walk along the chord between start and end incrementally,
1343  normalizing at each step. */
1344  geog2cart(&(e->start), &start);
1345  geog2cart(&(e->end), &end);
1346  dx = (end.x - start.x)/steps;
1347  dy = (end.y - start.y)/steps;
1348  dz = (end.z - start.z)/steps;
1349  p = start;
1350  gbox->xmin = gbox->xmax = p.x;
1351  gbox->ymin = gbox->ymax = p.y;
1352  gbox->zmin = gbox->zmax = p.z;
1353  for ( i = 0; i < steps; i++ )
1354  {
1355  p.x += dx;
1356  p.y += dy;
1357  p.z += dz;
1358  pn = p;
1359  normalize(&pn);
1360  gbox_merge_point3d(&pn, gbox);
1361  }
1362  return LW_SUCCESS;
1363 }
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:917
void normalize(POINT3D *p)
Normalize to a unit vector.
Definition: lwgeodetic.c:584
double y
Definition: liblwgeom.h:342
double xmax
Definition: liblwgeom.h:295
#define LW_SUCCESS
Definition: liblwgeom.h:79
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
double x
Definition: liblwgeom.h:342
int gbox_init_point3d(const POINT3D *p, GBOX *gbox)
Initialize a GBOX using the values of the point.
Definition: g_box.c:246
#define FP_IS_ZERO(A)
double z
Definition: liblwgeom.h:342
double zmax
Definition: liblwgeom.h:299
double ymin
Definition: liblwgeom.h:296
double xmin
Definition: liblwgeom.h:294
GEOGRAPHIC_POINT start
Definition: lwgeodetic.h:58
int gbox_merge_point3d(const POINT3D *p, GBOX *gbox)
Update the GBOX to be large enough to include itself and the new point.
Definition: g_box.c:235
double ymax
Definition: liblwgeom.h:297
GEOGRAPHIC_POINT end
Definition: lwgeodetic.h:59
Datum distance(PG_FUNCTION_ARGS)
void geog2cart(const GEOGRAPHIC_POINT *g, POINT3D *p)
Convert spherical coordinates to cartesian coordinates on unit sphere.
Definition: lwgeodetic.c:373
double zmin
Definition: liblwgeom.h:298
#define FP_EQUALS(A, B)
Here is the call graph for this function: