diff options
Diffstat (limited to 'perllib')
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Buckinghamshire.pm | 95 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Lincolnshire.pm | 123 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/UKCouncils.pm | 98 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Problem.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/Map/Lincolnshire.pm | 21 | ||||
-rw-r--r-- | perllib/Open311/GetServiceRequests.pm | 2 |
6 files changed, 258 insertions, 83 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/Lincolnshire.pm b/perllib/FixMyStreet/Cobrand/Lincolnshire.pm new file mode 100644 index 000000000..431314333 --- /dev/null +++ b/perllib/FixMyStreet/Cobrand/Lincolnshire.pm @@ -0,0 +1,123 @@ +package FixMyStreet::Cobrand::Lincolnshire; +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 2232; } +sub council_area { return 'Lincolnshire'; } +sub council_name { return 'Lincolnshire County Council'; } +sub council_url { return 'lincolnshire'; } +sub is_two_tier { 1 } + +sub enable_category_groups { 1 } +sub send_questionnaires { 0 } +sub report_sent_confirmation_email { 1 } + +sub admin_user_domain { 'lincolnshire.gov.uk' } + +sub enter_postcode_text { + my ($self) = @_; + return 'Enter a Lincolnshire postcode, street name and area, or check an existing report number'; +} + + +sub base_url { + my $self = shift; + return $self->next::method() if FixMyStreet->config('STAGING_SITE'); + return 'https://fixmystreet.lincolnshire.gov.uk'; +} + +sub contact_email { + my $self = shift; + return join( '@', 'confirm_support', 'lincolnshire.gov.uk' ); +} + + +sub example_places { + return ( 'LN1 1YL', 'Orchard Street, Lincoln' ); +} + +sub disambiguate_location { + my $self = shift; + my $string = shift; + return { + %{ $self->SUPER::disambiguate_location() }, + town => 'Lincolnshire', + centre => '53.1128371079972,-0.237920757894981', + span => '0.976148231905086,1.17860658530345', + bounds => [ 52.6402179235688, -0.820651304784901, 53.6163661554738, 0.357955280518546 ], + }; +} + + +sub open311_config { + my ($self, $row, $h, $params) = @_; + + my $extra = $row->get_extra_fields; + push @$extra, + { name => 'report_url', + value => $h->{url} }, + { name => 'title', + value => $row->title }, + { name => 'description', + value => $row->detail }; + + # Reports made via FMS.com or the app probably won't have a site code + # value 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. + if (!$row->get_extra_field_value('site_code')) { + if (my $site_code = $self->lookup_site_code($row)) { + push @$extra, + { name => 'site_code', + value => $site_code }; + } + } + + $row->set_extra_fields(@$extra); +} + +sub lookup_site_code_config { { + buffer => 200, # metres + url => "https://tilma.mysociety.org/mapserver/lincs", + srsname => "urn:ogc:def:crs:EPSG::27700", + typename => "NSG", + property => "Site_Code", + accept_feature => sub { 1 } +} } + + +sub categories_restriction { + my ($self, $rs) = @_; + # Lincolnshire is a two-tier council, but don't want to display + # all district-level categories on their cobrand - just a couple. + return $rs->search( { -or => [ + 'body.name' => "Lincolnshire County Council", + + # District categories: + 'me.category' => { -in => [ + 'Street nameplates', + 'Bench/cycle rack/litter bin/planter', + ] }, + ] } ); +} + +sub map_type { 'Lincolnshire' } + +sub pin_colour { + my ( $self, $p, $context ) = @_; + my $ext_status = $p->get_extra_metadata('external_status_code'); + return 'yellow' if $p->state eq 'confirmed' && $ext_status && $ext_status eq '0135'; + return 'red' if $p->state eq 'confirmed'; + return 'green' if $p->is_fixed || $p->is_closed; + return 'grey' if $p->state eq 'not responsible' || !$self->owns_problem( $p ); + return 'yellow'; +} + +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; diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index f2d221fa4..76a6f72fb 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -759,7 +759,7 @@ sub defect_types { # Note: this only makes sense when called on a problem that has been sent! sub can_display_external_id { my $self = shift; - if ($self->external_id && $self->send_method_used && $self->to_body_named('Oxfordshire|Angus')) { + if ($self->external_id && $self->send_method_used && $self->to_body_named('Oxfordshire|Lincolnshire')) { return 1; } return 0; diff --git a/perllib/FixMyStreet/Map/Lincolnshire.pm b/perllib/FixMyStreet/Map/Lincolnshire.pm new file mode 100644 index 000000000..7dbfe5d8e --- /dev/null +++ b/perllib/FixMyStreet/Map/Lincolnshire.pm @@ -0,0 +1,21 @@ +# FixMyStreet:Map::Lincolnshire +# More JavaScript, for street assets + +package FixMyStreet::Map::Lincolnshire; +use base 'FixMyStreet::Map::FMS'; + +use strict; + +sub map_javascript { [ + '/vendor/OpenLayers/OpenLayers.wfs.js', + '/vendor/OpenLayers.Projection.OrdnanceSurvey.js', + '/js/map-OpenLayers.js', + '/js/map-bing-ol.js', + '/js/map-fms.js', + '/cobrands/fixmystreet-uk-councils/roadworks.js', + '/cobrands/fixmystreet/assets.js', + '/cobrands/lincolnshire/roadworks.js', + '/cobrands/lincolnshire/assets.js', +] } + +1; diff --git a/perllib/Open311/GetServiceRequests.pm b/perllib/Open311/GetServiceRequests.pm index 2d15347fd..2d20c6246 100644 --- a/perllib/Open311/GetServiceRequests.pm +++ b/perllib/Open311/GetServiceRequests.pm @@ -158,7 +158,7 @@ sub create_problems { { user => $self->system_user, external_id => $request_id, - detail => $request->{description}, + detail => $request->{description} || $request->{service_name} . ' problem', title => $request->{title} || $request->{service_name} . ' problem', anonymous => 0, name => $self->system_user->name, |