PostGIS  2.1.10dev-r@@SVN_REVISION@@
double ptarray_length_spheroid ( const POINTARRAY pa,
const SPHEROID s 
)

Definition at line 2828 of file lwgeodetic.c.

References SPHEROID::a, SPHEROID::b, POINTARRAY::flags, FLAGS_GET_Z, geographic_point_init(), getPoint4d_p(), LW_FALSE, POINTARRAY::npoints, SPHEROID::radius, sphere_distance(), spheroid_distance(), POINT4D::x, POINT4D::y, and POINT4D::z.

Referenced by lwgeom_length_spheroid().

2829 {
2830  GEOGRAPHIC_POINT a, b;
2831  double za = 0.0, zb = 0.0;
2832  POINT4D p;
2833  int i;
2834  int hasz = LW_FALSE;
2835  double length = 0.0;
2836  double seglength = 0.0;
2837 
2838  /* Return zero on non-sensical inputs */
2839  if ( ! pa || pa->npoints < 2 )
2840  return 0.0;
2841 
2842  /* See if we have a third dimension */
2843  hasz = FLAGS_GET_Z(pa->flags);
2844 
2845  /* Initialize first point */
2846  getPoint4d_p(pa, 0, &p);
2847  geographic_point_init(p.x, p.y, &a);
2848  if ( hasz )
2849  za = p.z;
2850 
2851  /* Loop and sum the length for each segment */
2852  for ( i = 1; i < pa->npoints; i++ )
2853  {
2854  seglength = 0.0;
2855  getPoint4d_p(pa, i, &p);
2856  geographic_point_init(p.x, p.y, &b);
2857  if ( hasz )
2858  zb = p.z;
2859 
2860  /* Special sphere case */
2861  if ( s->a == s->b )
2862  seglength = s->radius * sphere_distance(&a, &b);
2863  /* Spheroid case */
2864  else
2865  seglength = spheroid_distance(&a, &b, s);
2866 
2867  /* Add in the vertical displacement if we're in 3D */
2868  if ( hasz )
2869  seglength = sqrt( (zb-za)*(zb-za) + seglength*seglength );
2870 
2871  /* Add this segment length to the total */
2872  length += seglength;
2873 
2874  /* B gets incremented in the next loop, so we save the value here */
2875  a = b;
2876  za = zb;
2877  }
2878  return length;
2879 }
double x
Definition: liblwgeom.h:308
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:897
int npoints
Definition: liblwgeom.h:327
double b
Definition: liblwgeom.h:270
double radius
Definition: liblwgeom.h:274
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:33
#define LW_FALSE
Definition: liblwgeom.h:52
uint8_t flags
Definition: liblwgeom.h:325
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:106
double z
Definition: liblwgeom.h:308
double a
Definition: liblwgeom.h:269
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g)
Initialize a geographic point.
Definition: lwgeodetic.c:157
double spheroid_distance(const GEOGRAPHIC_POINT *a, const GEOGRAPHIC_POINT *b, const SPHEROID *spheroid)
Computes the shortest distance along the surface of the spheroid between two points.
Definition: lwspheroid.c:59
double y
Definition: liblwgeom.h:308
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:217

Here is the call graph for this function:

Here is the caller graph for this function: