pax_global_header00006660000000000000000000000064141645474560014532gustar00rootroot0000000000000052 comment=88c5a143b5e4cd055ad2cd275777de000cd715c6 libgeo-hash-perl-0.02/000077500000000000000000000000001416454745600145755ustar00rootroot00000000000000libgeo-hash-perl-0.02/Build.PL000066400000000000000000000006101416454745600160660ustar00rootroot00000000000000use strict; use warnings; use Module::Build; my $builder = Module::Build->new( module_name => 'Geo::Hash', license => 'perl', dist_author => 'Andy Armstrong ', dist_version_from => 'lib/Geo/Hash.pm', requires => { 'Test::More' => 0, }, add_to_cleanup => ['Geo-Hash-*'], ); $builder->create_build_script(); libgeo-hash-perl-0.02/Changes000066400000000000000000000002271416454745600160710ustar00rootroot00000000000000Revision history for Geo-Hash 0.01 2008-02-29 - Initial release. 0.02 2008-02-29 - Added precision guessing - Added decode_to_interval libgeo-hash-perl-0.02/MANIFEST000066400000000000000000000004201416454745600157220ustar00rootroot00000000000000Build.PL Changes lib/Geo/Hash.pm Makefile.PL MANIFEST README t/00.load.t t/geohash.t t/pod-coverage.t t/pod.t META.yml Module meta-data (added by MakeMaker) SIGNATURE Public-key signature (added by MakeMaker) libgeo-hash-perl-0.02/META.yml000066400000000000000000000007001416454745600160430ustar00rootroot00000000000000--- #YAML:1.0 name: Geo-Hash version: 0.02 abstract: Encode / decode geohash.org locations. license: perl author: - Andy Armstrong generated_by: ExtUtils::MakeMaker version 6.42 distribution_type: module requires: Test::More: 0 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 libgeo-hash-perl-0.02/Makefile.PL000066400000000000000000000010551416454745600165500ustar00rootroot00000000000000use 5.006001; use strict; use ExtUtils::MakeMaker; eval 'use ExtUtils::MakeMaker::Coverage'; WriteMakefile( ( MM->can( 'signature_target' ) ? ( SIGN => 1 ) : () ), NAME => 'Geo::Hash', AUTHOR => 'Andy Armstrong ', LICENSE => 'perl', VERSION_FROM => 'lib/Geo/Hash.pm', ABSTRACT_FROM => 'lib/Geo/Hash.pm', PL_FILES => {}, PREREQ_PM => { 'Test::More' => 0, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Geo-Hash-*' }, ); libgeo-hash-perl-0.02/README000066400000000000000000000007241416454745600154600ustar00rootroot00000000000000Geo-Hash version 0.02 INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install Alternatively, to install with Module::Build, you can use the following commands: perl Build.PL ./Build ./Build test ./Build install DEPENDENCIES None. COPYRIGHT AND LICENCE Copyright (C) 2008, Andy Armstrong This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libgeo-hash-perl-0.02/SIGNATURE000066400000000000000000000025011416454745600160570ustar00rootroot00000000000000This file contains message digests of all files listed in MANIFEST, signed via the Module::Signature module, version 0.55. To verify the content in this distribution, first make sure you have Module::Signature installed, then type: % cpansign -v It will check each file's integrity, as well as the signature's validity. If "==> Signature verified OK! <==" is not displayed, the distribution may already have been compromised, and you should not run its Makefile.PL or Build.PL. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 SHA1 8a73c4a3b821945955829f47572b617dc300a10a Build.PL SHA1 73f1deacb03909ffc445500ec272d42b61223b1b Changes SHA1 a706919b333f9dddd8cb64f9a43e47f246bbfbb2 MANIFEST SHA1 2a1775b462f14d574b0879110043985471ee5b13 META.yml SHA1 3d5879314ba4b1c428e13c7b15c587cf91573a75 Makefile.PL SHA1 349a83977ad57630d369e619c8a2e03ee8f26fce README SHA1 76295a710aadc19426b3b41669e06493536cedfa lib/Geo/Hash.pm SHA1 be6e0364221a868999eba6eedc790d3800eb598a t/00.load.t SHA1 6c829ecd735146d7743f0a38482ea50fd81e577a t/geohash.t SHA1 bdd09cf1930990e0da69bcd59e551c6b162f24d0 t/pod-coverage.t SHA1 0190346d7072d458c8a10a45c19f86db641dcc48 t/pod.t -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHyBmawoknRJZQnCERAhpGAJ42bPMKL16Dn4DTsUiGcdFW3G1h1wCgw4Ez 56u88jtB8zcdrU91g56JR60= =HBVQ -----END PGP SIGNATURE----- libgeo-hash-perl-0.02/lib/000077500000000000000000000000001416454745600153435ustar00rootroot00000000000000libgeo-hash-perl-0.02/lib/Geo/000077500000000000000000000000001416454745600160555ustar00rootroot00000000000000libgeo-hash-perl-0.02/lib/Geo/Hash.pm000066400000000000000000000107721416454745600173050ustar00rootroot00000000000000package Geo::Hash; use warnings; use strict; use Carp; =head1 NAME Geo::Hash - Encode / decode geohash.org locations. =head1 VERSION This document describes Geo::Hash version 0.02 =cut our $VERSION = '0.02'; =head1 SYNOPSIS use Geo::Hash; my $gh = Geo::Hash->new; my $hash = $gh->encode( $lat, $lon ); my ( $lat, $lon ) = $gh->decode( $hash ); =head1 DESCRIPTION Geohash is a latitude/longitude geocode system invented by Gustavo Niemeyer when writing the web service at geohash.org, and put into the public domain. This module encodes and decodes geohash locations. See L and L for more information. =head1 INTERFACE =head2 C<< new >> Create a new Geo::Hash object. my $gh = Geo::Hash->new; =cut sub new { bless {}, shift } my @ENC = qw( 0 1 2 3 4 5 6 7 8 9 b c d e f g h j k m n p q r s t u v w x y z ); my %DEC = map { $ENC[$_] => $_ } 0 .. $#ENC; sub _mid { my ( $ar, $wh ) = @_; return ( $ar->[$wh][0] + $ar->[$wh][1] ) / 2; } # The number of bits necessary to represent the specified number of # decimal digits sub _d2b { int( shift() * 3.32192809488736 + 1 ) } sub _bits_for_number { my $n = shift; return 0 unless $n =~ s/.*\.//; return _d2b( length $n ); } =head2 C<< precision >> Infer a suitable precision (number of character in hash) for a given lat, lon pair. my $prec = $gh->precision( $lat, $lon ); =cut sub precision { my ( $self, $lat, $lon ) = @_; my $lab = _bits_for_number( $lat ) + 8; my $lob = _bits_for_number( $lon ) + 9; return int( ( ( $lab > $lob ? $lab : $lob ) + 1 ) / 2.5 ); } =head2 C<< encode >> Encode a lat, long pair into a geohash. my $hash = $gh->encode( $lat, $lon ); You may optionally supply the length of the desired geohash: # Very precise my $hash = $gh->encode( $lat, $lon, 10 ); If the precision argument is omitted C will be used to provide a default. =cut sub encode { croak "encode needs two or three arguments" unless @_ >= 3 && @_ <= 4; my ( $self, @pos ) = splice @_, 0, 3; my $prec = shift || $self->precision( @pos ); my $int = [ [ 90, -90 ], [ 180, -180 ] ]; my $flip = 1; my @enc = (); while ( @enc < $prec ) { my $bits = 0; for ( 0 .. 4 ) { my $mid = _mid( $int, $flip ); my $bit = $pos[$flip] >= $mid ? 1 : 0; $bits = ( ( $bits << 1 ) | $bit ); $int->[$flip][$bit] = $mid; $flip ^= 1; } push @enc, $ENC[$bits]; } return join '', @enc; } =head2 C<< decode_to_interval >> Like C but instead of returning a pair of coordinates returns the interval for each coordinate. This gives some indication of how precisely the original hash specified the location. The return value is a pair of array refs. Each referred to array contains the upper and lower bounds for each coordinate. my ( $lat_range, $lon_range ) = $gh->decode_to_interval( $hash ); # $lat_range and $lon_range are references to two element arrays =cut sub decode_to_interval { croak "Needs one argument" unless @_ == 2; my ( $self, $hash ) = @_; my $int = [ [ 90, -90 ], [ 180, -180 ] ]; my $flip = 1; for my $ch ( split //, $hash ) { if ( defined( my $bits = $DEC{$ch} ) ) { for ( 0 .. 4 ) { $int->[$flip][ ( $bits & 16 ) >> 4 ] = _mid( $int, $flip ); $flip ^= 1; $bits <<= 1; } } else { croak "Bad character '$ch' in hash '$hash'"; } } return @$int; } =head2 C<< decode >> Decode a geohash into a lat, long pair. my ( $lat, $lon ) = $gh->decode( $hash ); =cut sub decode { my @int = shift->decode_to_interval( @_ ); return map { _mid( \@int, $_ ) } 0 .. 1; } 1; __END__ =head1 CONFIGURATION AND ENVIRONMENT Geo::Hash requires no configuration files or environment variables. =head1 DEPENDENCIES None. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. Please report any bugs or feature requests to C, or through the web interface at L. =head1 AUTHOR Andy Armstrong C<< >> L =head1 LICENCE AND COPYRIGHT Copyright (c) 2008, Andy Armstrong C<< >>. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. libgeo-hash-perl-0.02/t/000077500000000000000000000000001416454745600150405ustar00rootroot00000000000000libgeo-hash-perl-0.02/t/00.load.t000066400000000000000000000001631416454745600163620ustar00rootroot00000000000000use Test::More tests => 1; BEGIN { use_ok( 'Geo::Hash' ); } diag( "Testing Geo::Hash $Geo::Hash::VERSION" ); libgeo-hash-perl-0.02/t/geohash.t000066400000000000000000000027131416454745600166460ustar00rootroot00000000000000use strict; use warnings; use Test::More; use Geo::Hash; my @tests = ( { hash => 'ezs42', pos => [ 42.6, -5.6 ], eps => 0.01, }, { hash => 'mh7w', pos => [ -20, 50 ], eps => 0.1, }, { hash => 't3b9m', pos => [ 10.1, 57.2 ], eps => 0.1, }, { hash => 'c2b25ps', pos => [ 49.26, -123.26 ], eps => 0.01, }, { hash => '80021bgm', pos => [ 0.005, -179.567 ], eps => 0.001, }, { hash => 'k484ht99h2', pos => [ -30.55555, 0.2 ], eps => 0.00001, }, { hash => '8buh2w4pnt', pos => [ 5.00001, -140.6 ], eps => 0.00001, }, ); plan tests => 8 * @tests; for my $test ( @tests ) { my ( $hash, $pos, $eps ) = @{$test}{qw(hash pos eps)}; ok my $gh = Geo::Hash->new, "$hash: new"; isa_ok $gh, 'Geo::Hash'; is $gh->encode( @$pos, length $hash ), $hash, "$hash: encode"; { my @got = $gh->decode( $hash ); ok abs( $got[$_] - $pos->[$_] ) < $eps, "$hash: decode $_" for 0 .. 1; } { my $enc_hash = $gh->encode( @$pos ); ok abs( length( $enc_hash ) - length( $hash ) ) <= 1, "$hash: auto precision"; # diag "@$pos ($hash) -> $enc_hash"; my @got = $gh->decode( $enc_hash ); ok abs( $got[$_] - $pos->[$_] ) < $eps, "$hash: decode $_" for 0 .. 1; } } libgeo-hash-perl-0.02/t/pod-coverage.t000066400000000000000000000003641416454745600176030ustar00rootroot00000000000000#!perl -T use Test::More; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; all_pod_coverage_ok( { private => [ qr{^BUILD|DEMOLISH|AUTOMETHOD|START$}, qr{^_} ] } ); libgeo-hash-perl-0.02/t/pod.t000066400000000000000000000002141416454745600160040ustar00rootroot00000000000000#!perl -T use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok();