summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-05-06 16:03:58 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-05-06 16:03:58 -0400
commit1956ff35d239d9bb33fefe31ee374934952e5076 (patch)
tree61f487a1e4d7f886e69e01ace5503a282a687c97
parentb6462462697e60c8d921988c4760cd66a3b43579 (diff)
downloadgpsd-1956ff35d239d9bb33fefe31ee374934952e5076.tar.gz
Fixes for the Maidehead locator code, and a better regression test.
-rw-r--r--.gitignore1
-rw-r--r--SConstruct14
-rw-r--r--gpsdclient.c31
-rw-r--r--test/maidenhead_locator.test.chk1
-rwxr-xr-xtest_maidenhead.py30
-rw-r--r--test_maidenhead_locator.c39
6 files changed, 58 insertions, 58 deletions
diff --git a/.gitignore b/.gitignore
index b3304335..96f1aa15 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,7 +28,6 @@ test_geoid
test_json
test_trig
test_libgps
-test_maidenhead_locator
# Other generated files
gps.html
gpscat.html
diff --git a/SConstruct b/SConstruct
index 99a5a421..4f573f71 100644
--- a/SConstruct
+++ b/SConstruct
@@ -726,7 +726,6 @@ if ncurseslibs:
# Test programs
test_float = env.Program('test_float', ['test_float.c'])
test_geoid = env.Program('test_geoid', ['test_geoid.c'], parse_flags=gpslibs)
-test_maidenhead_locator = env.Program('test_maidenhead_locator', ['test_maidenhead_locator.c'], parse_flags=gpslibs)
test_json = env.Program('test_json', ['test_json.c'], parse_flags=gpslibs)
test_mkgmtime = env.Program('test_mkgmtime', ['test_mkgmtime.c'], parse_flags=gpslibs)
test_trig = env.Program('test_trig', ['test_trig.c'], parse_flags=["-lm"])
@@ -735,7 +734,7 @@ test_bits = env.Program('test_bits', ['test_bits.c', "bits.c"])
test_gpsmm = env.Program('test_gpsmm', ['test_gpsmm.cpp'], parse_flags=gpslibs)
test_libgps = env.Program('test_libgps', ['test_libgps.c'], parse_flags=gpslibs)
testprogs = [test_float, test_trig, test_bits, test_packet,
- test_mkgmtime, test_geoid, test_maidenhead_locator, test_json, test_libgps]
+ test_mkgmtime, test_geoid, test_json, test_libgps]
if cxx and env["libgpsmm"]:
testprogs.append(test_gpsmm)
@@ -1009,7 +1008,6 @@ splint_table = [
('splint-test_packet',['test_packet.c'],'test_packet test harness', ['']),
('splint-test_mkgmtime',['test_mkgmtime.c'],'test_mkgmtime test harness', ['']),
('splint-test_geoid',['test_geoid.c'],'test_geoid test harness', ['']),
- ('splint-test_maidenhead_locator',['test_maidenhead_locator.c'],'test_maidenhead_locator test harness', ['']),
('splint-test_json',['test_json.c'],'test_json test harness', ['']),
]
@@ -1128,14 +1126,10 @@ geoid_regress = Utility('geoid-regress', [test_geoid], [
'$SRCDIR/test_geoid 37.371192 122.014965 | diff -u $SRCDIR/test/geoid.test.chk -',
])
-# Rebuild the Maidenhead Locator test
-Utility('maidenhead-locator-makeregress', [test_maidenhead_locator], [
- '$SRCDIR/test_maidenhead_locator 37.371192 122.014965 >$SRCDIR/test/maidenhead_locator.test.chk'])
-
# Regression-test the Maidenhead Locator
-maidenhead_locator_regress = Utility('maidenhead-locator-regress', [test_maidenhead_locator], [
- '@echo "Testing the Maidenhead Locator..."',
- '$SRCDIR/test_maidenhead_locator 37.371192 122.014965 | diff -u $SRCDIR/test/maidenhead_locator.test.chk -',
+maidenhead_locator_regress = Utility('maidenhead-locator-regress', [], [
+ '@echo "Testing the Maidenhead Locator conversion..."',
+ '$SRCDIR/test_maidenhead.py',
])
# Regression-test the calendar functions
diff --git a/gpsdclient.c b/gpsdclient.c
index 5b49c0f7..d202bf3e 100644
--- a/gpsdclient.c
+++ b/gpsdclient.c
@@ -176,28 +176,45 @@ void gpsd_source_spec(const char *arg, struct fixsource_t *source)
/*@ +observertrans -statictrans +mustfreeonly +branchstate +kepttrans @*/
char *maidenhead(double n, double e)
-/* lat/lon to Maidenhead (from QGrid - http://users.pandora.be/on4qz/qgrid/) */
+/* lat/lon to Maidenhead */
{
+ /*
+ * Specification at
+ * http://en.wikipedia.org/wiki/Maidenhead_Locator_System
+ *
+ * There's a fair amount of slop in how Maidenhead converters operate
+ * that can make it look like this one is wrong.
+ *
+ * 1. Many return caps for paces 5 and 6 when according to the spwec
+ * they should return smalls.
+ *
+ * 2. Some converters, including QGrid from which this code was originally
+ * derived, add an 0.5 offset to the divided e and n just before it
+ * is cast to integer and used for places 5 and 6. This appears to be
+ * intended as a round-to-nearest hack (as opposed to the implicit
+ * round down from the cast). If I'm reading the spec right it
+ * is not correct to do this.
+ */
static char buf[7];
int t1;
e=e+180.0;
t1=(int)(e/20);
- buf[0]=(char)t1+'@';
+ buf[0]=(char)t1+'A';
e-=(float)t1*20.0;
t1=(int)e/2;
- buf[2]=(char)t1+'/';
+ buf[2]=(char)t1+'0';
e-=(float)t1*2;
- buf[4]=(char)(int)(e*12.0+0.5)+'`';
+ buf[4]=(char)(int)(e*12.0)+'a';
n=n+90.0;
t1=(int)(n/10.0);
- buf[1]=(char)t1+'@';
+ buf[1]=(char)t1+'A';
n-=(float)t1*10.0;
- buf[3]=(char)n+'/';
+ buf[3]=(char)n+'0';
n-=(int)n;
n*=24; // convert to 24 division
- buf[5]=(char)(int)(n+0.5)+'`';
+ buf[5]=(char)(int)(n)+'a';
buf[6] = '\0';
return buf;
diff --git a/test/maidenhead_locator.test.chk b/test/maidenhead_locator.test.chk
deleted file mode 100644
index bea4d550..00000000
--- a/test/maidenhead_locator.test.chk
+++ /dev/null
@@ -1 +0,0 @@
- lat= 37.371192 lon= 122.014965 locator= OL06`i
diff --git a/test_maidenhead.py b/test_maidenhead.py
new file mode 100755
index 00000000..39010b62
--- /dev/null
+++ b/test_maidenhead.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+#
+# Test grid locator conversion.
+#
+# Midenhead specification at
+# http://en.wikipedia.org/wiki/Maidenhead_Locator_System
+# Test conversions generated using
+# http://f6fvy.free.fr/qthLocator/
+
+import sys, gps.clienthelpers
+
+errors = 0
+for (lat, lon, maidenhead, location) in [
+ (48.86471, 2.37305, "JN18eu", "Paris"),
+ (41.93498, 12.43652, "JN61fw", "Rome"),
+ (39.9771, -75.1685, "FM29jx", "Philadelphia"),
+ (-23.4028, -50.9766, "GG46mo", "Sao Paulo"),
+ ]:
+ converted = gps.clienthelpers.maidenhead(lat, lon)
+ if converted != maidenhead:
+ print >>sys.stderr, "maidenhead test: from %s %s (%s) expected %s got %s" \
+ % (lat, lon, location, maidenhead, converted)
+ else:
+ print "%s OK" % location
+
+if errors:
+ sys.exit(1)
+else:
+ sys.exit(0)
+
diff --git a/test_maidenhead_locator.c b/test_maidenhead_locator.c
deleted file mode 100644
index ea60fa00..00000000
--- a/test_maidenhead_locator.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* test driver for the ECEF to Maidenhead Locator
- *
- * This file is Copyright (c) 2011 by the GPSD project
- * BSD terms apply: see the file COPYING in the distribution root for details.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "gpsdclient.h"
-
-int main(int argc, char **argv)
-{
- double lat, lon;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s lat lon\n", argv[0]);
- return 1;
- }
-
- lat = atof(argv[1]);
- lon = atof(argv[2]);
-
- if (lat > 90. || lat < -90.) {
- fprintf(stderr, " -90 <= lat=%s(%.f) <= 90 ?\n", argv[1], lat);
- return 1;
- }
-
- if (lon > 180. || lat < -180.) {
- fprintf(stderr, " -180 <= lon=%s(%.f) <= 180 ?\n", argv[2], lon);
- return 1;
- }
-
- printf(" lat= %f lon= %f locator= %s\n",
- lat, lon, maidenhead(lat, lon));
-
- return 0;
-}