Geo::GeoNames::File - Perl module for handling GeoNames.org data files


Geo-GeoNames-Record documentation Contained in the Geo-GeoNames-Record distribution.

Index


Code Index:

NAME

Top

Geo::GeoNames::File - Perl module for handling GeoNames.org data files

SYNOPSIS

Top

use Geo::GeoNames::File;

my $file = Geo::GeoNames::File->open( qw/US.txt GB.txt/ );

while( my $rec = $file->next() ) { print $rec->name . "\n"; }

$file->close();

DESCRIPTION

Top

Provides a Perl extention for handling GeoNames.org data files. You may use this module to load GeoNames.org records from several seperate files.

AUTHOR

Top

Xiangrui Meng <mengxr@stanford.edu>

COPYRIGHT

Top


Geo-GeoNames-Record documentation Contained in the Geo-GeoNames-Record distribution.
package Geo::GeoNames::File;

use 5.008007;
use strict;
use warnings;

use Carp ();

require Geo::GeoNames::Record;

sub open
{
    my $class = shift;
    my @filenames = @_;

    my $self = {
	filenames    => \@filenames,
	cur_filename => undef,
	cur_fh       => undef,
    };

    bless $self, $class;

    return $self;
}

sub close
{
  my $self = shift;

  if( $self->{cur_fh} )
  {
    CORE::close $self->{cur_fh};
  }
}

sub next 
{
    my ( $self, $filter ) = @_;
    
    if ( $filter and ref($filter) ne 'CODE' )
    {
	Carp::croak( "filter function must be a subroutine reference." );
    }
    
    if( $self->{cur_fh} )	# if cur_fh is active
    {
      while(1)
      {
	if( eof($self->{cur_fh}) )
	{
	  CORE::close $self->{cur_fh};
	  $self->{cur_fh} = undef;
	  
	  return $self->next($filter);
	}
	else
	{
	  my $fh = $self->{cur_fh};
	  my $line = <$fh>;
	
	  next if $line =~ /^\s*#/;

	  my $rec = Geo::GeoNames::Record->new( $line );

	  next if( $filter and !($filter->($rec)) );

	  return $rec;
	}
      }
    }
    else			# open next file
    {
      $self->{cur_filename} = shift @{$self->{filenames}} 
	or return;
      
      CORE::open( $self->{cur_fh}, "<:utf8", $self->{cur_filename} ) 
	  or Carp::croak( "Couldn't open $self->{cur_filename}!" );
    
      return $self->next($filter);
    }
}

1;
__END__