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
|
||||
* 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
|
||||
* 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) azimuth_long_path HAMLIB_PARAMS((double azimuth));
|
||||
|
||||
extern HAMLIB_EXPORT(void) longlat2locator HAMLIB_PARAMS((double longitude,
|
||||
double latitude, char *locator));
|
||||
extern HAMLIB_EXPORT(int) longlat2locator HAMLIB_PARAMS((double longitude,
|
||||
double latitude, char *locator, int pair_count));
|
||||
extern HAMLIB_EXPORT(int) locator2longlat HAMLIB_PARAMS((double *longitude,
|
||||
double *latitude, const char *locator));
|
||||
|
||||
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,
|
||||
int *minutes, int *seconds));
|
||||
int *minutes, double *seconds));
|
||||
|
||||
|
||||
/*! \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 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,
|
||||
* by S. R. Sampson, N5OWK.
|
||||
|
@ -68,6 +68,38 @@
|
|||
/* arc length for 1 degree, 60 Nautical Miles */
|
||||
#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 */
|
||||
|
||||
/**
|
||||
|
@ -84,11 +116,11 @@
|
|||
*
|
||||
* \sa dec2dms()
|
||||
*/
|
||||
double dms2dec(int degrees, int minutes, int seconds) {
|
||||
double dms2dec(int degrees, int minutes, double seconds) {
|
||||
if (degrees >= 0)
|
||||
return (double)degrees + (double)minutes/60. + (double)seconds/3600.;
|
||||
return (double)degrees + (double)minutes/60. + seconds/3600.;
|
||||
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()
|
||||
*/
|
||||
void dec2dms(double dec, int *degrees, int *minutes, int *seconds) {
|
||||
int deg, min, sec, is_neg = 0;
|
||||
void dec2dms(double dec, int *degrees, int *minutes, double *seconds) {
|
||||
int deg, min, is_neg = 0;
|
||||
double st;
|
||||
|
||||
if (!degrees || !minutes || !seconds)
|
||||
|
@ -147,54 +179,14 @@ void dec2dms(double dec, int *degrees, int *minutes, int *seconds) {
|
|||
st = 60. * (st-(double)deg);
|
||||
min = (int)floor(st);
|
||||
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 */
|
||||
(is_neg == 1) ? (*degrees = deg * -1) : (*degrees = deg);
|
||||
|
||||
*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
|
||||
* \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.
|
||||
*
|
||||
* \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()
|
||||
*/
|
||||
|
@ -220,12 +212,16 @@ const static int loc_char_range[] = { 18, 10, 24, 10, 25, 10 };
|
|||
/* begin dph */
|
||||
|
||||
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;
|
||||
double xy[2], minutes;
|
||||
|
||||
paircount = strlen(locator) / 2;
|
||||
|
||||
if (paircount > MAX_LOCATOR_PAIRS) /* Max. locator length to allow */
|
||||
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) */
|
||||
minutes = 0.0;
|
||||
|
@ -241,7 +237,7 @@ int locator2longlat(double *longitude, double *latitude, const char *locator) {
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -259,34 +255,44 @@ int locator2longlat(double *longitude, double *latitude, const char *locator) {
|
|||
* \param longitude The longitude, decimal
|
||||
* \param latitude The latitude, decimal
|
||||
* \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.
|
||||
* \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()
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
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) {
|
||||
tmp = ((x_or_y == 0) ? longitude / 2. : latitude);
|
||||
|
||||
/* The 1e-6 here guards against floating point rounding errors */
|
||||
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]);
|
||||
|
||||
/* assert(locvalue < loc_char_range[pair]); */
|
||||
tmp -= loc_char_weight[pair] * locvalue;
|
||||
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 */
|
||||
|
|
|
@ -15,17 +15,18 @@
|
|||
int main (int argc, char *argv[]) {
|
||||
char recodedloc[13], *loc1, *loc2;
|
||||
double lon1 = 0, lat1, lon2, lat2;
|
||||
double distance, az;
|
||||
int deg, min, sec;
|
||||
int retcode;
|
||||
double distance, az, sec;
|
||||
int deg, min;
|
||||
int retcode, locator_length;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <locator1> [<locator2>]\n", argv[0]);
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <locator1> <precision> [<locator2>]\n", argv[0]);
|
||||
exit(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);
|
||||
retcode = locator2longlat(&lon1, &lat1, loc1);
|
||||
|
@ -35,21 +36,20 @@ int main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
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);
|
||||
printf(" Recoded lon: %f\n", lon1);
|
||||
|
||||
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);
|
||||
printf(" Recoded lat: %f\n", lat1);
|
||||
|
||||
longlat2locator(lon1, lat1, recodedloc);
|
||||
// recodedloc[6] = '\0';
|
||||
longlat2locator(lon1, lat1, recodedloc, locator_length);
|
||||
printf(" Recoded: %s\n", recodedloc);
|
||||
|
||||
if (loc2 == NULL)
|
||||
exit(0);
|
||||
exit(0);
|
||||
|
||||
printf("\nLocator2: %s\n", loc2);
|
||||
retcode = locator2longlat(&lon2, &lat2, loc2);
|
||||
|
@ -59,17 +59,16 @@ int main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
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);
|
||||
printf(" Recoded lon: %f\n", lon2);
|
||||
|
||||
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);
|
||||
printf(" Recoded lat: %f\n", lat2);
|
||||
|
||||
longlat2locator(lon2, lat2, recodedloc);
|
||||
// recodedloc[6] = '\0';
|
||||
longlat2locator(lon2, lat2, recodedloc, locator_length);
|
||||
printf(" Recoded: %s\n", recodedloc);
|
||||
|
||||
retcode = qrb(lon1, lat1, lon2, lat2, &distance, &az);
|
||||
|
@ -79,7 +78,7 @@ int main (int argc, char *argv[]) {
|
|||
}
|
||||
dec2dms(az, °, &min, &sec);
|
||||
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;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue