Astro-satpass
view release on metacpan or search on metacpan
script/satpass view on Meta::CPAN
# the end of the address, but conflicts between U.S. Postal state
# codes and ISO 3166 country codes abound, running from
# AL = Alabama (U.S.) or Albania (ISO) through
# VA = Virginia (U.S.) or Vatican City (ISO).
# In addition to the global options, the geocode verb takes -all
# (for the benefit of height() if called) and -height (to negate
# the autoheight setting)
BEGIN {
$cmdlgl{geocode} = [qw{all height retry_on_zero=i source_layer=s}];
$cmdlgl{geocode_as} = $cmdlgl{geocode};
$cmdlgl{geocode_ca} = $cmdlgl{geocode};
$cmdlgl{geocode_fm} = $cmdlgl{geocode};
$cmdlgl{geocode_gu} = $cmdlgl{geocode};
$cmdlgl{geocode_mh} = $cmdlgl{geocode};
$cmdlgl{geocode_mp} = $cmdlgl{geocode};
$cmdlgl{geocode_pr} = $cmdlgl{geocode};
$cmdlgl{geocode_pw} = $cmdlgl{geocode};
$cmdlgl{geocode_us} = $cmdlgl{geocode};
$cmdlgl{geocode_vi} = $cmdlgl{geocode};
}
# Here is the subroutine proper.
sub geocode {
my $cc = lc ($_[1] || $parm{country});
my $handler = "geocode_$cc";
die <<eod unless __PACKAGE__->can ($handler);
Error - I have no idea how to geocode a location in country code
'$cc'. The only known country codes at the moment are
@{[join ', ', _find_suffixes ('geocode_')]}
eod
goto \&{$handler};
}
########################################################################
#
# geocode_ca () get lat/long from geocoder.ca
#
sub geocode_ca {
_load_module ('LWP::UserAgent', 'geocode_ca');
_load_module ('XML::Parser', 'geocode_ca');
warn <<eod;
Warning - Geocoding Canadian addresses is now unsupported, and probably
will not work anyway, because geocoder.ca has started requiring
registration to use its free port. My apologies for the
inconvenience.
eod
my $set_loc = @_;
my $loc = shift @_ || $parm{location};
# Manufacture an LWP::UserAgent object.
my $ua = LWP::UserAgent->new ();
foreach my $url (qw{http://geocoder.ca/ http://backup-geocoder.ca/}) {
my $rslt = $ua->post ($url,
{locate => $loc, geoit => 'XML'});
next unless $rslt->is_success ();
$cmdopt{debug} and warn "Debug - Parsing ", $rslt->content;
my @xml = _parse_xml ($rslt->content, 'geocode_ca');
@xml = @{_find_first_tag (\@xml, 'geodata')};
my @rslt;
my $point = {};
foreach (@xml) {
next unless ARRAY_REF eq ref $_;
next unless $_->[0] eq 'latt' || $_->[0] eq 'longt';
$point->{$_->[0]} = $_->[2];
if (exists $point->{latt} && exists $point->{longt}) {
push @rslt, [$point->{latt}, $point->{longt}];
$point = {};
}
}
if (@rslt == 1) {
$parm{location} = $loc if $set_loc;
@parm{qw{latitude longitude}} = @{$rslt[0]};
print "\n";
show (($set_loc ? 'location' : ()), qw{latitude longitude});
_geocode_height ();
last;
}
elsif (@rslt) {
die <<eod;
Error - Too many results.
eod
}
else {
die <<eod;
Error - No results.
eod
}
}
}
########################################################################
#
# geocode_us () get lat/long from Open Street Maps
#
# The options are those documented with geocode().
sub geocode_us {
my ( $loc ) = @_;
my $set_loc;
if ( defined $loc ) {
$set_loc = 1;
} else {
$loc = $parm{location};
}
my $class = _load_module( [ 'Geo::Coder::OSM' ], 'geocode_us' );
my $gc = $class->new();
if ( my @rslt = sort { $b->{importance} <=> $a->{importance} }
$gc->geocode( location => $loc ) ) {
splice @rslt, 1; # I give up.
( run in 0.662 second using v1.01-cache-2.11-cpan-39bf76dae61 )