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 )