PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ ptarray_length_spheroid()

double ptarray_length_spheroid ( const POINTARRAY pa,
const SPHEROID s 
)

Definition at line 3228 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().

3229 {
3230  GEOGRAPHIC_POINT a, b;
3231  double za = 0.0, zb = 0.0;
3232  POINT4D p;
3233  int i;
3234  int hasz = LW_FALSE;
3235  double length = 0.0;
3236  double seglength = 0.0;
3237 
3238  /* Return zero on non-sensical inputs */
3239  if ( ! pa || pa->npoints < 2 )
3240  return 0.0;
3241 
3242  /* See if we have a third dimension */
3243  hasz = FLAGS_GET_Z(pa->flags);
3244 
3245  /* Initialize first point */
3246  getPoint4d_p(pa, 0, &p);
3247  geographic_point_init(p.x, p.y, &a);
3248  if ( hasz )
3249  za = p.z;
3250 
3251  /* Loop and sum the length for each segment */
3252  for ( i = 1; i < pa->npoints; i++ )
3253  {
3254  seglength = 0.0;
3255  getPoint4d_p(pa, i, &p);
3256  geographic_point_init(p.x, p.y, &b);
3257  if ( hasz )
3258  zb = p.z;
3259 
3260  /* Special sphere case */
3261  if ( s->a == s->b )
3262  seglength = s->radius * sphere_distance(&a, &b);
3263  /* Spheroid case */
3264  else
3265  seglength = spheroid_distance(&a, &b, s);
3266 
3267  /* Add in the vertical displacement if we're in 3D */
3268  if ( hasz )
3269  seglength = sqrt( (zb-za)*(zb-za) + seglength*seglength );
3270 
3271  /* Add this segment length to the total */
3272  length += seglength;
3273 
3274  /* B gets incremented in the next loop, so we save the value here */
3275  a = b;
3276  za = zb;
3277  }
3278  return length;
3279 }
double x
Definition: liblwgeom.h:352
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:944
int npoints
Definition: liblwgeom.h:371
double b
Definition: liblwgeom.h:314
double radius
Definition: liblwgeom.h:318
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:52
#define LW_FALSE
Definition: liblwgeom.h:77
uint8_t flags
Definition: liblwgeom.h:369
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:140
double z
Definition: liblwgeom.h:352
double a
Definition: liblwgeom.h:313
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g)
Initialize a geographic point.
Definition: lwgeodetic.c:180
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:186
double y
Definition: liblwgeom.h:352
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:122
Here is the call graph for this function:
Here is the caller graph for this function: