LCOV - code coverage report
Current view: top level - contrib/earthdistance - earthdistance.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 20 22 90.9 %
Date: 2019-11-13 21:06:57 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* contrib/earthdistance/earthdistance.c */
       2             : 
       3             : #include "postgres.h"
       4             : 
       5             : #include <math.h>
       6             : 
       7             : #include "utils/geo_decls.h"  /* for Point */
       8             : 
       9             : #ifndef M_PI
      10             : #define M_PI 3.14159265358979323846
      11             : #endif
      12             : 
      13           2 : PG_MODULE_MAGIC;
      14             : 
      15             : /* Earth's radius is in statute miles. */
      16             : static const double EARTH_RADIUS = 3958.747716;
      17             : static const double TWO_PI = 2.0 * M_PI;
      18             : 
      19             : 
      20             : /******************************************************
      21             :  *
      22             :  * degtorad - convert degrees to radians
      23             :  *
      24             :  * arg: double, angle in degrees
      25             :  *
      26             :  * returns: double, same angle in radians
      27             :  ******************************************************/
      28             : 
      29             : static double
      30         192 : degtorad(double degrees)
      31             : {
      32         192 :     return (degrees / 360.0) * TWO_PI;
      33             : }
      34             : 
      35             : /******************************************************
      36             :  *
      37             :  * geo_distance_internal - distance between points
      38             :  *
      39             :  * args:
      40             :  *   a pair of points - for each point,
      41             :  *     x-coordinate is longitude in degrees west of Greenwich
      42             :  *     y-coordinate is latitude in degrees above equator
      43             :  *
      44             :  * returns: double
      45             :  *   distance between the points in miles on earth's surface
      46             :  ******************************************************/
      47             : 
      48             : static double
      49          48 : geo_distance_internal(Point *pt1, Point *pt2)
      50             : {
      51             :     double      long1,
      52             :                 lat1,
      53             :                 long2,
      54             :                 lat2;
      55             :     double      longdiff;
      56             :     double      sino;
      57             : 
      58             :     /* convert degrees to radians */
      59             : 
      60          48 :     long1 = degtorad(pt1->x);
      61          48 :     lat1 = degtorad(pt1->y);
      62             : 
      63          48 :     long2 = degtorad(pt2->x);
      64          48 :     lat2 = degtorad(pt2->y);
      65             : 
      66             :     /* compute difference in longitudes - want < 180 degrees */
      67          48 :     longdiff = fabs(long1 - long2);
      68          48 :     if (longdiff > M_PI)
      69           0 :         longdiff = TWO_PI - longdiff;
      70             : 
      71          96 :     sino = sqrt(sin(fabs(lat1 - lat2) / 2.) * sin(fabs(lat1 - lat2) / 2.) +
      72          48 :                 cos(lat1) * cos(lat2) * sin(longdiff / 2.) * sin(longdiff / 2.));
      73          48 :     if (sino > 1.)
      74           0 :         sino = 1.;
      75             : 
      76          48 :     return 2. * EARTH_RADIUS * asin(sino);
      77             : }
      78             : 
      79             : 
      80             : /******************************************************
      81             :  *
      82             :  * geo_distance - distance between points
      83             :  *
      84             :  * args:
      85             :  *   a pair of points - for each point,
      86             :  *     x-coordinate is longitude in degrees west of Greenwich
      87             :  *     y-coordinate is latitude in degrees above equator
      88             :  *
      89             :  * returns: float8
      90             :  *   distance between the points in miles on earth's surface
      91             :  ******************************************************/
      92             : 
      93           4 : PG_FUNCTION_INFO_V1(geo_distance);
      94             : 
      95             : Datum
      96          48 : geo_distance(PG_FUNCTION_ARGS)
      97             : {
      98          48 :     Point      *pt1 = PG_GETARG_POINT_P(0);
      99          48 :     Point      *pt2 = PG_GETARG_POINT_P(1);
     100             :     float8      result;
     101             : 
     102          48 :     result = geo_distance_internal(pt1, pt2);
     103          48 :     PG_RETURN_FLOAT8(result);
     104             : }

Generated by: LCOV version 1.13