diff options
author | Struan Donald <struan@exo.org.uk> | 2017-12-22 12:53:48 +0000 |
---|---|---|
committer | Matthew Somerville <matthew-github@dracos.co.uk> | 2018-05-09 12:57:56 +0100 |
commit | 22f0fed0b1ce6e7effac37e025bd55dc6043a838 (patch) | |
tree | a4bd66224c560418863319e9a6144d9b8702d462 | |
parent | 22815e994510659870987609d244b3f6324bab22 (diff) |
ajax endpoint to return closest address.
/ajax/closest will return ajax with details of the closest address to
the lat/lon passed in from the Bing geocoder.
Tidy up find_closest() to use overloaded string rather than passing
in whether you want a string or not.
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Around.pm | 21 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Default.pm | 35 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/FiksGataMi.pm | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/FixaMinGata.pm | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/UK.pm | 34 | ||||
-rw-r--r-- | perllib/FixMyStreet/Geocode/Address.pm | 28 | ||||
-rw-r--r-- | perllib/FixMyStreet/Integrations/ExorRDI.pm | 4 | ||||
-rw-r--r-- | t/app/model/problem.t | 4 | ||||
-rw-r--r-- | t/cobrand/bromley.t | 1 | ||||
-rw-r--r-- | t/cobrand/closest.t | 16 | ||||
-rw-r--r-- | t/cobrand/oxfordshire.t | 1 | ||||
-rw-r--r-- | t/cobrand/rutland.t | 1 | ||||
-rw-r--r-- | t/sendreport/open311.t | 3 |
13 files changed, 107 insertions, 43 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index 25f97fd8f..8fed5c3aa 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -308,6 +308,27 @@ sub ajax : Path('/ajax') { $c->forward('/reports/ajax', [ 'around/on_map_list_items.html' ]); } +sub location_closest_address : Path('/ajax/closest') { + my ( $self, $c ) = @_; + $c->res->content_type('application/json; charset=utf-8'); + + my $lat = $c->get_param('lat'); + my $lon = $c->get_param('lon'); + unless ($lat && $lon) { + $c->res->status(404); + $c->res->body(''); + return; + } + + my $closest = $c->cobrand->find_closest({ latitude => $lat, longitude => $lon }); + my $data = { + road => $closest->{address}{addressLine}, + full_address => $closest->{name}, + }; + + $c->res->body(encode_json($data)); +} + sub location_autocomplete : Path('/ajax/geocode') { my ( $self, $c ) = @_; $c->res->content_type('application/json; charset=utf-8'); diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 99b247412..92494250e 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -5,6 +5,7 @@ use strict; use warnings; use FixMyStreet; use FixMyStreet::DB; +use FixMyStreet::Geocode::Address; use FixMyStreet::Geocode::Bing; use DateTime; use List::MoreUtils 'none'; @@ -514,34 +515,32 @@ sub geocoded_string_check { return 1; } =item find_closest Used by send-reports and similar to attach nearest things to the bottom of the -report. +report. This can be called with either a hash of lat/lon or a Problem. =cut sub find_closest { - my ( $self, $problem, $as_data ) = @_; + my ($self, $data) = @_; + $data = { problem => $data } if ref $data ne 'HASH'; + + my $problem = $data->{problem}; + my $lat = $problem ? $problem->latitude : $data->{latitude}; + my $lon = $problem ? $problem->longitude : $data->{longitude}; + my $j = $problem->geocode if $problem; - my $j = $problem->geocode; if (!$j) { - $j = FixMyStreet::Geocode::Bing::reverse( $problem->latitude, $problem->longitude, + $j = FixMyStreet::Geocode::Bing::reverse( $lat, $lon, disambiguate_location()->{bing_culture} ); - # cache the bing results for use in alerts - $problem->geocode( $j ); - $problem->update; - } - - my $data = $as_data ? {} : ''; - if ($j && $j->{resourceSets}[0]{resources}[0]{name}) { - my $str = $j->{resourceSets}[0]{resources}[0]{name}; - if ($as_data) { - $data->{road} = $str; - } else { - $data .= sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s"), - $str) . "\n\n"; + if ($problem) { + # cache the bing results for use in alerts + $problem->geocode( $j ); + $problem->update; } } - return $data; + return FixMyStreet::Geocode::Address->new($j->{resourceSets}[0]{resources}[0]) + if $j && $j->{resourceSets}[0]{resources}[0]{name}; + return {}; } =item find_closest_address_for_rss diff --git a/perllib/FixMyStreet/Cobrand/FiksGataMi.pm b/perllib/FixMyStreet/Cobrand/FiksGataMi.pm index e49d5bd47..306ad358a 100644 --- a/perllib/FixMyStreet/Cobrand/FiksGataMi.pm +++ b/perllib/FixMyStreet/Cobrand/FiksGataMi.pm @@ -62,6 +62,7 @@ sub geocoded_string_check { sub find_closest { my ( $self, $problem ) = @_; + $problem = $problem->{problem} if ref $problem eq 'HASH'; return FixMyStreet::Geocode::OSM::closest_road_text( $self, $problem->latitude, $problem->longitude ); } diff --git a/perllib/FixMyStreet/Cobrand/FixaMinGata.pm b/perllib/FixMyStreet/Cobrand/FixaMinGata.pm index 37dec5a11..29e840dfa 100644 --- a/perllib/FixMyStreet/Cobrand/FixaMinGata.pm +++ b/perllib/FixMyStreet/Cobrand/FixaMinGata.pm @@ -122,6 +122,7 @@ sub geocoded_string_check { sub find_closest { my ( $self, $problem ) = @_; + $problem = $problem->{problem} if ref $problem eq 'HASH'; return FixMyStreet::Geocode::OSM::closest_road_text( $self, $problem->latitude, $problem->longitude ); } diff --git a/perllib/FixMyStreet/Cobrand/UK.pm b/perllib/FixMyStreet/Cobrand/UK.pm index 0ecb6a7c6..f99f29eb4 100644 --- a/perllib/FixMyStreet/Cobrand/UK.pm +++ b/perllib/FixMyStreet/Cobrand/UK.pm @@ -117,27 +117,23 @@ sub short_name { } sub find_closest { - my ( $self, $problem, $as_data ) = @_; - - my $data = $self->SUPER::find_closest($problem, $as_data); - - my $mapit_url = FixMyStreet->config('MAPIT_URL'); - my ($lat, $lon) = map { Utils::truncate_coordinate($_) } $problem->latitude, $problem->longitude; - my $url = $mapit_url . "nearest/4326/$lon,$lat"; - my $j = LWP::Simple::get($url); - if ($j) { - $j = JSON->new->utf8->allow_nonref->decode($j); - if ($j->{postcode}) { - if ($as_data) { - $data->{postcode} = $j->{postcode}; - } else { - $data .= sprintf(_("Nearest postcode to the pin placed on the map (automatically generated): %s (%sm away)"), - $j->{postcode}{postcode}, $j->{postcode}{distance}) . "\n\n"; - } - } + my ($self, $data) = @_; + + $data = { problem => $data } if ref $data ne 'HASH'; + + my $problem = $data->{problem}; + my $lat = $problem ? $problem->latitude : $data->{latitude}; + my $lon = $problem ? $problem->longitude : $data->{longitude}; + + my $closest = $self->SUPER::find_closest($data); + + ($lat, $lon) = map { Utils::truncate_coordinate($_) } $lat, $lon; + my $j = mySociety::MaPit::call('nearest', "4326/$lon,$lat"); + if ($j->{postcode}) { + $closest->{postcode} = $j->{postcode}; } - return $data; + return $closest; } sub reports_body_check { diff --git a/perllib/FixMyStreet/Geocode/Address.pm b/perllib/FixMyStreet/Geocode/Address.pm new file mode 100644 index 000000000..522091f62 --- /dev/null +++ b/perllib/FixMyStreet/Geocode/Address.pm @@ -0,0 +1,28 @@ +package FixMyStreet::Geocode::Address; + +use strict; +use warnings; + +use overload '""' => \&as_string, fallback => 1; + +sub new { + my ($class, $data) = @_; + my $self = { %$data }; + bless $self, $class; +} + +sub as_string { + my $self = shift; + + my $data = sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s"), + $self->{name}) . "\n\n"; + + if ($self->{postcode}) { + $data .= sprintf(_("Nearest postcode to the pin placed on the map (automatically generated): %s (%sm away)"), + $self->{postcode}{postcode}, $self->{postcode}{distance}) . "\n\n"; + } + + return $data; +} + +1; diff --git a/perllib/FixMyStreet/Integrations/ExorRDI.pm b/perllib/FixMyStreet/Integrations/ExorRDI.pm index dc865e1ad..ce59df9be 100644 --- a/perllib/FixMyStreet/Integrations/ExorRDI.pm +++ b/perllib/FixMyStreet/Integrations/ExorRDI.pm @@ -113,9 +113,9 @@ sub construct { my $location = "${eastings}E ${northings}N"; $location = "[DID NOT USE MAP] $location" unless $report->used_map; - my $closest_address = $cobrand->find_closest($report, 1); + my $closest_address = $cobrand->find_closest($report); if (%$closest_address) { - $location .= " Nearest road: $closest_address->{road}." if $closest_address->{road}; + $location .= " Nearest road: $closest_address->{name}." if $closest_address->{name}; $location .= " Nearest postcode: $closest_address->{postcode}{postcode}." if $closest_address->{postcode}; } diff --git a/t/app/model/problem.t b/t/app/model/problem.t index 27f6aed66..b9bbe4682 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -514,6 +514,7 @@ foreach my $test ( { subtest $test->{ desc } => sub { my $override = { ALLOWED_COBRANDS => [ 'fixmystreet' ], + MAPIT_URL => 'http://mapit.uk/', BASE_URL => 'http://www.fixmystreet.com', }; if ( $test->{cobrand} && $test->{cobrand} =~ /hart/ ) { @@ -587,9 +588,10 @@ foreach my $test ( { }; } -subtest 'check can set mutiple emails as a single contact' => sub { +subtest 'check can set multiple emails as a single contact' => sub { my $override = { ALLOWED_COBRANDS => [ 'fixmystreet' ], + MAPIT_URL => 'http://mapit.uk/', }; my $contact = { diff --git a/t/cobrand/bromley.t b/t/cobrand/bromley.t index a92786b18..e42ab5be2 100644 --- a/t/cobrand/bromley.t +++ b/t/cobrand/bromley.t @@ -83,6 +83,7 @@ for my $test ( FixMyStreet::override_config { STAGING_FLAGS => { send_reports => 1 }, ALLOWED_COBRANDS => [ 'fixmystreet', 'bromley' ], + MAPIT_URL => 'http://mapit.uk/', }, sub { $test_data = FixMyStreet::Script::Reports::send(); }; diff --git a/t/cobrand/closest.t b/t/cobrand/closest.t index 36fe78a01..6d28bb6f1 100644 --- a/t/cobrand/closest.t +++ b/t/cobrand/closest.t @@ -72,8 +72,18 @@ FixMyStreet::override_config { $near = $c->find_closest_address_for_rss($report); ok !$near, 'no closest address for RSS if not cached'; + + my $json = $mech->get_ok_json('/ajax/closest?lat=55&lon=-1'); + is_deeply $json, {"road"=> "Constitution Hill","full_address"=>"Constitution Hill, London, SW1A"}; +}; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + BING_MAPS_API_KEY => 'test', +}, sub { + my $json = $mech->get_ok_json('/ajax/closest?lat=55.952055&lon=-3.189579'); + is_deeply $json, {"road"=> "Constitution Hill","full_address"=>"Constitution Hill, London, SW1A"}; }; -END { - done_testing(); -} +done_testing(); diff --git a/t/cobrand/oxfordshire.t b/t/cobrand/oxfordshire.t index f5abde27f..19a82742a 100644 --- a/t/cobrand/oxfordshire.t +++ b/t/cobrand/oxfordshire.t @@ -159,6 +159,7 @@ EOF subtest 'Reports are marked as inspected correctly' => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire' ], + MAPIT_URL => 'http://mapit.uk/', }, sub { my $date = DateTime->new(year => 2017, month => 5, day => 5, hour => 12); diff --git a/t/cobrand/rutland.t b/t/cobrand/rutland.t index 8943e64fc..4d3c4befd 100644 --- a/t/cobrand/rutland.t +++ b/t/cobrand/rutland.t @@ -41,6 +41,7 @@ subtest 'testing special Open311 behaviour', sub { FixMyStreet::override_config { STAGING_FLAGS => { send_reports => 1 }, ALLOWED_COBRANDS => [ 'fixmystreet', 'rutland' ], + MAPIT_URL => 'http://mapit.uk/', }, sub { $test_data = FixMyStreet::Script::Reports::send(); }; diff --git a/t/sendreport/open311.t b/t/sendreport/open311.t index 23096aaac..26764dc19 100644 --- a/t/sendreport/open311.t +++ b/t/sendreport/open311.t @@ -37,6 +37,7 @@ subtest 'testing Open311 behaviour', sub { FixMyStreet::override_config { STAGING_FLAGS => { send_reports => 1 }, ALLOWED_COBRANDS => [ 'fixmystreet' ], + MAPIT_URL => 'http://mapit.uk/', }, sub { $test_data = FixMyStreet::Script::Reports::send(); }; @@ -72,6 +73,7 @@ subtest 'test report with multiple photos only sends one', sub { FixMyStreet::override_config { STAGING_FLAGS => { send_reports => 1 }, ALLOWED_COBRANDS => [ 'fixmystreet' ], + MAPIT_URL => 'http://mapit.uk/', }, sub { $test_data = FixMyStreet::Script::Reports::send(); }; @@ -104,6 +106,7 @@ subtest 'test sending multiple photos', sub { FixMyStreet::override_config { STAGING_FLAGS => { send_reports => 1 }, ALLOWED_COBRANDS => [ 'tester' ], + MAPIT_URL => 'http://mapit.uk/', }, sub { $test_data = FixMyStreet::Script::Reports::send(); }; |