#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 34000;
our $debug = 0; # 1;
use Geo::Coordinates::UTM::XS ();
# use Geo::Coordinates::UTM ();
if ($debug) {
open LOG, ">/tmp/log";
select LOG; $| = 1;
select STDOUT;
}
sub isub (*) {
my $name = shift;
no strict 'refs';
my $sub = eval "\\\&Geo::Coordinates::UTM::XS::$name";
# my $sub = eval "\\\&Geo::Coordinates::UTM::$name";
if ($debug) {
*{$name} = sub {
my @ret = $sub->(@_);
printf LOG "%s(%s) ==> %s\n",
$name, join(', ', @_), join(', ', @ret);
@ret;
}
}
else {
*{$name} = $sub;
}
}
isub latlon_to_utm;
isub latlon_to_utm_force_zone;
isub utm_to_latlon;
use constant maxerror => 7.5e-4;
use warnings;
use strict;
sub fleq ($$;$) {
if (abs($_[0] - $_[1]) < maxerror) {
pass($_[2]);
}
else {
fail($_[2]);
print LOG "ERROR: $_[0] != $_[1] ($_[2])\n" if $debug;
diag("floating point value $_[0] too different to reference $_[1]");
}
}
open TD, '<', 't/test.dat'
or die "unable to open test data file 't/test.dat'";
my $latlon = "CDEFGHJKLMNPQRSTUVWX";
while(<TD>) {
chomp;
next if /^\s*(?:#.*)?$/;
print LOG "DATA: $_\n" if $debug;
my ($ellipsoid, $latitude, $longitude, $zone, $easting, $northing) = split /\|/;
my ($z, $e, $n) = latlon_to_utm($ellipsoid, $latitude, $longitude);
is($z, $zone, "zone $.");
fleq($e, $easting, "easting $.");
fleq($n, $northing, "northing $.");
my ($lat, $lon) = utm_to_latlon($ellipsoid, $z, $easting, $northing);
fleq($lon, $longitude, "longitude $.");
fleq($lat, $latitude, "latitude $.");
my ($zone_number, $zone_letter) = $zone =~ /^(\d+)(\w)/;
($z, $e, $n) = latlon_to_utm_force_zone($ellipsoid, $zone_number, $latitude, $longitude);
is($z, $zone, "fz zone $.");
fleq($e, $easting, "fz easting $.");
fleq($n, $northing, "fz northing $.");
($lat, $lon) = utm_to_latlon($ellipsoid, $z, $e, $n);
fleq($lat, $latitude, "reverse latitude $.");
fleq($lon, $longitude, "reverse longitude $.");
for my $z1 ($zone_number - 1 .. $zone_number + 1) {
my $z1 = $zone_number + int(-2 + rand 5);
$z1 -= 60 if $z1 > 60;
$z1 += 60 if $z1 < 1;
# $z1 = 60 if $z1 > 60;
# $z1 = 1 if $z1 < 1;
for my $l1 (($latlon =~ /(.?)($zone_letter)(.?)/), '') {
($z, $e, $n) = latlon_to_utm_force_zone($ellipsoid, "$z1$l1", $latitude, $longitude);
($lat, $lon) = utm_to_latlon($ellipsoid, $z, $e, $n);
fleq($lon, $longitude, "fz longitude (zone $zone) $.");
fleq($lat, $latitude, "fz latitude (zone $zone) $.");
}
}
}