File Coverage

blib/lib/Geo/Coder/Abbreviations.pm
Criterion Covered Total %
statement 33 46 71.7
branch 9 16 56.2
condition 6 6 100.0
subroutine 6 7 85.7
pod 2 2 100.0
total 56 77 72.7


line stmt bran cond sub pod time code
1             package Geo::Coder::Abbreviations;
2              
3 3     3   304407 use warnings;
  3         25  
  3         85  
4 3     3   14 use strict;
  3         4  
  3         47  
5 3     3   1126 use JSON::MaybeXS;
  3         14047  
  3         144  
6 3     3   1122 use LWP::Simple::WithCache;
  3         296849  
  3         166  
7              
8             =head1 NAME
9              
10             Geo::Coder::Abbreviations - Quick and Dirty Interface to https://github.com/mapbox/geocoder-abbreviations
11              
12             =head1 VERSION
13              
14             Version 0.06
15              
16             =cut
17              
18             our %abbreviations;
19             our $VERSION = '0.06';
20              
21             # This is giving 404 errors at the moment
22             # https://github.com/mapbox/mapbox-java/issues/1460
23             # our location = 'https://raw.githubusercontent.com/mapbox/geocoder-abbreviations/master/tokens/en.json';
24 3     3   23 use constant LOCATION => 'https://raw.githubusercontent.com/allison-strandberg/geocoder-abbreviations/master/tokens/en.json';
  3         5  
  3         1230  
25              
26             =head1 SYNOPSIS
27              
28             Provides an interface to https://github.com/mapbox/geocoder-abbreviations.
29             One small function for now, I'll add others later.
30              
31             =head1 SUBROUTINES/METHODS
32              
33             =head2 new
34              
35             Creates a Geo::Coder::Abbreviations object.
36             It takes no arguments.
37             If you have L installed it will load much faster,
38             otherwise it will download the database from the Internet
39             when the class is first instantiated.
40              
41             =cut
42              
43             sub new {
44 4     4 1 81 my $proto = shift;
45 4   100     15 my $class = ref($proto) || $proto;
46              
47 4 100       14 if(!defined($class)) {
    50          
48             # Using CGI::Info->new(), not CGI::Info::new()
49             # carp(__PACKAGE__, ' use ->new() not ::new() to instantiate');
50             # return;
51              
52             # FIXME: this only works when no arguments are given
53 1         3 $class = __PACKAGE__;
54             } elsif(ref($class)) {
55             # clone the given object
56             # return bless { %{$class}, %args }, ref($class);
57 0         0 return bless { %{$class} }, ref($class);
  0         0  
58             }
59              
60 4 100       10 unless(scalar keys(%abbreviations)) {
61 1 50       2 if(eval { require HTTP::Cache::Transparent; }) {
  1         151  
62 0         0 require File::Spec; # That should be installed
63              
64 0         0 File::Spec->import();
65 0         0 HTTP::Cache::Transparent->import();
66              
67 0         0 my $cachedir;
68 0 0       0 if(my $e = $ENV{'CACHEDIR'}) {
69 0         0 $cachedir = File::Spec->catfile($e, 'http-cache-transparent');
70             } else {
71 0         0 $cachedir = File::Spec->catfile(File::Spec->tmpdir(), 'cache', 'http-cache-transparent');
72             }
73              
74 0 0       0 HTTP::Cache::Transparent::init({
75             BasePath => $cachedir,
76             # Verbose => $opts{'v'} ? 1 : 0,
77             NoUpdate => 60 * 60 * 24,
78             MaxAge => 30 * 24
79             }) || die "$0: $cachedir: $!";
80             }
81              
82             # TODO: Support other languages
83 1         8 my $data = LWP::Simple::WithCache::get(LOCATION);
84              
85 1 50       530495 if(!defined($data)) {
86             # die 'error downloading from ', LOCATION;
87 0         0 $data = join('', grep(!/^\s*(#|$)/, ));
88             }
89             %abbreviations = map {
90 343         979 my %rc = ();
91 343 100 100     527 if(defined($_->{'type'}) && ($_->{'type'} eq 'way')) {
92 62         56 foreach my $token(@{$_->{'tokens'}}) {
  62         72  
93 144         255 $rc{uc($token)} = uc($_->{'canonical'});
94             }
95             }
96 343         413 %rc;
97 1         2 } @{JSON::MaybeXS->new()->utf8()->decode($data)};
  1         10  
98              
99             # %abbreviations = map { (defined($_->{'type'}) && ($_->{'type'} eq 'way')) ? (uc($_->{'full'}) => uc($_->{'canonical'})) : () } @{JSON::MaybeXS->new()->utf8()->decode($data)};
100             }
101              
102 4         141 return bless {
103             table => \%abbreviations
104             }, $class;
105             }
106              
107             =head2 abbreviate
108              
109             Abbreviate a place.
110              
111             use Geo::Coder::Abbreviations;
112              
113             my $abbr = Geo::Coder::Abbreviations->new();
114             print $abbr->abbreviate('Road'), "\n"; # prints 'RD'
115             print $abbr->abbreviate('RD'), "\n"; # prints 'RD'
116              
117             =cut
118              
119             sub abbreviate {
120 0     0 1   my $self = shift;
121              
122 0           return $self->{'table'}->{uc(shift)};
123             }
124              
125             =head1 SEE ALSO
126              
127             L
128             L
129             L
130              
131             =head1 AUTHOR
132              
133             Nigel Horne, C<< >>
134              
135             =head1 BUGS
136              
137             You may need to ensure you don't translate "Cross Street" to "X ST".
138             See t/abbreviations.t.
139              
140             =head1 SUPPORT
141              
142             You can find documentation for this module with the perldoc command.
143              
144             perldoc Geo::Coder::Abbreviations
145              
146             You can also look for information at:
147              
148             =over 4
149              
150             =item * RT: CPAN's request tracker
151              
152             L
153              
154             =item * Search CPAN
155              
156             L
157              
158             =back
159              
160             =head1 ACKNOWLEDGMENTS
161              
162             =head1 LICENSE AND COPYRIGHT
163              
164             Copyright 2020-2023 Nigel Horne.
165              
166             This program is released under the following licence: GPL2
167              
168             =cut
169              
170             1; # End of Geo::Coder::Abbreviations
171              
172             # https://raw.githubusercontent.com/mapbox/geocoder-abbreviations/master/tokens/en.json is giving 404 errors at the moment
173             # so here is a copy until it's back
174              
175             __DATA__