-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dracos.pm
75 lines (67 loc) · 2.19 KB
/
Dracos.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package Dracos;
use Modern::Perl;
use File::Slurp;
my $postboxes_data_file = 'postboxes.tsv';
sub get_data {
if (not -e $postboxes_data_file) {
my $uri = 'http://www.dracos.co.uk/play/locating-postboxes/export.php';
die "$postboxes_data_file not there, fetch it from:\n$uri\n";
}
# Read the Dracos file and check the header line.
my @lines = read_file $postboxes_data_file;
die "$postboxes_data_file is empty" if not @lines;
my @header = split /\t/, lc(shift @lines);
my @expected = qw(ref pc loc1 loc2 latitude longitude);
die "too short header: @header" if @header < @expected;
@header = @header[0 .. $#expected];
die "bad header (@header), expected (@expected)"
if not (@header ~~ @expected);
# Remaining lines are data.
my @postbox_data;
foreach (@lines) {
my %h;
@h{qw(ref postcode loc1 loc2 lat lon)} = split /\t/;
foreach (keys %h) {
delete $h{$_} if $h{$_} !~ /\S/;
}
push @postbox_data, \%h;
}
# Process the Dracos entries breaking up the information a bit.
foreach (@postbox_data) {
$_->{operator} = 'Royal Mail'; # might as well assume this
my ($housenumber, $street, $postcode);
if (defined (my $loc1 = delete($_->{loc1}))) {
if ($loc1 =~ /\A(\d+) (.+) ([A-Z]+\d+)\z/) {
($housenumber, $street, $postcode) = ($1, $2, $3);
}
elsif ($loc1 =~ /\A(\d+) (.+)\z/) {
($housenumber, $street) = ($1, $2);
}
else {
$street = $loc1;
}
}
$_->{'addr:housenumber'} = $housenumber if defined $housenumber;
$_->{'addr:street'} = $street if defined $housenumber;
if (defined $postcode and exists $_->{postcode}
and $_->{postcode} !~ /\A$postcode /) {
if ($_->{postcode} =~ /\A${postcode}(\d)\z/) {
# A simple missing space, most likely.
$_->{postcode} = "$postcode $1";
}
else {
warn "inconsistency in Dracos data: box with $_->{postcode} has $postcode in loc1\n";
}
}
# loc2, if present, gives the intersection street. We don't do
# anything with this yet, since addr:street holds just the main one.
#
delete $_->{loc2};
# Rename this to the standard OSM name.
if (exists $_->{postcode}) {
$_->{postal_code} = delete $_->{postcode};
}
}
return @postbox_data;
}
1;