aboutsummaryrefslogtreecommitdiffstats
path: root/perllib
diff options
context:
space:
mode:
authorDave Arter <davea@mysociety.org>2018-06-14 16:55:07 +0100
committerDave Arter <davea@mysociety.org>2018-08-17 09:43:09 +0100
commitd0dd45e0280e33ffe018e579ab3d3605302a2a76 (patch)
tree32c118aa3d70675ba7294dee43424ca04d701818 /perllib
parent95b854b4ea5c42b9f527b2f161d25175347ea3c9 (diff)
[Buckinghamshire] Factor lookup_site_code up into UKCouncils cobrand
Diffstat (limited to 'perllib')
-rw-r--r--perllib/FixMyStreet/Cobrand/Buckinghamshire.pm95
-rw-r--r--perllib/FixMyStreet/Cobrand/UKCouncils.pm98
2 files changed, 112 insertions, 81 deletions
diff --git a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm
index f02ee9e51..783a565f1 100644
--- a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm
+++ b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm
@@ -4,11 +4,6 @@ use parent 'FixMyStreet::Cobrand::UKCouncils';
use strict;
use warnings;
-use LWP::Simple;
-use URI;
-use Try::Tiny;
-use JSON::MaybeXS;
-
sub council_area_id { return 2217; }
sub council_area { return 'Buckinghamshire'; }
sub council_name { return 'Buckinghamshire County Council'; }
@@ -336,85 +331,23 @@ sub categories_restriction {
return $rs->search( [ { 'body_areas.area_id' => 2217 }, { category => 'Flytipping' } ], { join => { body => 'body_areas' } });
}
-sub lookup_site_code {
- my $self = shift;
- my $row = shift;
- my $buffer = shift || 200; # metres
-
- my ($x, $y) = $row->local_coords;
- my ($w, $s, $e, $n) = ($x-$buffer, $y-$buffer, $x+$buffer, $y+$buffer);
-
- my $uri = URI->new("https://tilma.mysociety.org/mapserver/bucks");
- $uri->query_form(
- REQUEST => "GetFeature",
- SERVICE => "WFS",
- SRSNAME => "urn:ogc:def:crs:EPSG::27700",
- TYPENAME => "Whole_Street",
- VERSION => "1.1.0",
- outputformat => "geojson",
- BBOX => "$w,$s,$e,$n"
- );
-
- my $response = get($uri);
-
- my $j = JSON->new->utf8->allow_nonref;
- try {
- $j = $j->decode($response);
- } catch {
- # There was either no asset found, or an error with the WFS
- # call - in either case let's just proceed without the USRN.
- return '';
- };
-
- # We have a list of features, and we want to find the one closest to the
- # report location.
- my $site_code = '';
- my $nearest;
-
- # There are only certain features we care about, the rest can be ignored.
- my @valid_types = ( "2", "3A", "3B", "4A", "4B", "HE", "HWOA", "HWSA", "P" );
- my %valid_types = map { $_ => 1 } @valid_types;
-
- for my $feature ( @{ $j->{features} } ) {
+sub lookup_site_code_config { {
+ buffer => 200, # metres
+ url => "https://tilma.mysociety.org/mapserver/bucks",
+ srsname => "urn:ogc:def:crs:EPSG::27700",
+ typename => "Whole_Street",
+ property => "site_code",
+ accept_feature => sub {
+ my $feature = shift;
+
+ # There are only certain features we care about, the rest can be ignored.
+ my @valid_types = ( "2", "3A", "3B", "4A", "4B", "HE", "HWOA", "HWSA", "P" );
+ my %valid_types = map { $_ => 1 } @valid_types;
my $type = $feature->{properties}->{feature_ty};
- next unless $valid_types{$type};
-
- # We shouldn't receive anything aside from these two geometry types, but belt and braces.
- next unless $feature->{geometry}->{type} eq 'MultiLineString' || $feature->{geometry}->{type} eq 'LineString';
- my @coordinates = @{ $feature->{geometry}->{coordinates} };
- if ( $feature->{geometry}->{type} eq 'MultiLineString') {
- # The coordinates are stored as a list of lists, so flatten 'em out
- @coordinates = map { @{ $_ } } @coordinates;
- }
-
- # If any of this feature's points are closer than those we've seen so
- # far then use the site_code from this feature.
- for my $coords ( @coordinates ) {
- my ($fx, $fy) = @$coords;
- my $distance = $self->_distance($x, $y, $fx, $fy);
- if ( !defined $nearest || $distance < $nearest ) {
- $site_code = $feature->{properties}->{site_code};
- $nearest = $distance;
- }
- }
+ return $valid_types{$type};
}
+} }
- return $site_code;
-}
-
-
-=head2 _distance
-
-Returns the cartesian distance between two coordinates.
-This is not a general-purpose distance function, it's intended for use with
-fairly nearby coordinates in EPSG:27700 where a spheroid doesn't need to be
-taken into account.
-
-=cut
-sub _distance {
- my ($self, $ax, $ay, $bx, $by) = @_;
- return sqrt( (($ax - $bx) ** 2) + (($ay - $by) ** 2) );
-}
1;
diff --git a/perllib/FixMyStreet/Cobrand/UKCouncils.pm b/perllib/FixMyStreet/Cobrand/UKCouncils.pm
index 25f809d8c..72f6ff89e 100644
--- a/perllib/FixMyStreet/Cobrand/UKCouncils.pm
+++ b/perllib/FixMyStreet/Cobrand/UKCouncils.pm
@@ -6,6 +6,10 @@ use warnings;
use Carp;
use URI::Escape;
+use LWP::Simple;
+use URI;
+use Try::Tiny;
+use JSON::MaybeXS;
sub is_council {
1;
@@ -222,4 +226,98 @@ sub prefill_report_fields_for_inspector { 1 }
sub social_auth_disabled { 1 }
+=head2 lookup_site_code
+
+Reports made via FMS.com or the app probably won't have a site code
+value (required for Confirm integrations) because we don't display
+the adopted highways layer on those frontends.
+Instead we'll look up the closest asset from the WFS
+service at the point we're sending the report over Open311.
+
+NB this requires the cobrand to implement `lookup_site_code_config` -
+see Buckinghamshire or Lincolnshire for an example.
+
+
+=cut
+
+sub lookup_site_code {
+ my $self = shift;
+ my $row = shift;
+ my $buffer = shift;
+
+ my $cfg = $self->lookup_site_code_config;
+
+ $buffer ||= $cfg->{buffer}; # metres
+ my ($x, $y) = $row->local_coords;
+ my ($w, $s, $e, $n) = ($x-$buffer, $y-$buffer, $x+$buffer, $y+$buffer);
+
+ my $uri = URI->new($cfg->{url});
+ $uri->query_form(
+ REQUEST => "GetFeature",
+ SERVICE => "WFS",
+ SRSNAME => $cfg->{srsname},
+ TYPENAME => $cfg->{typename},
+ VERSION => "1.1.0",
+ outputformat => "geojson",
+ BBOX => "$w,$s,$e,$n"
+ );
+
+ my $response = get($uri);
+
+ my $j = JSON->new->utf8->allow_nonref;
+ try {
+ $j = $j->decode($response);
+ } catch {
+ # There was either no asset found, or an error with the WFS
+ # call - in either case let's just proceed without the USRN.
+ return '';
+ };
+
+ # We have a list of features, and we want to find the one closest to the
+ # report location.
+ my $site_code = '';
+ my $nearest;
+
+ for my $feature ( @{ $j->{features} } ) {
+ next unless $cfg->{accept_feature}($feature);
+
+ # We shouldn't receive anything aside from these two geometry types, but belt and braces.
+ next unless $feature->{geometry}->{type} eq 'MultiLineString' || $feature->{geometry}->{type} eq 'LineString';
+
+ my @coordinates = @{ $feature->{geometry}->{coordinates} };
+ if ( $feature->{geometry}->{type} eq 'MultiLineString') {
+ # The coordinates are stored as a list of lists, so flatten 'em out
+ @coordinates = map { @{ $_ } } @coordinates;
+ }
+
+ # If any of this feature's points are closer than those we've seen so
+ # far then use the site_code from this feature.
+ for my $coords ( @coordinates ) {
+ my ($fx, $fy) = @$coords;
+ my $distance = $self->_distance($x, $y, $fx, $fy);
+ if ( !defined $nearest || $distance < $nearest ) {
+ $site_code = $feature->{properties}->{$cfg->{property}};
+ $nearest = $distance;
+ }
+ }
+ }
+
+ return $site_code;
+}
+
+
+=head2 _distance
+
+Returns the cartesian distance between two coordinates.
+This is not a general-purpose distance function, it's intended for use with
+fairly nearby coordinates in EPSG:27700 where a spheroid doesn't need to be
+taken into account.
+
+=cut
+sub _distance {
+ my ($self, $ax, $ay, $bx, $by) = @_;
+ return sqrt( (($ax - $bx) ** 2) + (($ay - $by) ** 2) );
+}
+
+
1;