File Coverage

blib/lib/WWW/Velib/Map.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             # Map.pm - WWW::Velib::Map
2             #
3             # Copyright (c) 2007 David Landgren
4             # All rights reserved
5              
6             package WWW::Velib::Map;
7 4     4   32059 use strict;
  4         9  
  4         179  
8              
9 4     4   2700 use LWP::Simple 'get';
  4         156020  
  4         40  
10 4     4   5598 use XML::Twig;
  0            
  0            
11             use WWW::Velib::Station;
12              
13             use vars '$VERSION';
14             $VERSION = '0.02';
15              
16             use constant DETAILS => 'http://www.velib.paris.fr/service/carto';
17              
18             sub new {
19             my $class = shift;
20             my $self = {};
21              
22             my %arg = @_;
23             if ($arg{file}) {
24             open IN, "< $arg{file}" or do {
25             require Carp;
26             Carp::croak("cannot open $arg{file} for input: $!\n");
27             };
28             chomp(my $header = );
29             if ($header eq '# version 1.0 WWW::Velib::Map data cache') {
30             my $self = bless {
31             html => '',
32             station => _load_v1(\*IN),
33             };
34             close IN;
35             return $self;
36             }
37             else {
38             require Carp;
39             Carp::croak("don't know how to handle $arg{file}: version mis-match\n");
40             }
41             }
42             else {
43             my $station;
44             my $twig = XML::Twig->new(
45             twig_handlers => {
46             marker => sub {
47             my $att = $_->{att};
48             $station->{$att->{number}} = WWW::Velib::Station->make(
49             map {$att->{$_}}
50             qw(number name address fullAddress lat lng open)
51             );
52             },
53             }
54             );
55             if (my $content = get(DETAILS)) {
56             $twig->parse($content);
57             $self->{_html} = $content;
58             $self->{station} = $station;
59             }
60             else {
61             $self->{_html} = '';
62             $self->{station} = {};
63             }
64             }
65             return bless $self, $class;
66             }
67              
68             sub save {
69             my $self = shift;
70             my $file = shift or do {
71             require Carp;
72             Carp::croak("no filename given for save()\n");
73             };
74             open OUT, "> $file" or do {
75             require Carp;
76             Carp::croak("cannot open $file for output: $!\n");
77             };
78             print OUT "# version 1.0 WWW::Velib::Map data cache\n";
79             my $station = $self->station;
80             for my $s (keys %$station) {
81             print OUT join("\t",
82             @{$station->{$s}}{qw(number open lat lng theta phi name address fullAddress)}
83             ), "\n";
84             }
85             close OUT;
86             }
87              
88             sub _load_v1 {
89             local *I = shift;
90             my $s;
91             while (my $rec = ) {
92             chomp $rec;
93             my @rec = split /\t/, $rec;
94             $s->{$rec[0]} = WWW::Velib::Station->load_v1(@rec);
95             }
96             return $s;
97             }
98              
99             sub station {
100             return $_[0]->{station};
101             }
102              
103             sub search {
104             my $self = shift;
105             my %arg = @_;
106             $arg{n} = 1 unless exists $arg{n};
107              
108             my $all = $self->station;
109             my $origin = $all->{$arg{station}};
110             return () unless $origin;
111              
112             my %distance;
113             for my $snum (keys %$all) {
114             my $station = $all->{$snum};
115             my $dist = $station->distance_from($origin);
116             push @{$distance{$dist}}, {dist => $dist, station => $station}
117             if not exists $arg{distance}
118             or (exists $arg{distance} and $dist <= $arg{distance});
119             }
120              
121             my @result;
122             STATION:
123             for my $dist (sort { $a <=> $b } keys %distance) {
124             for my $s (sort {$a->{station}->number <=> $b->{station}->number} @{$distance{$dist}}) {
125             push @result, $s->{station};
126             if (not exists $arg{distance}) {
127             last STATION if scalar @result == $arg{n};
128             }
129             }
130             }
131              
132             if ($arg{status}) {
133             $_->refresh for @result;
134             }
135             return @result;
136             }
137              
138             'The Lusty Decadent Delights of Imperial Pompeii';
139             __END__