[R] Converting coordinates to actual distances
Jim Lemon
bitwrit at ozemail.com.au
Fri Sep 16 09:35:27 CEST 2005
Paul Brewin wrote:
> Hello,
>
> I've been searching for a method of converting Lat/Lon decimal
> coordinates into actual distances between points, and taking into
> account the curvature of the earth. Is there such a package in R? I've
> looked at the GeoR package, but this does not seem to contain what I am
> looking for. Ideally the output would be a triangular matrix of
> distances.
Hi Paul,
Below is an implementation of the Haversine formula that I once had to
use for calculating distances between telephone exchanges. It's in C,
but could be translated to R fairly easily. I've included a degrees to
radians conversion as well.
Jim
#define APOSTROPHE 39
#define EARTH_RADIUS 6367
typedef struct {
char *basename;
char *number[2];
double lat[2];
double lon[2];
char delimiter[4];
char *data02;
char *data03;
char *data07;
char *data08;
FILE *input;
FILE *output;
} PSTS_INFO;
/* DegreesToRadians
Converts a string of the form nnndnn'nn"[NSEW] to a value in radians.
East (E) and South (S) are arbitrarily negative. Note that this routine
will generate garbage if not passed a string of the correct form,
although it is unlikely to do too much damage.
Return value value of the string in radians
-10 input not correct format
*/
double DegreesToRadians(char *dms) {
int index = 0;
double degrees;
double minutes = 0;
double seconds = 0;
int mult;
degrees = atof(dms);
while(isdigit(dms[index])) index++;
if(dms[index++] == 'd') {
minutes = atof(&dms[index]);
minutes /= 60;
while(isdigit(dms[index])) index++;
if(dms[index++] == APOSTROPHE) {
seconds = atof(&dms[index]);
seconds /= 360;
while(isdigit(dms[index]) && dms[index]) index++;
if(dms[index++] == QUOTES) {
mult = (dms[index] == 'S' || dms[index] == 'E') ? -1 : 1;
degrees += minutes + seconds;
return(mult * degrees * M_PI/180);
}
}
}
return(-10);
}
/* GreatCircleDistance
(Formula and recommendations for calculation taken from:
http://www.census.gov/cgi-bin/geo/gisfaq?Q5.1
by Bob Chamberlain - rgc at solstice.jpl.nasa.gov)
Calculates 'great circle' distances using the Haversine formula,
based upon a spherical earth of EARTH_RADIUS radius.
This version extracts the two latitude/longitude pairs (as radians)
from the PSTS_INFO structure.
*/
double GreatCircleDist(PSTS_INFO *psts_info) {
double a,d,dlon,dlat;
dlon = psts_info->lon[1] - psts_info->lon[0];
dlat = psts_info->lat[1] - psts_info->lat[0];
a = pow(sin(dlat / 2),2) + cos(psts_info->lat[0]) *
cos(psts_info->lat[1]) * pow(sin(dlon / 2),2);
/* The penultimate result may be calculated either way - the first
is bulletproof, the second is a bit faster */
d = 2 * atan2(sqrt(a),sqrt(1 - a));
/* d = 2 * asin(sqrt(a));*/
return(d * EARTH_RADIUS);
}
More information about the R-help
mailing list