kopia lustrzana https://git.sr.ht/~michalr/hamlocator
Conversion of Maidenhead to approx. location
rodzic
ee7b194b78
commit
2a5843af1f
|
@ -19,11 +19,11 @@
|
|||
namespace Hamlocator {
|
||||
public class Application : Adw.Application {
|
||||
private Location location;
|
||||
private LocationToMaidenhead l2m;
|
||||
private MaidenheadConverter mc;
|
||||
|
||||
public Application () {
|
||||
Object (application_id: "eu.fl9.hamlocator", flags: ApplicationFlags.FLAGS_NONE);
|
||||
l2m = new LocationToMaidenhead();
|
||||
mc = new MaidenheadConverter();
|
||||
}
|
||||
|
||||
construct {
|
||||
|
@ -58,7 +58,7 @@ namespace Hamlocator {
|
|||
win.SetLabel("unable to\nget location");
|
||||
win.SetDetails(@"Reason:\n$(pos.err)");
|
||||
} else {
|
||||
win.SetLabel(l2m.get_locator(pos.loc));
|
||||
win.SetLabel(mc.location_to_maidenhead(pos.loc));
|
||||
win.SetDetails(@"lat: $(pos.loc.latitude)°\nlon: $(pos.loc.longitude)°");
|
||||
}
|
||||
win.SetRefreshButtonEnabled(true);
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
// https://metacpan.org/release/MEH/Ham-Locator-0.1000/source/lib/Ham/Locator.pm
|
||||
|
||||
namespace Hamlocator {
|
||||
public class LocationToMaidenhead : Object {
|
||||
private string l2m;
|
||||
public class MaidenheadConverter : Object {
|
||||
private const char[] L2M = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
|
||||
private const double[] M2L_MULTIPLIERS = {10.0, 1.0, 1.0/24.0, 1.0/240.0, 1.0/5760.0};
|
||||
|
||||
public LocationToMaidenhead() {
|
||||
this.l2m = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
}
|
||||
public MaidenheadConverter() {}
|
||||
|
||||
public string get_locator(GClue.Location pos) {
|
||||
public string location_to_maidenhead(GClue.Location pos) {
|
||||
double lat = pos.latitude + 90;
|
||||
double lon = pos.longitude + 180;
|
||||
|
||||
|
@ -18,7 +17,7 @@ namespace Hamlocator {
|
|||
double lat1 = (lat / 10);
|
||||
double lon1 = (lon / 20);
|
||||
|
||||
string loc1 = @"$(this.l2m[Math.lround(Math.floor(lon1))])$(this.l2m[Math.lround(Math.floor(lat1))])";
|
||||
string loc1 = @"$(L2M[Math.lround(Math.floor(lon1))])$(L2M[Math.lround(Math.floor(lat1))])";
|
||||
|
||||
// Square
|
||||
double lat2 = 10 * (lat1 - Math.floor(lat1));
|
||||
|
@ -30,9 +29,40 @@ namespace Hamlocator {
|
|||
double lat3 = 24 * (lat2 - Math.floor(lat2));
|
||||
double lon3 = 24 * (lon2 - Math.floor(lon2));
|
||||
|
||||
string loc3 = @"$(this.l2m[Math.lround(Math.floor(lon3))])$(this.l2m[Math.lround(Math.floor(lat3))])".down();
|
||||
string loc3 = @"$(L2M[Math.lround(Math.floor(lon3))])$(L2M[Math.lround(Math.floor(lat3))])".down();
|
||||
|
||||
return @"$loc1$loc2$loc3";
|
||||
}
|
||||
|
||||
public GClue.Location? maidenhead_to_location(string locator) {
|
||||
double lat = 0.0;
|
||||
double lon = 0.0;
|
||||
|
||||
if (locator.length % 2 != 0) {
|
||||
warning("Locator needs to be of even length");
|
||||
return null;
|
||||
}
|
||||
long i = 0; // where we are in the locator
|
||||
long mult_i = 0; // which multiplier are we currently using
|
||||
var upLocator = locator.up();
|
||||
while (i < upLocator.length) {
|
||||
// letters
|
||||
lon += (upLocator[i++] - 'A') * 2.0 * M2L_MULTIPLIERS[mult_i];
|
||||
lat += (upLocator[i++] - 'A') * M2L_MULTIPLIERS[mult_i];
|
||||
mult_i++;
|
||||
if (i >= upLocator.length) { break; }
|
||||
// numbers
|
||||
lon += (upLocator[i++] - '0') * 2.0 * M2L_MULTIPLIERS[mult_i];
|
||||
lat += (upLocator[i++] - '0') * M2L_MULTIPLIERS[mult_i];
|
||||
mult_i++;
|
||||
}
|
||||
|
||||
// move to the center of the box
|
||||
mult_i--;
|
||||
lon += 0.5 * 2.0 * M2L_MULTIPLIERS[mult_i];
|
||||
lat += 0.5 * M2L_MULTIPLIERS[mult_i];
|
||||
|
||||
return new SimpleLocation((lat - 90.0), (lon - 180.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ hamlocator_sources = [
|
|||
'window.vala',
|
||||
'application.vala',
|
||||
'location.vala',
|
||||
'maidenhead.vala'
|
||||
'maidenhead.vala',
|
||||
'simple_location.vala'
|
||||
]
|
||||
|
||||
test_sources = [
|
||||
'tests' / 'main.vala',
|
||||
'tests' / 'testcase.vala',
|
||||
'tests' / 'maidenhead_tests.vala',
|
||||
'tests' / 'fake_geoclue_location.vala'
|
||||
]
|
||||
|
||||
hamlocator_deps = [
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
public class FakeGeoclueLocation : GLib.Object, GClue.Location {
|
||||
public class SimpleLocation : GLib.Object, GClue.Location {
|
||||
private double lat;
|
||||
private double lon;
|
||||
|
||||
public FakeGeoclueLocation(double lat, double lon) {
|
||||
|
||||
public SimpleLocation(double lat, double lon) {
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public override double accuracy {
|
||||
|
||||
public override double accuracy {
|
||||
get { return double.NAN; }
|
||||
set { assert(false); }
|
||||
}
|
||||
public override double altitude {
|
||||
public override double altitude {
|
||||
get { return double.NAN; }
|
||||
set { assert(false); }
|
||||
}
|
||||
public override string description { owned
|
||||
public override string description { owned
|
||||
get { return ""; }
|
||||
set { assert(false); }
|
||||
}
|
||||
public override double heading {
|
||||
public override double heading {
|
||||
get { return double.NAN; }
|
||||
set { assert(false); }
|
||||
}
|
||||
public override double latitude {
|
||||
public override double latitude {
|
||||
get { return this.lat; }
|
||||
set { assert(false); }
|
||||
}
|
||||
public override double longitude {
|
||||
public override double longitude {
|
||||
get { return this.lon; }
|
||||
set { assert(false); }
|
||||
}
|
||||
public override double speed {
|
||||
public override double speed {
|
||||
get { return double.NAN; }
|
||||
set { assert(false); }
|
||||
}
|
|
@ -1,45 +1,51 @@
|
|||
public class MaidenheadTests : TestCase {
|
||||
public MaidenheadTests() {
|
||||
base("Maidenhead Tests");
|
||||
add_test_location(0.0, 0.0, "JJ00aa");
|
||||
add_test_location(90.0, 0.0, "JS00aa");
|
||||
add_test_location(0.0, 180.0, "SJ00aa");
|
||||
add_test_location(90.0, 180.0, "SS00aa");
|
||||
add_test_location(-90.0, 0.0, "JA00aa");
|
||||
add_test_location(0.0, -180.0, "AJ00aa");
|
||||
add_test_location(-90.0, -180.0, "AA00aa");
|
||||
add_test_location(90.0, -180.0, "AS00aa");
|
||||
add_test_location(-90.0, 180.0, "SA00aa");
|
||||
add_test_maidenhead(0.0, 0.0, "JJ00aa");
|
||||
add_test_maidenhead(90.0, 0.0, "JS00aa");
|
||||
add_test_maidenhead(0.0, 180.0, "SJ00aa");
|
||||
add_test_maidenhead(90.0, 180.0, "SS00aa");
|
||||
add_test_maidenhead(-90.0, 0.0, "JA00aa");
|
||||
add_test_maidenhead(0.0, -180.0, "AJ00aa");
|
||||
add_test_maidenhead(-90.0, -180.0, "AA00aa");
|
||||
add_test_maidenhead(90.0, -180.0, "AS00aa");
|
||||
add_test_maidenhead(-90.0, 180.0, "SA00aa");
|
||||
|
||||
add_test_location(51.0, 17.0, "JO80lx");
|
||||
add_test_location(51.1, 17.1, "JO81nc");
|
||||
add_test_location(51.2, 17.2, "JO81oe");
|
||||
add_test_location(51.3, 17.3, "JO81ph");
|
||||
add_test_location(51.4, 17.4, "JO81qj");
|
||||
add_test_location(51.5, 17.5, "JO81sm");
|
||||
add_test_location(51.6, 17.6, "JO81to");
|
||||
add_test_location(51.7, 17.7, "JO81uq");
|
||||
add_test_location(51.8, 17.8, "JO81vt");
|
||||
add_test_location(51.9, 17.9, "JO81wv");
|
||||
add_test_location(51.99, 17.99, "JO81xx");
|
||||
add_test_maidenhead(51.0, 17.0, "JO80lx");
|
||||
add_test_maidenhead(51.1, 17.1, "JO81nc");
|
||||
add_test_maidenhead(51.2, 17.2, "JO81oe");
|
||||
add_test_maidenhead(51.3, 17.3, "JO81ph");
|
||||
add_test_maidenhead(51.4, 17.4, "JO81qj");
|
||||
add_test_maidenhead(51.5, 17.5, "JO81sm");
|
||||
add_test_maidenhead(51.6, 17.6, "JO81to");
|
||||
add_test_maidenhead(51.7, 17.7, "JO81uq");
|
||||
add_test_maidenhead(51.8, 17.8, "JO81vt");
|
||||
add_test_maidenhead(51.9, 17.9, "JO81wv");
|
||||
add_test_maidenhead(51.99, 17.99, "JO81xx");
|
||||
|
||||
add_test_location(51.1205, 17.0261, "JO81mc");
|
||||
add_test_location(37.1104, -5.4932, "IM77gc");
|
||||
add_test_location(-30.5377, 22.8516, "KF19kl");
|
||||
add_test_location(-27.4613, -65.0391, "FG72lm");
|
||||
add_test_location(-24.6168, 136.4063, "PG85ej");
|
||||
add_test_maidenhead(51.1205, 17.0261, "JO81mc");
|
||||
add_test_maidenhead(37.1104, -5.4932, "IM77gc");
|
||||
add_test_maidenhead(-30.5377, 22.8516, "KF19kl");
|
||||
add_test_maidenhead(-27.4613, -65.0391, "FG72lm");
|
||||
add_test_maidenhead(-24.6168, 136.4063, "PG85ej");
|
||||
}
|
||||
|
||||
protected Hamlocator.LocationToMaidenhead tested;
|
||||
protected Hamlocator.MaidenheadConverter tested;
|
||||
|
||||
public override void set_up() {
|
||||
this.tested = new Hamlocator.LocationToMaidenhead();
|
||||
this.tested = new Hamlocator.MaidenheadConverter();
|
||||
}
|
||||
|
||||
public void add_test_location(double lat, double lon, string expected) {
|
||||
add_test (@"Expect location lat:$lat lon:$lon to be $expected", () => {
|
||||
GClue.Location pos = new FakeGeoclueLocation(lat, lon);
|
||||
assert_cmpstr(this.tested.get_locator(pos), EQ, expected);
|
||||
public void add_test_maidenhead(double lat, double lon, string locator) {
|
||||
add_test (@"Expect location lat:$lat lon:$lon to be $locator", () => {
|
||||
GClue.Location pos = new SimpleLocation(lat, lon);
|
||||
assert_cmpstr(this.tested.location_to_maidenhead(pos), EQ, locator);
|
||||
});
|
||||
add_test (@"Expect location at $locator to be approx. lat:$lat lon:$lon", () => {
|
||||
GClue.Location pos = this.tested.maidenhead_to_location(locator);
|
||||
assert_nonnull(pos);
|
||||
assert_cmpfloat_with_epsilon(pos.latitude, lat, (1.0/24.0));
|
||||
assert_cmpfloat_with_epsilon(pos.longitude, lon, (2.0/24.0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue