aboutsummaryrefslogtreecommitdiffstats
path: root/perllib
diff options
context:
space:
mode:
Diffstat (limited to 'perllib')
-rw-r--r--perllib/Carp/Always.pm162
-rw-r--r--perllib/Cobrands/Barnet/Util.pm8
-rw-r--r--perllib/FixMyStreet/Alert.pm14
-rw-r--r--perllib/FixMyStreet/Geocode.pm36
-rw-r--r--perllib/FixMyStreet/Map.pm93
-rw-r--r--perllib/FixMyStreet/Map/Tilma/Original.pm57
-rw-r--r--perllib/Page.pm5
-rw-r--r--perllib/Problems.pm30
-rw-r--r--perllib/Utils.pm70
9 files changed, 382 insertions, 93 deletions
diff --git a/perllib/Carp/Always.pm b/perllib/Carp/Always.pm
new file mode 100644
index 000000000..68bcaee52
--- /dev/null
+++ b/perllib/Carp/Always.pm
@@ -0,0 +1,162 @@
+
+package Carp::Always;
+
+use 5.006;
+use strict;
+use warnings;
+
+our $VERSION = '0.09';
+
+use Carp qw(verbose); # makes carp() cluck and croak() confess
+
+sub _warn {
+ if ($_[-1] =~ /\n$/s) {
+ my $arg = pop @_;
+ $arg =~ s/ at .*? line .*?\n$//s;
+ push @_, $arg;
+ }
+ warn &Carp::longmess;
+}
+
+sub _die {
+ if ($_[-1] =~ /\n$/s) {
+ my $arg = pop @_;
+ $arg =~ s/ at .*? line .*?\n$//s;
+ push @_, $arg;
+ }
+ die &Carp::longmess;
+}
+
+my %OLD_SIG;
+
+BEGIN {
+ @OLD_SIG{qw(__DIE__ __WARN__)} = @SIG{qw(__DIE__ __WARN__)};
+ $SIG{__DIE__} = \&_die;
+ $SIG{__WARN__} = \&_warn;
+}
+
+END {
+ @SIG{qw(__DIE__ __WARN__)} = @OLD_SIG{qw(__DIE__ __WARN__)};
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Carp::Always - Warns and dies noisily with stack backtraces
+
+=head1 SYNOPSIS
+
+ use Carp::Always;
+
+makes every C<warn()> and C<die()> complains loudly in the calling package
+and elsewhere. More often used on the command line:
+
+ perl -MCarp::Always script.pl
+
+=head1 DESCRIPTION
+
+This module is meant as a debugging aid. It can be
+used to make a script complain loudly with stack backtraces
+when warn()ing or die()ing.
+
+Here are how stack backtraces produced by this module
+looks:
+
+ # it works for explicit die's and warn's
+ $ perl -MCarp::Always -e 'sub f { die "arghh" }; sub g { f }; g'
+ arghh at -e line 1
+ main::f() called at -e line 1
+ main::g() called at -e line 1
+
+ # it works for interpreter-thrown failures
+ $ perl -MCarp::Always -w -e 'sub f { $a = shift; @a = @$a };' \
+ -e 'sub g { f(undef) }; g'
+ Use of uninitialized value in array dereference at -e line 1
+ main::f('undef') called at -e line 2
+ main::g() called at -e line 2
+
+In the implementation, the C<Carp> module does
+the heavy work, through C<longmess()>. The
+actual implementation sets the signal hooks
+C<$SIG{__WARN__}> and C<$SIG{__DIE__}> to
+emit the stack backtraces.
+
+Oh, by the way, C<carp> and C<croak> when requiring/using
+the C<Carp> module are also made verbose, behaving
+like C<cloak> and C<confess>, respectively.
+
+=head2 EXPORT
+
+Nothing at all is exported.
+
+=head1 ACKNOWLEDGMENTS
+
+This module was born as a reaction to a release
+of L<Acme::JavaTrace> by Sébastien Aperghis-Tramoni.
+Sébastien also has a newer module called
+L<Devel::SimpleTrace> with the same code and fewer flame
+comments on docs. The pruning of the uselessly long
+docs of this module were prodded by Michael Schwern.
+
+Schwern and others told me "the module name stinked" -
+it was called C<Carp::Indeed>. After thinking long
+and not getting nowhere, I went with nuffin's suggestion
+and now it is called C<Carp::Always>.
+C<Carp::Indeed> which is now deprecate
+lives in its own distribution (which won't go anywhere
+but will stay there as a redirection to this module).
+
+=head1 SEE ALSO
+
+=over 4
+
+=item *
+
+L<Carp>
+
+=item *
+
+L<Acme::JavaTrace> and L<Devel::SimpleTrace>
+
+=back
+
+Please report bugs via CPAN RT
+http://rt.cpan.org/NoAuth/Bugs.html?Dist=Carp-Always.
+
+=head1 BUGS
+
+Every (un)deserving module has its own pet bugs.
+
+=over 4
+
+=item *
+
+This module does not play well with other modules which fusses
+around with C<warn>, C<die>, C<$SIG{'__WARN__'}>,
+C<$SIG{'__DIE__'}>.
+
+=item *
+
+Test scripts are good. I should write more of these.
+
+=item *
+
+I don't know if this module name is still a bug as it was
+at the time of C<Carp::Indeed>.
+
+=back
+
+=head1 AUTHOR
+
+Adriano Ferreira, E<lt>ferreira@cpan.orgE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2005-2007 by Adriano R. Ferreira
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
diff --git a/perllib/Cobrands/Barnet/Util.pm b/perllib/Cobrands/Barnet/Util.pm
index 32973c10c..8ce296aaf 100644
--- a/perllib/Cobrands/Barnet/Util.pm
+++ b/perllib/Cobrands/Barnet/Util.pm
@@ -69,9 +69,9 @@ sub council_check {
my $councils;
if ($params->{all_councils}) {
$councils = $params->{all_councils};
- } elsif ($params->{e}) {
+ } elsif (defined $params->{lat}) {
my $parent_types = $mySociety::VotingArea::council_parent_types;
- $councils = mySociety::MaPit::call('point', "27700/$params->{e},$params->{n}", type => $parent_types);
+ $councils = mySociety::MaPit::call('point', "4326/$params->{lon},$params->{lat}", type => $parent_types);
}
my $council_match = defined $councils->{2489};
if ($council_match) {
@@ -104,9 +104,9 @@ sub disambiguate_location {
}
sub recent_photos {
- my ($self, $num, $e, $n, $dist) = @_;
+ my ($self, $num, $lat, $lon, $dist) = @_;
$num = 2 if $num == 3;
- return Problems::recent_photos($num, $e, $n, $dist);
+ return Problems::recent_photos($num, $lat, $lon, $dist);
}
1;
diff --git a/perllib/FixMyStreet/Alert.pm b/perllib/FixMyStreet/Alert.pm
index b9c124741..90a5b1aaa 100644
--- a/perllib/FixMyStreet/Alert.pm
+++ b/perllib/FixMyStreet/Alert.pm
@@ -184,12 +184,11 @@ sub email_alerts ($) {
$query->execute();
while (my $alert = $query->fetchrow_hashref) {
next unless (Cobrand::email_host($alert->{cobrand}));
- my $e = $alert->{parameter};
- my $n = $alert->{parameter2};
+ my $longitude = $alert->{parameter};
+ my $latitude = $alert->{parameter2};
$url = Cobrand::base_url_for_emails($alert->{cobrand}, $alert->{cobrand_data});
my ($site_restriction, $site_id) = Cobrand::site_restriction($alert->{cobrand}, $alert->{cobrand_data});
- my ($lat, $lon) = mySociety::GeoUtil::national_grid_to_wgs84($e, $n, 'G');
- my $d = mySociety::Gaze::get_radius_containing_population($lat, $lon, 200000);
+ my $d = mySociety::Gaze::get_radius_containing_population($latitude, $longitude, 200000);
$d = int($d*10+0.5)/10;
my $testing_email_clause = "and problem.email <> '$testing_email'" if $testing_email;
my %data = ( template => $template, data => '', alert_id => $alert->{id}, alert_email => $alert->{email}, lang => $alert->{lang}, cobrand => $alert->{cobrand}, cobrand_data => $alert->{cobrand_data} );
@@ -202,7 +201,7 @@ sub email_alerts ($) {
$site_restriction
order by confirmed desc";
$q = dbh()->prepare($q);
- $q->execute($e, $n, $d, $alert->{whensubscribed}, $alert->{id}, $alert->{email});
+ $q->execute($latitude, $longitude, $d, $alert->{whensubscribed}, $alert->{id}, $alert->{email});
while (my $row = $q->fetchrow_hashref) {
dbh()->do('insert into alert_sent (alert_id, parameter) values (?,?)', {}, $alert->{id}, $row->{id});
$data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}\n\n";
@@ -310,9 +309,8 @@ sub generate_rss ($$$;$$$$) {
}
$item{description} .= ent("\n<br><a href='$cobrand_url'>Report on FixMyStreet</a>");
- if ($row->{easting} && $row->{northing}) {
- my ($lat,$lon) = mySociety::GeoUtil::national_grid_to_wgs84($row->{easting}, $row->{northing}, 'G');
- $item{georss} = { point => "$lat $lon" };
+ if ($row->{latitude} || $row->{longitude}) {
+ $item{georss} = { point => "$row->{latitude} $row->{longitude}" };
}
$rss->add_item( %item );
}
diff --git a/perllib/FixMyStreet/Geocode.pm b/perllib/FixMyStreet/Geocode.pm
index 4854411cf..0379169b8 100644
--- a/perllib/FixMyStreet/Geocode.pm
+++ b/perllib/FixMyStreet/Geocode.pm
@@ -37,40 +37,32 @@ BEGIN {
# of the site to diambiguate locations.
sub lookup {
my ($s, $q) = @_;
- my ($easting, $northing, $error);
+ my ($latitude, $longitude, $error);
if ($s =~ /^\d+$/) {
$error = 'FixMyStreet is a UK-based website that currently works in England, Scotland, and Wales. Please enter either a postcode, or a Great British street name and area.';
} elsif (mySociety::PostcodeUtil::is_valid_postcode($s)) {
my $location = mySociety::MaPit::call('postcode', $s);
unless ($error = Page::mapit_check_error($location)) {
- $easting = $location->{easting};
- $northing = $location->{northing};
+ $latitude = $location->{wgs84_lat};
+ $longitude = $location->{wgs84_lon};
}
} else {
- ($easting, $northing, $error) = FixMyStreet::Geocode::string($s, $q);
+ ($latitude, $longitude, $error) = FixMyStreet::Geocode::string($s, $q);
}
- return ($easting, $northing, $error);
+ return ($latitude, $longitude, $error);
}
sub geocoded_string_coordinates {
my ($js, $q) = @_;
- my ($easting, $northing, $error);
+ my ($latitude, $longitude, $error);
my ($accuracy) = $js =~ /"Accuracy" *: *(\d)/;
if ($accuracy < 4) {
$error = _('Sorry, that location appears to be too general; please be more specific.');
- } else {
-
- $js =~ /"coordinates" *: *\[ *(.*?), *(.*?),/;
- my $lon = $1; my $lat = $2;
- try {
- ($easting, $northing) = mySociety::GeoUtil::wgs84_to_national_grid($lat, $lon, 'G');
- } catch Error::Simple with {
- $error = shift;
- $error = _('That location does not appear to be in Britain; please try again.')
- if $error =~ /out of the area covered/;
- }
- }
- return ($easting, $northing, $error);
+ } elsif ( $js =~ /"coordinates" *: *\[ *(.*?), *(.*?),/ ) {
+ $longitude = $1;
+ $latitude = $2;
+ }
+ return ($latitude, $longitude, $error);
}
# string STRING QUERY
@@ -90,7 +82,7 @@ sub string {
my $url = 'http://maps.google.com/maps/geo?' . $s;
my $cache_dir = mySociety::Config::get('GEO_CACHE');
my $cache_file = $cache_dir . md5_hex($url);
- my ($js, $error, $easting, $northing);
+ my ($js, $error, $latitude, $longitude);
if (-s $cache_file) {
$js = File::Slurp::read_file($cache_file);
} else {
@@ -123,9 +115,9 @@ sub string {
# Northern Ireland, hopefully
$error = _("We do not cover Northern Ireland, I'm afraid, as our licence doesn't include any maps for the region.");
} else {
- ($easting, $northing, $error) = geocoded_string_coordinates($js, $q);
+ ($latitude, $longitude, $error) = geocoded_string_coordinates($js, $q);
}
- return ($easting, $northing, $error);
+ return ($latitude, $longitude, $error);
}
# list_choices
diff --git a/perllib/FixMyStreet/Map.pm b/perllib/FixMyStreet/Map.pm
index 12ecf78fe..0902914dd 100644
--- a/perllib/FixMyStreet/Map.pm
+++ b/perllib/FixMyStreet/Map.pm
@@ -14,29 +14,34 @@ use Problems;
use Cobrand;
use mySociety::Config;
use mySociety::Gaze;
-use mySociety::GeoUtil;
+use mySociety::GeoUtil qw(national_grid_to_wgs84);
use mySociety::Locale;
use mySociety::Web qw(ent NewURL);
+use Utils;
# Run on module boot up
load();
# This is yucky, but no-one's taught me a better way
sub load {
- my $type = mySociety::Config::get('MAP_TYPE');
+ my $type = mySociety::Config::get('MAP_TYPE');
my $class = "FixMyStreet::Map::$type";
eval "use $class";
+
+ # If we have an error die as it is a compile error rather than runtime error
+ die $@ if $@;
}
sub header {
- my ($q, $type) = @_;
+ my ( $q, $type ) = @_;
return '' unless $type;
my $cobrand = Page::get_cobrand($q);
- my $cobrand_form_elements = Cobrand::form_elements($cobrand, 'mapForm', $q);
- my $form_action = Cobrand::url($cobrand, '', $q);
+ my $cobrand_form_elements =
+ Cobrand::form_elements( $cobrand, 'mapForm', $q );
+ my $form_action = Cobrand::url( $cobrand, '', $q );
my $encoding = '';
- $encoding = ' enctype="multipart/form-data"' if $type==2;
+ $encoding = ' enctype="multipart/form-data"' if $type == 2;
my $pc = $q->param('pc') || '';
my $pc_enc = ent($pc);
return <<EOF;
@@ -47,49 +52,67 @@ $cobrand_form_elements
EOF
}
+=head2 map_features_easting_northing
+
+Wrapper around map_features which does the easting, northing to lat, lon
+conversion.
+
+=cut
+
+sub map_features_easting_northing {
+ my ( $q, $easting, $northing, $interval ) = @_;
+ my ( $lat, $lon ) = Utils::convert_en_to_latlon( $easting, $northing );
+ return map_features( $q, $lat, $lon, $interval );
+}
+
sub map_features {
- my ($q, $easting, $northing, $interval) = @_;
-
- my $min_e = $easting - 500;
- my $min_n = $northing - 500;
- my $mid_e = $easting;
- my $mid_n = $northing;
- my $max_e = $easting + 500;
- my $max_n = $northing + 500;
-
- # list of problems aoround map can be limited, but should show all pins
- my ($around_map, $around_map_list);
- if (my $around_limit = Cobrand::on_map_list_limit(Page::get_cobrand($q))) {
- $around_map_list = Problems::around_map($min_e, $max_e, $min_n, $max_n, $interval, $around_limit);
- $around_map = Problems::around_map($min_e, $max_e, $min_n, $max_n, $interval, undef);
- } else {
- $around_map = $around_map_list = Problems::around_map($min_e, $max_e, $min_n, $max_n, $interval, undef);
- }
+ my ( $q, $lat, $lon, $interval ) = @_;
+
+ # TODO - be smarter about calculating the surrounding square
+ # use deltas that are roughly 500m in the UK - so we get a 1 sq km search box
+ my $lat_delta = 0.00438;
+ my $lon_delta = 0.00736;
+
+ my $min_lat = $lat - $lat_delta;
+ my $max_lat = $lat + $lat_delta;
+
+ my $min_lon = $lon - $lon_delta;
+ my $max_lon = $lon + $lon_delta;
+
+ # list of problems around map can be limited, but should show all pins
+ my $around_limit #
+ = Cobrand::on_map_list_limit( Page::get_cobrand($q) ) || undef;
+
+ my @around_args = ( $min_lat, $max_lat, $min_lon, $max_lon, $interval );
+ my $around_map_list = Problems::around_map( @around_args, $around_limit );
+ my $around_map = Problems::around_map( @around_args, undef );
my $dist;
mySociety::Locale::in_gb_locale {
- my ($lat, $lon) = mySociety::GeoUtil::national_grid_to_wgs84($mid_e, $mid_n, 'G');
- $dist = mySociety::Gaze::get_radius_containing_population($lat, $lon, 200000);
+ $dist =
+ mySociety::Gaze::get_radius_containing_population( $lat, $lon,
+ 200000 );
};
- $dist = int($dist*10+0.5)/10;
+ $dist = int( $dist * 10 + 0.5 ) / 10;
- my $limit = 20;
- my @ids = map { $_->{id} } @$around_map_list;
- my $nearby = Problems::nearby($dist, join(',', @ids), $limit, $mid_e, $mid_n, $interval);
+ my $limit = 20;
+ my @ids = map { $_->{id} } @$around_map_list;
+ my $nearby = Problems::nearby( $dist, join( ',', @ids ),
+ $limit, $lat, $lon, $interval );
- return ($around_map, $around_map_list, $nearby, $dist);
+ return ( $around_map, $around_map_list, $nearby, $dist );
}
sub compass ($$$) {
- my ($q, $x, $y) = @_;
+ my ( $q, $x, $y ) = @_;
my @compass;
- for (my $i=$x-1; $i<=$x+1; $i++) {
- for (my $j=$y-1; $j<=$y+1; $j++) {
- $compass[$i][$j] = NewURL($q, x=>$i, y=>$j);
+ for ( my $i = $x - 1 ; $i <= $x + 1 ; $i++ ) {
+ for ( my $j = $y - 1 ; $j <= $y + 1 ; $j++ ) {
+ $compass[$i][$j] = NewURL( $q, x => $i, y => $j );
}
}
my $recentre = NewURL($q);
- my $host = Page::base_url_with_lang($q, undef);
+ my $host = Page::base_url_with_lang( $q, undef );
return <<EOF;
<table cellpadding="0" cellspacing="0" border="0" id="compass">
<tr valign="bottom">
diff --git a/perllib/FixMyStreet/Map/Tilma/Original.pm b/perllib/FixMyStreet/Map/Tilma/Original.pm
index 5772f6ccd..81b123b30 100644
--- a/perllib/FixMyStreet/Map/Tilma/Original.pm
+++ b/perllib/FixMyStreet/Map/Tilma/Original.pm
@@ -13,6 +13,13 @@ use LWP::Simple;
use Cobrand;
use mySociety::Web qw(ent NewURL);
+use mySociety::GeoUtil;
+use Utils;
+
+sub _ll_to_en {
+ my ($lat, $lon) = @_;
+ return mySociety::GeoUtil::wgs84_to_national_grid( $lat, $lon, 'G' );
+}
sub header_js {
return '
@@ -22,7 +29,7 @@ sub header_js {
# display_map Q PARAMS
# PARAMS include:
-# EASTING, NORTHING for the centre point of the map
+# latitude, longitude for the centre point of the map
# TYPE is 1 if the map is clickable, 2 if clickable and has a form upload,
# 0 if not clickable
# PINS is array of pins to show, location and colour
@@ -36,6 +43,18 @@ sub _display_map {
$mid_point = 189;
}
+ # convert map center point to easting, northing
+ ( $params{easting}, $params{northing} ) =
+ _ll_to_en( $params{latitude}, $params{longitude} );
+
+ # FIXME - convert all pins to lat, lng
+ # all the pins are currently [lat, lng, colour] - convert them
+ foreach my $pin ( @{ $params{pins} ||= [] } ) {
+ my ( $lat, $lon ) = ( $pin->[0], $pin->[1] );
+ my ( $e, $n ) = _ll_to_en( $lat, $lon );
+ ( $pin->[0], $pin->[1] ) = ( $e, $n );
+ }
+
# X/Y tile co-ords may be overridden in the query string
my @vars = qw(x y);
my %input = map { $_ => $q->param($_) || '' } @vars;
@@ -154,10 +173,14 @@ sub map_pins {
my $e = FixMyStreet::Map::tile_to_os($x);
my $n = FixMyStreet::Map::tile_to_os($y);
- my ($around_map, $around_map_list, $nearby, $dist) = FixMyStreet::Map::map_features($q, $e, $n, $interval);
+
+ my ( $around_map, $around_map_list, $nearby, $dist ) =
+ FixMyStreet::Map::map_features_easting_northing( $q, $e, $n, $interval );
my $pins = '';
foreach (@$around_map) {
+ ( $_->{easting}, $_->{northing} ) =
+ _ll_to_en( $_->{latitude}, $_->{longitude} );
my $px = FixMyStreet::Map::os_to_px($_->{easting}, $sx);
my $py = FixMyStreet::Map::os_to_px($_->{northing}, $sy, 1);
my $col = $_->{state} eq 'fixed' ? 'green' : 'red';
@@ -165,6 +188,8 @@ sub map_pins {
}
foreach (@$nearby) {
+ ( $_->{easting}, $_->{northing} ) =
+ _ll_to_en( $_->{latitude}, $_->{longitude} );
my $px = FixMyStreet::Map::os_to_px($_->{easting}, $sx);
my $py = FixMyStreet::Map::os_to_px($_->{northing}, $sy, 1);
my $col = $_->{state} eq 'fixed' ? 'green' : 'red';
@@ -196,10 +221,30 @@ sub tile_to_px {
sub os_to_tile {
return $_[0] / SCALE_FACTOR;
}
+
sub tile_to_os {
return int($_[0] * SCALE_FACTOR + 0.5);
}
+=head2 tile_xy_to_wgs84
+
+ ($lat, $lon) = tile_xy_to_wgs84( $x, $y );
+
+Takes the tile x,y and converts to lat, lon.
+
+=cut
+
+sub tile_xy_to_wgs84 {
+ my ( $x, $y ) = @_;
+
+ my $easting = tile_to_os($x);
+ my $northing = tile_to_os($y);
+
+ my ( $lat, $lon ) = Utils::convert_en_to_latlon( $easting, $northing );
+ return ( $lat, $lon );
+}
+
+
sub click_to_tile {
my ($pin_tile, $pin, $invert) = @_;
$pin -= TILE_WIDTH while $pin > TILE_WIDTH;
@@ -219,6 +264,14 @@ sub click_to_os {
return ($easting, $northing);
}
+# Given some click co-ords (the tile they were on, and where in the
+# tile they were), convert to WGS84 and return.
+sub click_to_wgs84 {
+ my ( $easting, $northing ) = FixMyStreet::Map::click_to_os(@_);
+ my ( $lat, $lon ) = national_grid_to_wgs84( $easting, $northing, 'G' );
+ return ( $lat, $lon );
+}
+
# Given (E,N) and potential override (X,Y), return the X/Y tile for the centre
# of the map (either to get the point near the middle, or the override X,Y),
# and the pixel co-ords of the point, relative to that map.
diff --git a/perllib/Page.pm b/perllib/Page.pm
index b3f320f5d..fc7127a78 100644
--- a/perllib/Page.pm
+++ b/perllib/Page.pm
@@ -80,6 +80,9 @@ sub report_error {
my $trylater = sprintf(_('Please try again later, or <a href="mailto:%s">email us</a> to let us know.'), $contact_email);
my $somethingwrong = _("Sorry! Something's gone wrong.");
my $errortext = _("The text of the error was:");
+
+ my $msg_br = join '<br><br>', split m{\n}, $msg;
+
print "Status: 500\nContent-Type: text/html; charset=iso-8859-1\n\n",
qq(<html><head><title>$somethingwrong</title></head></html>),
q(<body>),
@@ -87,7 +90,7 @@ sub report_error {
qq(<p>$trylater</p>),
q(<hr>),
qq(<p>$errortext</p>),
- qq(<blockquote class="errortext">$msg</blockquote>),
+ qq(<blockquote class="errortext">$msg_br</blockquote>),
q(</body></html>);
}
diff --git a/perllib/Problems.pm b/perllib/Problems.pm
index 1556b7724..8c6eeccad 100644
--- a/perllib/Problems.pm
+++ b/perllib/Problems.pm
@@ -87,10 +87,10 @@ sub recent_new {
# Front page recent lists
sub recent_photos {
- my ($num, $e, $n, $dist) = @_;
+ my ($num, $lat, $lon, $dist) = @_;
my $probs;
- if ($e) {
- my $key = "recent_photos:$site_key:$num:$e:$n:$dist";
+ if (defined $lat) {
+ my $key = "recent_photos:$site_key:$num:$lat:$lon:$dist";
$probs = Memcached::get($key);
unless ($probs) {
$probs = select_all("select id, title
@@ -98,7 +98,7 @@ sub recent_photos {
where nearby.problem_id = problem.id
and state in ('confirmed', 'fixed') and photo is not null
$site_restriction
- order by confirmed desc limit $num", $e, $n, $dist);
+ order by confirmed desc limit $num", $lat, $lon, $dist);
Memcached::set($key, $probs, 3600);
}
} else {
@@ -170,46 +170,46 @@ sub front_stats {
# Problems around a location
sub around_map {
- my ($min_e, $max_e, $min_n, $max_n, $interval, $limit) = @_;
+ my ($min_lat, $max_lat, $min_lon, $max_lon, $interval, $limit) = @_;
my $limit_clause = '';
if ($limit) {
$limit_clause = " limit $limit";
}
mySociety::Locale::in_gb_locale { select_all(
- "select id,title,easting,northing,state,
+ "select id,title,latitude,longitude,state,
extract(epoch from confirmed) as time
from problem
where state in ('confirmed', 'fixed')
- and easting>=? and easting<? and northing>=? and northing<? " .
+ and latitude>=? and latitude<? and longitude>=? and longitude<? " .
($interval ? " and ms_current_timestamp()-lastupdate < '$interval'::interval" : '') .
" $site_restriction
order by created desc
- $limit_clause", $min_e, $max_e, $min_n, $max_n);
+ $limit_clause", $min_lat, $max_lat, $min_lon, $max_lon);
};
}
sub nearby {
- my ($dist, $ids, $limit, $mid_e, $mid_n, $interval) = @_;
+ my ($dist, $ids, $limit, $mid_lat, $mid_lon, $interval) = @_;
mySociety::Locale::in_gb_locale { select_all(
- "select id, title, easting, northing, distance, state,
+ "select id, title, latitude, longitude, distance, state,
extract(epoch from confirmed) as time
from problem_find_nearby(?, ?, $dist) as nearby, problem
where nearby.problem_id = problem.id " .
($interval ? " and ms_current_timestamp()-lastupdate < '$interval'::interval" : '') .
" and state in ('confirmed', 'fixed')" . ($ids ? ' and id not in (' . $ids . ')' : '') . "
$site_restriction
- order by distance, created desc limit $limit", $mid_e, $mid_n);
+ order by distance, created desc limit $limit", $mid_lat, $mid_lon);
}
}
sub fixed_nearby {
- my ($dist, $mid_e, $mid_n) = @_;
+ my ($dist, $mid_lat, $mid_lon) = @_;
mySociety::Locale::in_gb_locale { select_all(
- "select id, title, easting, northing, distance
+ "select id, title, latitude, longitude, distance
from problem_find_nearby(?, ?, $dist) as nearby, problem
where nearby.problem_id = problem.id and state='fixed'
$site_restriction
- order by lastupdate desc", $mid_e, $mid_n);
+ order by lastupdate desc", $mid_lat, $mid_lon);
}
}
@@ -218,7 +218,7 @@ sub fixed_nearby {
sub fetch_problem {
my $id = shift;
my $p = dbh()->selectrow_hashref(
- "select id, easting, northing, council, category, title, detail, photo,
+ "select id, latitude, longitude, council, category, title, detail, photo,
used_map, name, anonymous, extract(epoch from confirmed) as time,
state, extract(epoch from whensent-confirmed) as whensent,
extract(epoch from ms_current_timestamp()-lastupdate) as duration,
diff --git a/perllib/Utils.pm b/perllib/Utils.pm
index 24f4a6f94..d54e081c8 100644
--- a/perllib/Utils.pm
+++ b/perllib/Utils.pm
@@ -13,18 +13,76 @@ package Utils;
use strict;
use mySociety::DBHandle qw(dbh);
+use mySociety::GeoUtil;
sub workaround_pg_bytea {
- my ($st, $img_idx, @elements) = @_;
+ my ( $st, $img_idx, @elements ) = @_;
my $s = dbh()->prepare($st);
- for (my $i=1; $i<=@elements; $i++) {
- if ($i == $img_idx) {
- $s->bind_param($i, $elements[$i-1], { pg_type => DBD::Pg::PG_BYTEA });
- } else {
- $s->bind_param($i, $elements[$i-1]);
+ for ( my $i = 1 ; $i <= @elements ; $i++ ) {
+ if ( $i == $img_idx ) {
+ $s->bind_param(
+ $i,
+ $elements[ $i - 1 ],
+ { pg_type => DBD::Pg::PG_BYTEA }
+ );
+ }
+ else {
+ $s->bind_param( $i, $elements[ $i - 1 ] );
}
}
$s->execute();
}
+=head2 convert_en_to_latlon
+
+ ( $latitude, $longitude ) = Utils::convert_en_to_latlon( $easting, $northing );
+
+Takes the easting and northing and returns latitude and longitude.
+
+=cut
+
+sub convert_en_to_latlon {
+ my ( $easting, $northing ) = @_;
+
+ my ( $latitude, $longitude ) =
+
+ # map { truncate_coordinate($_) }
+ mySociety::GeoUtil::national_grid_to_wgs84( $easting, $northing, 'G' );
+
+ return ( $latitude, $longitude );
+}
+
+=head2 convert_en_to_latlon_truncated
+
+ ( $lat, $lon ) = Utils::convert_en_to_latlon( $easting, $northing );
+
+Takes the easting and northing and returns latitude and longitude (truncated
+using C<Utils::truncate_coordinate>).
+
+=cut
+
+sub convert_en_to_latlon_truncated {
+ my ( $easting, $northing ) = @_;
+
+ return
+ map { truncate_coordinate($_) }
+ convert_en_to_latlon( $easting, $northing );
+}
+
+=head2 truncate_coordinate
+
+ $short = Utils::truncate_coordinate( $long );
+
+Given a long coordinate returns a shorter one - rounded to 6 decimal places -
+which is < 1m at the equator.
+
+=cut
+
+sub truncate_coordinate {
+ my $in = shift;
+ my $out = sprintf( '%0.6f', $in );
+ $out =~ s{\.?0+\z}{} if $out =~ m{\.};
+ return $out;
+}
+
1;