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-79ac388436b8
Hamlib-1.2.0
Nate Bargmann, N0NB 2003-08-21 20:22:06 +00:00
rodzic 9efbb5e911
commit da8d2e4b41
3 zmienionych plików z 82 dodań i 77 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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 */

Wyświetl plik

@ -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, &deg, &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, &deg, &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, &deg, &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, &deg, &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, &deg, &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;
}