| Geo-Hash documentation | Contained in the Geo-Hash distribution. |
Geo::Hash - Encode / decode geohash.org locations.
This document describes Geo::Hash version 0.02
use Geo::Hash;
my $gh = Geo::Hash->new;
my $hash = $gh->encode( $lat, $lon );
my ( $lat, $lon ) = $gh->decode( $hash );
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 http://en.wikipedia.org/wiki/Geohash and http://geohash.org for more information.
newCreate a new Geo::Hash object.
my $gh = Geo::Hash->new;
precisionInfer a suitable precision (number of character in hash) for a given lat, lon pair.
my $prec = $gh->precision( $lat, $lon );
encodeEncode 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 precision will be used to
provide a default.
decode_to_intervalLike decode 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
decodeDecode a geohash into a lat, long pair.
my ( $lat, $lon ) = $gh->decode( $hash );
Geo::Hash requires no configuration files or environment variables.
None.
None reported.
No bugs have been reported.
Please report any bugs or feature requests to
bug-geo-hash@rt.cpan.org, or through the web interface at
http://rt.cpan.org.
Andy Armstrong <andy@hexten.net>
Copyright (c) 2008, Andy Armstrong <andy@hexten.net>.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.
| Geo-Hash documentation | Contained in the Geo-Hash distribution. |
package Geo::Hash; use warnings; use strict; use Carp;
our $VERSION = '0.02';
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 ); }
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 ); }
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; }
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; }
sub decode { my @int = shift->decode_to_interval( @_ ); return map { _mid( \@int, $_ ) } 0 .. 1; } 1; __END__