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"); +}