kopia lustrzana https://github.com/Hamlib/Hamlib
2003-08-21
Update: locator.c -- added argument int pair_count to longlat2locator() and changed longlat2locator() from void to type int return. Changed *seconds argument in dms2dec() and dec2dms() from type int to type double. rotator.h -- function prototypes to match above. testloc.c -- modified to support changes in locator.c Added additional command line parameter, locator-length which is expected after the first locator and before the optional second locator. git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@1517 7ae35d74-ebe9-4afe-98af-79ac388436b8Hamlib-1.2.0
rodzic
9efbb5e911
commit
da8d2e4b41
|
@ -2,7 +2,7 @@
|
||||||
* Hamlib Interface - Rotator API header
|
* Hamlib Interface - Rotator API header
|
||||||
* Copyright (c) 2000-2003 by Stephane Fillod
|
* Copyright (c) 2000-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: rotator.h,v 1.7 2003-04-27 22:14:40 fillods Exp $
|
* $Id: rotator.h,v 1.8 2003-08-21 20:22:06 n0nb Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Library General Public License as
|
* it under the terms of the GNU Library General Public License as
|
||||||
|
@ -334,15 +334,15 @@ extern HAMLIB_EXPORT(int) qrb HAMLIB_PARAMS((double lon1, double lat1,
|
||||||
extern HAMLIB_EXPORT(double) distance_long_path HAMLIB_PARAMS((double distance));
|
extern HAMLIB_EXPORT(double) distance_long_path HAMLIB_PARAMS((double distance));
|
||||||
extern HAMLIB_EXPORT(double) azimuth_long_path HAMLIB_PARAMS((double azimuth));
|
extern HAMLIB_EXPORT(double) azimuth_long_path HAMLIB_PARAMS((double azimuth));
|
||||||
|
|
||||||
extern HAMLIB_EXPORT(void) longlat2locator HAMLIB_PARAMS((double longitude,
|
extern HAMLIB_EXPORT(int) longlat2locator HAMLIB_PARAMS((double longitude,
|
||||||
double latitude, char *locator));
|
double latitude, char *locator, int pair_count));
|
||||||
extern HAMLIB_EXPORT(int) locator2longlat HAMLIB_PARAMS((double *longitude,
|
extern HAMLIB_EXPORT(int) locator2longlat HAMLIB_PARAMS((double *longitude,
|
||||||
double *latitude, const char *locator));
|
double *latitude, const char *locator));
|
||||||
|
|
||||||
extern HAMLIB_EXPORT(double) dms2dec HAMLIB_PARAMS((int degs, int minutes,
|
extern HAMLIB_EXPORT(double) dms2dec HAMLIB_PARAMS((int degs, int minutes,
|
||||||
int seconds));
|
double seconds));
|
||||||
extern HAMLIB_EXPORT(void) dec2dms HAMLIB_PARAMS((double dec, int *degrees,
|
extern HAMLIB_EXPORT(void) dec2dms HAMLIB_PARAMS((double dec, int *degrees,
|
||||||
int *minutes, int *seconds));
|
int *minutes, double *seconds));
|
||||||
|
|
||||||
|
|
||||||
/*! \def rot_debug
|
/*! \def rot_debug
|
||||||
|
|
118
src/locator.c
118
src/locator.c
|
@ -14,7 +14,7 @@
|
||||||
* Copyright (c) 2003 by Nate Bargmann
|
* Copyright (c) 2003 by Nate Bargmann
|
||||||
* Copyright (c) 2003 by Dave Hines
|
* Copyright (c) 2003 by Dave Hines
|
||||||
*
|
*
|
||||||
* $Id: locator.c,v 1.8 2003-08-21 03:11:27 n0nb Exp $
|
* $Id: locator.c,v 1.9 2003-08-21 20:22:06 n0nb Exp $
|
||||||
*
|
*
|
||||||
* Code to determine bearing and range was taken from the Great Circle,
|
* Code to determine bearing and range was taken from the Great Circle,
|
||||||
* by S. R. Sampson, N5OWK.
|
* by S. R. Sampson, N5OWK.
|
||||||
|
@ -68,6 +68,38 @@
|
||||||
/* arc length for 1 degree, 60 Nautical Miles */
|
/* arc length for 1 degree, 60 Nautical Miles */
|
||||||
#define ARC_IN_KM 111.2
|
#define ARC_IN_KM 111.2
|
||||||
|
|
||||||
|
/* The following is contributed by Dave Hines
|
||||||
|
*
|
||||||
|
* begin dph
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* These are the constants used when converting between Maidenhead grid
|
||||||
|
* locators and longitude/latitude values. MAX_LOCATOR_PAIRS is the maximum
|
||||||
|
* number of locator character pairs to convert. This number MUST NOT exceed
|
||||||
|
* the number of pairs of values in range[] & weight[].
|
||||||
|
* Setting MAX_LOCATOR_PAIRS to 3 will convert the currently defined 6
|
||||||
|
* character locators. A value of 4 will convert the extended 8 character
|
||||||
|
* locators described in section 3L of "The IARU region 1 VHF managers
|
||||||
|
* handbook". Values of 5 and 6 will extent the format even more, to the
|
||||||
|
* longest definition I have seen for locators. Beware that there seems to be
|
||||||
|
* no universally accepted standard for 10 & 12 character locators.
|
||||||
|
* Note that the loc_char_weight values are in minutes of arc, to avoid
|
||||||
|
* constants which can't be represented precisely in either binary or decimal.
|
||||||
|
*
|
||||||
|
* MAX_LOCATOR_PAIRS now sets the limit locator2longlat() will convert and
|
||||||
|
* sets the maximum length longlat2locator() will generate. Each function
|
||||||
|
* properly handles any value from 1 to 6 so MAX_LOCATOR_PAIRS should be
|
||||||
|
* left at 6. MIN_LOCATOR_PAIRS sets a floor on the shortest locator that
|
||||||
|
* should be handled. -N0NB
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const static double loc_char_weight[] = { 600.0, 60.0, 2.5, 0.25, 0.01, 0.001 };
|
||||||
|
const static int loc_char_range[] = { 18, 10, 24, 10, 25, 10 };
|
||||||
|
#define MAX_LOCATOR_PAIRS 6
|
||||||
|
#define MIN_LOCATOR_PAIRS 1
|
||||||
|
|
||||||
|
/* end dph */
|
||||||
|
|
||||||
#endif /* !DOC_HIDDEN */
|
#endif /* !DOC_HIDDEN */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,11 +116,11 @@
|
||||||
*
|
*
|
||||||
* \sa dec2dms()
|
* \sa dec2dms()
|
||||||
*/
|
*/
|
||||||
double dms2dec(int degrees, int minutes, int seconds) {
|
double dms2dec(int degrees, int minutes, double seconds) {
|
||||||
if (degrees >= 0)
|
if (degrees >= 0)
|
||||||
return (double)degrees + (double)minutes/60. + (double)seconds/3600.;
|
return (double)degrees + (double)minutes/60. + seconds/3600.;
|
||||||
else
|
else
|
||||||
return (double)degrees - (double)minutes/60. - (double)seconds/3600.;
|
return (double)degrees - (double)minutes/60. - seconds/3600.;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,8 +140,8 @@ double dms2dec(int degrees, int minutes, int seconds) {
|
||||||
*
|
*
|
||||||
* \sa dms2dec()
|
* \sa dms2dec()
|
||||||
*/
|
*/
|
||||||
void dec2dms(double dec, int *degrees, int *minutes, int *seconds) {
|
void dec2dms(double dec, int *degrees, int *minutes, double *seconds) {
|
||||||
int deg, min, sec, is_neg = 0;
|
int deg, min, is_neg = 0;
|
||||||
double st;
|
double st;
|
||||||
|
|
||||||
if (!degrees || !minutes || !seconds)
|
if (!degrees || !minutes || !seconds)
|
||||||
|
@ -147,54 +179,14 @@ void dec2dms(double dec, int *degrees, int *minutes, int *seconds) {
|
||||||
st = 60. * (st-(double)deg);
|
st = 60. * (st-(double)deg);
|
||||||
min = (int)floor(st);
|
min = (int)floor(st);
|
||||||
st = 60. * (st-(double)min);
|
st = 60. * (st-(double)min);
|
||||||
sec = (int)floor(st);
|
|
||||||
|
|
||||||
/* round fractional seconds up if greater than sec.5
|
|
||||||
* round up min and deg if warranted.
|
|
||||||
*/
|
|
||||||
if (fmod(st, sec) >= 0.5) {
|
|
||||||
sec++;
|
|
||||||
if (sec == 60) {
|
|
||||||
sec = 0;
|
|
||||||
min++;
|
|
||||||
if (min == 60) {
|
|
||||||
min = 0;
|
|
||||||
deg++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set *degrees to original sign passed to dec */
|
/* set *degrees to original sign passed to dec */
|
||||||
(is_neg == 1) ? (*degrees = deg * -1) : (*degrees = deg);
|
(is_neg == 1) ? (*degrees = deg * -1) : (*degrees = deg);
|
||||||
|
|
||||||
*minutes = min;
|
*minutes = min;
|
||||||
*seconds = sec;
|
*seconds = st;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following is contributed by Dave Hines
|
|
||||||
*
|
|
||||||
* begin dph
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* These are the constants used when converting between Maidenhead grid
|
|
||||||
* locators and longitude/latitude values. MAX_LOCATOR_PAIRS is the maximum
|
|
||||||
* number of locator character pairs to convert. This number MUST NOT exceed
|
|
||||||
* the number of pairs of values in range[] & weight[].
|
|
||||||
* Setting MAX_LOCATOR_PAIRS to 3 will convert the currently defined 6
|
|
||||||
* character locators. A value of 4 will convert the extended 8 character
|
|
||||||
* locators described in section 3L of "The IARU region 1 VHF managers
|
|
||||||
* handbook". Values of 5 and 6 will extent the format even more, to the
|
|
||||||
* longest definition I have seen for locators. Beware that there seems to be
|
|
||||||
* no universally accepted standard for 10 & 12 character locators.
|
|
||||||
* Note that the loc_char_weight values are in minutes of arc, to avoid
|
|
||||||
* constants which can't be represented precisely in either binary or decimal.
|
|
||||||
*/
|
|
||||||
const static double loc_char_weight[] = { 600.0, 60.0, 2.5, 0.25, 0.01, 0.001 };
|
|
||||||
const static int loc_char_range[] = { 18, 10, 24, 10, 25, 10 };
|
|
||||||
#define MAX_LOCATOR_PAIRS 6
|
|
||||||
|
|
||||||
/* end dph */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Convert Maidenhead grid locator to longitude/latitude
|
* \brief Convert Maidenhead grid locator to longitude/latitude
|
||||||
* \param longitude The location where to store longitude, decimal
|
* \param longitude The location where to store longitude, decimal
|
||||||
|
@ -212,7 +204,7 @@ const static int loc_char_range[] = { 18, 10, 24, 10, 25, 10 };
|
||||||
* and 1' 15" from south boundary.
|
* and 1' 15" from south boundary.
|
||||||
*
|
*
|
||||||
* \return RIG_OK to indicate conversion went ok, -RIG_EINVAL if locator
|
* \return RIG_OK to indicate conversion went ok, -RIG_EINVAL if locator
|
||||||
* exceeds RR99xx or is malformed (not of 2 through 12 character format).
|
* exceeds RR99xx or exceeds length limit. Currently 1 to 6 lon/lat pairs.
|
||||||
*
|
*
|
||||||
* \sa longlat2locator()
|
* \sa longlat2locator()
|
||||||
*/
|
*/
|
||||||
|
@ -220,12 +212,16 @@ const static int loc_char_range[] = { 18, 10, 24, 10, 25, 10 };
|
||||||
/* begin dph */
|
/* begin dph */
|
||||||
|
|
||||||
int locator2longlat(double *longitude, double *latitude, const char *locator) {
|
int locator2longlat(double *longitude, double *latitude, const char *locator) {
|
||||||
int x_or_y, paircount = strlen(locator) / 2;
|
int x_or_y, paircount;
|
||||||
int locvalue, pair;
|
int locvalue, pair;
|
||||||
double xy[2], minutes;
|
double xy[2], minutes;
|
||||||
|
|
||||||
|
paircount = strlen(locator) / 2;
|
||||||
|
|
||||||
if (paircount > MAX_LOCATOR_PAIRS) /* Max. locator length to allow */
|
if (paircount > MAX_LOCATOR_PAIRS) /* Max. locator length to allow */
|
||||||
paircount = MAX_LOCATOR_PAIRS;
|
paircount = MAX_LOCATOR_PAIRS;
|
||||||
|
else if (paircount < MIN_LOCATOR_PAIRS)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
for (x_or_y = 0; x_or_y < 2; ++x_or_y) { /* For x(=long) and y(=lat) */
|
for (x_or_y = 0; x_or_y < 2; ++x_or_y) { /* For x(=long) and y(=lat) */
|
||||||
minutes = 0.0;
|
minutes = 0.0;
|
||||||
|
@ -241,7 +237,7 @@ int locator2longlat(double *longitude, double *latitude, const char *locator) {
|
||||||
|
|
||||||
minutes += locvalue * loc_char_weight[pair];
|
minutes += locvalue * loc_char_weight[pair];
|
||||||
}
|
}
|
||||||
minutes += loc_char_weight[paircount-1] / 2.0; /* Center coordinate */
|
minutes += loc_char_weight[paircount - 1] / 2.0; /* Center coordinate */
|
||||||
|
|
||||||
xy[x_or_y] = minutes / 60.0 - 90.0;
|
xy[x_or_y] = minutes / 60.0 - 90.0;
|
||||||
}
|
}
|
||||||
|
@ -259,34 +255,44 @@ int locator2longlat(double *longitude, double *latitude, const char *locator) {
|
||||||
* \param longitude The longitude, decimal
|
* \param longitude The longitude, decimal
|
||||||
* \param latitude The latitude, decimal
|
* \param latitude The latitude, decimal
|
||||||
* \param locator The location where to store the locator
|
* \param locator The location where to store the locator
|
||||||
|
* \param pair_count The desired precision expressed as lon/lat pairs in the locator
|
||||||
*
|
*
|
||||||
* Convert longitude/latitude (decimal) to Maidenhead grid locator.
|
* Convert longitude/latitude (decimal) to Maidenhead grid locator.
|
||||||
* \a locator must point to an array at least MAX_LOCATOR_PAIRS*2 char plus nul long.
|
* \a locator must point to an array at least pair_count * 2 char plus '\0'.
|
||||||
|
*
|
||||||
|
* \return RIG_OK if locator was successfully computed. -RIG_EINVAL if
|
||||||
|
* pair_count exceeds length limit. Currently 1 to 6 lon/lat pairs.
|
||||||
*
|
*
|
||||||
* \sa locator2longlat()
|
* \sa locator2longlat()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* begin dph */
|
/* begin dph */
|
||||||
|
|
||||||
void longlat2locator(double longitude, double latitude, char *locator) {
|
int longlat2locator(double longitude, double latitude,
|
||||||
|
char *locator, int pair_count) {
|
||||||
int x_or_y, pair, locvalue;
|
int x_or_y, pair, locvalue;
|
||||||
double tmp;
|
double tmp;
|
||||||
|
|
||||||
|
if (pair_count < MIN_LOCATOR_PAIRS || pair_count > MAX_LOCATOR_PAIRS)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
for (x_or_y = 0; x_or_y < 2; ++x_or_y) {
|
for (x_or_y = 0; x_or_y < 2; ++x_or_y) {
|
||||||
tmp = ((x_or_y == 0) ? longitude / 2. : latitude);
|
tmp = ((x_or_y == 0) ? longitude / 2. : latitude);
|
||||||
|
|
||||||
/* The 1e-6 here guards against floating point rounding errors */
|
/* The 1e-6 here guards against floating point rounding errors */
|
||||||
tmp = fmod(tmp + 270., 180.) * 60. + 1e-6;
|
tmp = fmod(tmp + 270., 180.) * 60. + 1e-6;
|
||||||
for (pair = 0; pair < MAX_LOCATOR_PAIRS; ++pair) {
|
for (pair = 0; pair < pair_count; ++pair) {
|
||||||
locvalue = (int) (tmp / loc_char_weight[pair]);
|
locvalue = (int) (tmp / loc_char_weight[pair]);
|
||||||
|
|
||||||
/* assert(locvalue < loc_char_range[pair]); */
|
/* assert(locvalue < loc_char_range[pair]); */
|
||||||
tmp -= loc_char_weight[pair] * locvalue;
|
tmp -= loc_char_weight[pair] * locvalue;
|
||||||
locvalue += (loc_char_range[pair] == 10) ? '0':'A';
|
locvalue += (loc_char_range[pair] == 10) ? '0':'A';
|
||||||
locator[pair*2 + x_or_y] = locvalue;
|
locator[pair * 2 + x_or_y] = locvalue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locator[MAX_LOCATOR_PAIRS * 2] = '\0';
|
locator[pair_count * 2] = '\0';
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end dph */
|
/* end dph */
|
||||||
|
|
|
@ -15,17 +15,18 @@
|
||||||
int main (int argc, char *argv[]) {
|
int main (int argc, char *argv[]) {
|
||||||
char recodedloc[13], *loc1, *loc2;
|
char recodedloc[13], *loc1, *loc2;
|
||||||
double lon1 = 0, lat1, lon2, lat2;
|
double lon1 = 0, lat1, lon2, lat2;
|
||||||
double distance, az;
|
double distance, az, sec;
|
||||||
int deg, min, sec;
|
int deg, min;
|
||||||
int retcode;
|
int retcode, locator_length;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: %s <locator1> [<locator2>]\n", argv[0]);
|
fprintf(stderr, "Usage: %s <locator1> <precision> [<locator2>]\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
loc1 = argv[1];
|
loc1 = argv[1];
|
||||||
loc2 = argc > 2 ? argv[2] : NULL;
|
locator_length = atoi(argv[2]);
|
||||||
|
loc2 = argc > 3 ? argv[3] : NULL;
|
||||||
|
|
||||||
printf("Locator1: %s\n", loc1);
|
printf("Locator1: %s\n", loc1);
|
||||||
retcode = locator2longlat(&lon1, &lat1, loc1);
|
retcode = locator2longlat(&lon1, &lat1, loc1);
|
||||||
|
@ -35,21 +36,20 @@ int main (int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dec2dms(lon1, °, &min, &sec);
|
dec2dms(lon1, °, &min, &sec);
|
||||||
printf(" Longitude: %f, %d° %d' %d\"\n", lon1, deg, min, sec);
|
printf(" Longitude: %f, %d° %d' %.2f\"\n", lon1, deg, min, sec);
|
||||||
lon1 = dms2dec(deg, min, sec);
|
lon1 = dms2dec(deg, min, sec);
|
||||||
printf(" Recoded lon: %f\n", lon1);
|
printf(" Recoded lon: %f\n", lon1);
|
||||||
|
|
||||||
dec2dms(lat1, °, &min, &sec);
|
dec2dms(lat1, °, &min, &sec);
|
||||||
printf(" Latitude: %f, %d° %d' %d\"\n", lat1, deg, min, sec);
|
printf(" Latitude: %f, %d° %d' %.2f\"\n", lat1, deg, min, sec);
|
||||||
lat1 = dms2dec(deg, min, sec);
|
lat1 = dms2dec(deg, min, sec);
|
||||||
printf(" Recoded lat: %f\n", lat1);
|
printf(" Recoded lat: %f\n", lat1);
|
||||||
|
|
||||||
longlat2locator(lon1, lat1, recodedloc);
|
longlat2locator(lon1, lat1, recodedloc, locator_length);
|
||||||
// recodedloc[6] = '\0';
|
|
||||||
printf(" Recoded: %s\n", recodedloc);
|
printf(" Recoded: %s\n", recodedloc);
|
||||||
|
|
||||||
if (loc2 == NULL)
|
if (loc2 == NULL)
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
printf("\nLocator2: %s\n", loc2);
|
printf("\nLocator2: %s\n", loc2);
|
||||||
retcode = locator2longlat(&lon2, &lat2, loc2);
|
retcode = locator2longlat(&lon2, &lat2, loc2);
|
||||||
|
@ -59,17 +59,16 @@ int main (int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dec2dms(lon2, °, &min, &sec);
|
dec2dms(lon2, °, &min, &sec);
|
||||||
printf(" Longitude: %f, %d° %d' %d\"\n", lon2, deg, min, sec);
|
printf(" Longitude: %f, %d° %d' %.2f\"\n", lon2, deg, min, sec);
|
||||||
lon2 = dms2dec(deg, min, sec);
|
lon2 = dms2dec(deg, min, sec);
|
||||||
printf(" Recoded lon: %f\n", lon2);
|
printf(" Recoded lon: %f\n", lon2);
|
||||||
|
|
||||||
dec2dms(lat2, °, &min, &sec);
|
dec2dms(lat2, °, &min, &sec);
|
||||||
printf(" Latitude: %f, %d° %d' %d\"\n", lat2, deg, min, sec);
|
printf(" Latitude: %f, %d° %d' %.2f\"\n", lat2, deg, min, sec);
|
||||||
lat2 = dms2dec(deg, min, sec);
|
lat2 = dms2dec(deg, min, sec);
|
||||||
printf(" Recoded lat: %f\n", lat2);
|
printf(" Recoded lat: %f\n", lat2);
|
||||||
|
|
||||||
longlat2locator(lon2, lat2, recodedloc);
|
longlat2locator(lon2, lat2, recodedloc, locator_length);
|
||||||
// recodedloc[6] = '\0';
|
|
||||||
printf(" Recoded: %s\n", recodedloc);
|
printf(" Recoded: %s\n", recodedloc);
|
||||||
|
|
||||||
retcode = qrb(lon1, lat1, lon2, lat2, &distance, &az);
|
retcode = qrb(lon1, lat1, lon2, lat2, &distance, &az);
|
||||||
|
@ -79,7 +78,7 @@ int main (int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
dec2dms(az, °, &min, &sec);
|
dec2dms(az, °, &min, &sec);
|
||||||
printf("\nDistance: %.2fkm\n", distance);
|
printf("\nDistance: %.2fkm\n", distance);
|
||||||
printf("Bearing: %f, %d° %d' %d\"\n", az, deg, min, sec);
|
printf("Bearing: %f, %d° %d' %.2f\"\n", az, deg, min, sec);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue