Subject: | Geo::Calc::XS defaults to 'k-m' instead of 'm' |
If units are not specified in Geo::Calc::XS's constructor, it defaults to 'k-m'.
This is despite the fact that the documentation of Geo::Calc::XS and Geo::Calc says that the default is 'm', and that the implementation of Geo::Calc makes the default 'm'.
I've included a patch which makes the default 'm', and which adds getters for lat, lon, units and radius.
Subject: | 0001-Add-getters-and-fix-default-units.patch |
diff --git a/Makefile.PL b/Makefile.PL
index 5f9527c..1f7c11d 100755
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -17,6 +17,8 @@ WriteMakefile(
'File::Spec' => 0,
'Test::More' => 0,
'Test::Deep' => 0,
+ 'Test::Warn' => 0,
+ 'Test::NoWarnings' => 0,
},
LIBS => [''], # e.g., '-lm'
DEFINE => '', # e.g., '-DBYPASS'
diff --git a/XS.xs b/XS.xs
index d92e546..2709fdc 100644
--- a/XS.xs
+++ b/XS.xs
@@ -51,7 +51,7 @@ geocalc_init( GCX *gcx, HV * options )
SV ** sv = hv_fetch(options, "units", 5, 0);
if( sv == (SV**)NULL ) {
- gcx->unit_conv = 1; // Default to KM
+ gcx->unit_conv = 0; // Default to m
} else {
if( strEQ( SvPV_nolen( *sv ), "m" ) ) {
gcx->unit_conv = 0;
@@ -63,8 +63,11 @@ geocalc_init( GCX *gcx, HV * options )
gcx->unit_conv = 3;
} else if( strEQ( SvPV_nolen( *sv ), "mi" ) ) {
gcx->unit_conv = 4;
+ } else if( strEQ( SvPV_nolen( *sv ), "" ) ) {
+ gcx->unit_conv = 0;
} else {
- gcx->unit_conv = 1;
+ warn("Unrecognised unit (defaulting to m)");
+ gcx->unit_conv = 0;
}
}
/*
@@ -260,6 +263,48 @@ void new ( char *klass, ... )
) ) );
}
+void get_lat ( GCX *self, ... )
+ PPCODE:
+ {
+ XPUSHs( sv_2mortal( newSVnv( self->latitude ) ) );
+ }
+
+void get_lon ( GCX *self, ... )
+ PPCODE:
+ {
+ XPUSHs( sv_2mortal( newSVnv( self->longitude ) ) );
+ }
+
+void get_units ( GCX *self, ... )
+ PPCODE:
+ {
+ /* Distance Units */
+ /* 0 -> m, 1 -> km, 2 -> yards, 3 -> feet, 4 -> mile */
+ switch ( self->unit_conv)
+ {
+ case 0:
+ XPUSHs( sv_2mortal( newSVpv( "m", 0 ) ) );
+ break;
+ case 1:
+ XPUSHs( sv_2mortal( newSVpv( "k-m", 0 ) ) );
+ break;
+ case 2:
+ XPUSHs( sv_2mortal( newSVpv( "yd", 0 ) ) );
+ break;
+ case 3:
+ XPUSHs( sv_2mortal( newSVpv( "ft", 0 ) ) );
+ break;
+ default:
+ XPUSHs( sv_2mortal( newSVpv( "mi", 0 ) ) );
+ }
+ }
+
+void get_radius ( GCX *self, ... )
+ PPCODE:
+ {
+ XPUSHs( sv_2mortal( newSVnv( self->radius ) ) );
+ }
+
void distance_to( GCX *self, INGC *to_latlon, ... )
PPCODE:
{
diff --git a/t/03_properties.t b/t/03_properties.t
new file mode 100644
index 0000000..c8d4964
--- /dev/null
+++ b/t/03_properties.t
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Warn;
+
+require Test::NoWarnings;
+
+use_ok 'Geo::Calc::XS';
+
+my @units = ("m", "k-m", "mi", "yd", "ft", "");
+
+for my $unit (@units) {
+
+ my $gc = Geo::Calc::XS->new(
+ lat => '1.5423',
+ lon => '-2.234',
+ units => $unit,
+ );
+
+ my $actual_unit = $unit || "m";
+
+ is($gc->get_lat, '1.5423', "get_lat (units \"$unit\")");
+ is($gc->get_lon, '-2.234', "get_lon (units \"$unit\")");
+ is($gc->get_radius, 6371, "get_radius (units \"$unit\")");
+ is($gc->get_units, $actual_unit, "get_units (units \"$unit\")");
+}
+
+
+{
+ my $gc = Geo::Calc::XS->new( lat => 1, lon => 2 );
+ is($gc->get_lat, 1, "get_lat (units not specified)");
+ is($gc->get_lon, 2, "get_lat (units not specified)");
+ is($gc->get_radius, 6371, "get_radius (units not specified)");
+ is($gc->get_units, 'm', "get_units (units not specified)");
+}
+
+my $gc;
+
+warning_is
+ {
+ $gc = Geo::Calc::XS->new(
+ lat => 1,
+ lon => 2,
+ units => 'unknown'
+ );
+ }
+ "Unrecognised unit (defaulting to m)",
+ "Caught warning when specifying bad distance unit";
+
+is($gc->get_units, "m", "default to meters");
+
+Test::NoWarnings::had_no_warnings();
+done_testing();