aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm11
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm79
-rw-r--r--perllib/FixMyStreet/Map.pm5
-rw-r--r--perllib/FixMyStreet/Map/OSM.pm31
4 files changed, 113 insertions, 13 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm
index 89df4a52d..6ac3c8ea1 100644
--- a/perllib/FixMyStreet/App/Controller/Report.pm
+++ b/perllib/FixMyStreet/App/Controller/Report.pm
@@ -278,6 +278,17 @@ sub delete :Local :Args(1) {
return $c->res->redirect($uri);
}
+sub map : Path('') : Args(2) {
+ my ( $self, $c, $id, $map ) = @_;
+
+ $c->detach( '/page_error_404_not_found', [] ) unless $map eq 'map';
+ $c->forward( 'load_problem_or_display_error', [ $id ] );
+
+ my $image = $c->stash->{problem}->static_map;
+ $c->res->content_type($image->{content_type});
+ $c->res->body($image->{data});
+}
+
__PACKAGE__->meta->make_immutable;
1;
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index 1ae719361..92865ace9 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -161,6 +161,13 @@ use Moo;
use namespace::clean -except => [ 'meta' ];
use Utils;
use FixMyStreet::Map::FMS;
+use LWP::Simple qw($ua);
+
+my $IM = eval {
+ require Image::Magick;
+ Image::Magick->import;
+ 1;
+};
with 'FixMyStreet::Roles::Abuser',
'FixMyStreet::Roles::Extra',
@@ -654,7 +661,7 @@ sub can_display_external_id {
if ($self->external_id && $self->send_method_used && $self->bodies_str =~ /(2237|2550)/) {
return 1;
}
- return 0;
+ return 0;
}
sub duration_string {
@@ -836,7 +843,7 @@ __PACKAGE__->has_many(
"admin_log_entries",
"FixMyStreet::DB::Result::AdminLog",
{ "foreign.object_id" => "self.id" },
- {
+ {
cascade_copy => 0, cascade_delete => 0,
where => { 'object_type' => 'problem' },
}
@@ -873,6 +880,7 @@ has get_cobrand_logged => (
},
);
+
sub pin_data {
my ($self, $c, $page, %opts) = @_;
my $colour = $c->cobrand->pin_colour($self, $page);
@@ -885,6 +893,73 @@ sub pin_data {
title => $opts{private} ? $self->title : $self->title_safe,
problem => $self,
}
+};
+
+sub static_map {
+ my ($self) = @_;
+
+ return unless $IM;
+
+ my $orig_map_class = FixMyStreet::Map::set_map_class('OSM')
+ unless $FixMyStreet::Map::map_class->isa("FixMyStreet::Map::OSM");
+
+ my $map_data = $FixMyStreet::Map::map_class->generate_map_data(
+ { cobrand => $self->get_cobrand_logged },
+ latitude => $self->latitude,
+ longitude => $self->longitude,
+ pins => $self->used_map
+ ? [ {
+ latitude => $self->latitude,
+ longitude => $self->longitude,
+ colour => $self->get_cobrand_logged->pin_colour($self, 'report'),
+ type => 'big',
+ } ]
+ : [],
+ );
+
+ $ua->agent("FixMyStreet/1.0");
+ my $image;
+ for (my $i=0; $i<4; $i++) {
+ my $tile_url = $map_data->{tiles}->[$i];
+ if ($tile_url =~ m{^//}) {
+ $tile_url = "https:$tile_url";
+ }
+ my $tile = LWP::Simple::get($tile_url);
+ my $im = Image::Magick->new;
+ $im->BlobToImage($tile);
+ if (!$image) {
+ $image = $im;
+ $image->Extent(geometry => '512x512', gravity => 'NorthWest');
+ } else {
+ my $gravity = ($i<2?'North':'South') . ($i%2?'East':'West');
+ $image->Composite(image => $im, gravity => $gravity);
+ }
+ }
+
+ # The only pin might be the report pin, with added x/y
+ my $pin = $map_data->{pins}->[0];
+ if ($pin) {
+ my $im = Image::Magick->new;
+ $im->read(FixMyStreet->path_to('web', 'i', 'pin-yellow.png'));
+ $image->Composite(image => $im, gravity => 'NorthWest',
+ x => $pin->{px} - 24, y => $pin->{py} - 64);
+ }
+
+ # Bottom 128/ top 64 pixels will never have a pin
+ $image->Extent( geometry => '512x384', gravity => 'NorthWest');
+ $image->Extent( geometry => '512x320', gravity => 'SouthWest');
+
+ $image->Scale( geometry => "310x200>" );
+
+ my @blobs = $image->ImageToBlob(magick => 'jpeg');
+ undef $image;
+
+ FixMyStreet::Map::set_map_class($orig_map_class) if $orig_map_class;
+
+ return {
+ data => $blobs[0],
+ content_type => 'image/jpeg',
+ };
}
1;
diff --git a/perllib/FixMyStreet/Map.pm b/perllib/FixMyStreet/Map.pm
index 355fd8666..a850492b9 100644
--- a/perllib/FixMyStreet/Map.pm
+++ b/perllib/FixMyStreet/Map.pm
@@ -47,7 +47,8 @@ sub reload_allowed_maps {
=head2 map_class
-Set and return the appropriate class given a query parameter string.
+Sets the appropriate class given a query parameter string.
+Returns the old map class, if any.
=cut
@@ -57,7 +58,9 @@ sub set_map_class {
$str = __PACKAGE__.'::'.$str if $str;
my %avail = map { $_ => 1 } @ALL_MAP_CLASSES;
$str = $ALL_MAP_CLASSES[0] unless $str && $avail{$str};
+ my $old_map_class = $map_class;
$map_class = $str;
+ return $old_map_class;
}
sub display_map {
diff --git a/perllib/FixMyStreet/Map/OSM.pm b/perllib/FixMyStreet/Map/OSM.pm
index ae9e73a0a..d4000f1a4 100644
--- a/perllib/FixMyStreet/Map/OSM.pm
+++ b/perllib/FixMyStreet/Map/OSM.pm
@@ -50,6 +50,23 @@ sub copyright {
sub display_map {
my ($self, $c, %params) = @_;
+ # Map centre may be overridden in the query string
+ $params{latitude} = Utils::truncate_coordinate($c->get_param('lat') + 0)
+ if defined $c->get_param('lat');
+ $params{longitude} = Utils::truncate_coordinate($c->get_param('lon') + 0)
+ if defined $c->get_param('lon');
+
+ my %data;
+ $data{cobrand} = $c->cobrand;
+ $data{distance} = $c->stash->{distance};
+ $data{zoom} = $c->get_param('zoom') + 0 if defined $c->get_param('zoom');
+
+ $c->stash->{map} = $self->generate_map_data(\%data, %params);
+}
+
+sub generate_map_data {
+ my ($self, $data, %params) = @_;
+
my $numZoomLevels = ZOOM_LEVELS;
my $zoomOffset = MIN_ZOOM_LEVEL;
if ($params{any_zoom}) {
@@ -58,18 +75,12 @@ sub display_map {
}
# Adjust zoom level dependent upon population density
- my $dist = $c->stash->{distance}
+ my $dist = $data->{distance}
|| FixMyStreet::Gaze::get_radius_containing_population( $params{latitude}, $params{longitude} );
- my $default_zoom = $c->cobrand->default_map_zoom() ? $c->cobrand->default_map_zoom() : $numZoomLevels - 4;
+ my $default_zoom = $data->{cobrand}->default_map_zoom() || ($numZoomLevels - 4);
$default_zoom = $numZoomLevels - 3 if $dist < 10;
- # Map centre may be overridden in the query string
- $params{latitude} = Utils::truncate_coordinate($c->get_param('lat') + 0)
- if defined $c->get_param('lat');
- $params{longitude} = Utils::truncate_coordinate($c->get_param('lon') + 0)
- if defined $c->get_param('lon');
-
- my $zoom = defined $c->get_param('zoom') ? $c->get_param('zoom') + 0 : $default_zoom;
+ my $zoom = $data->{zoom} || $default_zoom;
$zoom = $numZoomLevels - 1 if $zoom >= $numZoomLevels;
$zoom = 0 if $zoom < 0;
$params{zoom_act} = $zoomOffset + $zoom;
@@ -79,7 +90,7 @@ sub display_map {
($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $params{x_tile}, $params{y_tile}, $params{zoom_act});
}
- $c->stash->{map} = {
+ return {
%params,
type => $self->map_template(),
map_type => $self->map_type(),