Algorithm-GooglePolylineEncoding

 view release on metacpan or  search on metacpan

GooglePolylineEncoding.pm  view on Meta::CPAN

    $number &= 0xffffffff; # to assure 32 bit
#   5. If the original decimal value is negative, invert this encoding:
#      00000010 00100101 01000011 11100001
    if ($is_negative) {
        $number = (~$number);
        $number &= 0xffffffff;
    }
#   6. Break the binary value out into 5-bit chunks (starting from the right hand side):
#      00001 00010 01010 10000 11111 00001
    my $bin = sprintf '%b', $number;
    $bin = '0'x(5-length($bin)%5) . $bin if length($bin)%5 != 0; # pad
    my @chunks;
    my $revbin = reverse $bin;
    push @chunks, scalar reverse($1) while $revbin =~ m{(.....)}g;
#   7. Place the 5-bit chunks into reverse order:
#      00001 11111 10000 01010 00010 00001
    # It's already reversed
#   8. OR each value with 0x20 if another bit chunk follows:
#      100001 111111 110000 101010 100010 000001
    @chunks = ((map { oct("0b$_") | 0x20 } @chunks[0 .. $#chunks-1]), oct("0b".$chunks[-1])); # and also decode to decimal on the fly
#   9. Convert each value to decimal:

GooglePolylineEncoding.pm  view on Meta::CPAN

    if ($number > ~0) {
	# sprintf '%b' works only for integers
	require Math::BigInt;
	$bin = Math::BigInt->new($number)->as_bin;
	$bin =~ s{^0b}{};
    } else {
	$bin = sprintf '%b', $number;
    }
#   3. Break the binary value out into 5-bit chunks (starting from the right hand side):
#      101 01110
    $bin = '0'x(5-length($bin)%5) . $bin if length($bin)%5 != 0; # pad
    my @chunks;
    my $revbin = reverse $bin;
    push @chunks, scalar reverse($1) while $revbin =~ m{(.....)}g;
#   4. Place the 5-bit chunks into reverse order:
#      01110 101
    # It's already reversed
#   5. OR each value with 0x20 if another bit chunk follows:
#      101110 00101
    @chunks = ((map { oct("0b$_") | 0x20 } @chunks[0 .. $#chunks-1]), oct("0b".$chunks[-1])); # and also decode to decimal on the fly
#   6. Convert each value to decimal:

GooglePolylineEncoding.pm  view on Meta::CPAN

    @chunks = map { chr } @chunks;
    join '', @chunks;
}

# Translated this php script
# <http://unitstep.net/blog/2008/08/02/decoding-google-maps-encoded-polylines-using-php/>
# to perl
sub decode_polyline {
    my($encoded) = @_;

    my $length = length $encoded;
    my $index = 0;
    my @points;
    my $lat = 0;
    my $lng = 0;

    while ($index < $length) {
	# The encoded polyline consists of a latitude value followed
	# by a longitude value. They should always come in pairs. Read
	# the latitude value first.
	for my $val (\$lat, \$lng) {
	    my $shift = 0;
	    my $result = 0;
	    # Temporary variable to hold each ASCII byte.
	    my $b;
	    do {
		# The `ord(substr($encoded, $index++))` statement returns



( run in 0.746 second using v1.01-cache-2.11-cpan-65fba6d93b7 )