Author: nick
Date: 2006-09-17 17:26:28 +0100 (Sun, 17 Sep 2006)
New Revision: 870
Modified:
trunk/lib/OpenGuides/Utils.pm
trunk/t/28_wgs84_coords.t
Log:
Support doing Helmert Transforms as required, using the MySociety Helmert transform
library, if installed. References #89
Modified: trunk/lib/OpenGuides/Utils.pm
===================================================================
--- trunk/lib/OpenGuides/Utils.pm 2006-09-17 15:36:44 UTC (rev 869)
+++ trunk/lib/OpenGuides/Utils.pm 2006-09-17 16:26:28 UTC (rev 870)
@@ -235,21 +235,61 @@
$args{config})
or croak "No longitude supplied to get_wgs84_coords";
croak "geo_handler not defined!" unless $config->geo_handler;
+
if ($config->force_wgs84) {
# Only as a rough approximation, good enough for large scale guides
return ($longitude, $latitude);
- } elsif ($config->geo_handler == 1) {
+ }
+
+ # If we don't have a lat and long, return undef right away
+ unless($args{longitude} || $args{latitude}) {
+ return undef;
+ }
+
+ # Try to load a provider of Helmert Transforms
+ my $helmert;
+ # First up, try the MySociety Geo::HelmertTransform
+ unless($helmert) {
+ eval {
+ require Geo::HelmertTransform;
+ $helmert = sub($$$) {
+ my ($datum,$oldlat,$oldlong) = @_;
+ my $datum_helper = Geo::HelmertTransform::datum($datum);
+ my $wgs84_helper = Geo::HelmertTransform::datum('WGS84');
+ unless($datum_helper) {
+ croak("No convertion helper for datum '$datum'");
+ return undef;
+ }
+
+ my ($lat,$long,$h) =
+
Geo::HelmertTransform::convert_datum($datum_helper,$wgs84_helper,$oldlat,$oldlong,0);
+ return ($long,$lat);
+ };
+ };
+ }
+ # Next, try .....
+ unless($helmert) {
+ eval {
+ };
+ }
+ # Give up, return undef
+ unless($helmert) {
+ return undef;
+ }
+
+
+ if ($config->geo_handler == 1) {
# Do conversion here
- return undef;
+ return &$helmert('Airy1830',$latitude,$longitude);
} elsif ($config->geo_handler == 2) {
# Do conversion here
- return undef;
+ return &$helmert('Airy1830Modified',$latitude,$longitude);
} elsif ($config->geo_handler == 3) {
if ($config->ellipsoid eq "WGS-84") {
return ($longitude, $latitude);
} else {
# Do conversion here
- return undef;
+ return &$helmert($config->ellipsoid,$latitude,$longitude);
}
} else {
croak "Invalid geo_handler config option $config->geo_handler";
Modified: trunk/t/28_wgs84_coords.t
===================================================================
--- trunk/t/28_wgs84_coords.t 2006-09-17 15:36:44 UTC (rev 869)
+++ trunk/t/28_wgs84_coords.t 2006-09-17 16:26:28 UTC (rev 870)
@@ -4,7 +4,7 @@
use OpenGuides::Test;
use Test::More;
-plan tests => 2;
+plan tests => 4;
# Clear out the database from any previous runs.
unlink "t/node.db";
@@ -17,7 +17,7 @@
my $guide = OpenGuides->new( config => $config );
-my ($longitude, $latitude) = (0, 0);
+my ($longitude, $latitude) = (10, 12);
my ($wgs_long, $wgs_lat) = OpenGuides::Utils->get_wgs84_coords(
longitude => $longitude,
@@ -28,3 +28,36 @@
"get_wgs84_coords returns the original longitude when force_wgs84 is on");
is( $wgs_lat, $latitude,
"get_wgs84_coords returns the original latitude when force_wgs84 is on");
+
+
+# Now claim to be in the UK
+eval{ require Geo::HelmertTransform; };
+my $have_helmert = $@ ? 0 : 1;
+SKIP : {
+ skip "Geo::HelmertTransform not installed - can't do transforms", 2
+ unless $have_helmert;
+
+ $config->force_wgs84(0);
+ $config->geo_handler(1);
+
+ # Set our location to be somewhere known
+ ($longitude,$latitude) = (-1.258200,51.754349);
+ my ($wgs84_lon,$wgs84_lat) = (-1.259687,51.754813);
+
+ ($wgs_long, $wgs_lat) = OpenGuides::Utils->get_wgs84_coords(
+ longitude => $longitude,
+ latitude => $latitude,
+ config => $config);
+
+ # Round to 5 dp
+ my $fivedp = 1 * 1000 * 100;
+ $wgs_long = int($wgs_long * $fivedp)/$fivedp;
+ $wgs_lat = int($wgs_lat * $fivedp)/$fivedp;
+ $wgs84_lon = int($wgs84_lon * $fivedp)/$fivedp;
+ $wgs84_lat = int($wgs84_lat * $fivedp)/$fivedp;
+
+ is( $wgs_long, $wgs84_lon,
+ "get_wgs84_coords does Airy1830 -> WGS84 convertion properly");
+ is( $wgs_lat, $wgs84_lat,
+ "get_wgs84_coords does Airy1830 -> WGS84 convertion properly");
+}