diff options
Diffstat (limited to 'perllib/FixMyStreet/Map.pm')
-rw-r--r-- | perllib/FixMyStreet/Map.pm | 168 |
1 files changed, 99 insertions, 69 deletions
diff --git a/perllib/FixMyStreet/Map.pm b/perllib/FixMyStreet/Map.pm index 12ecf78fe..5305b360a 100644 --- a/perllib/FixMyStreet/Map.pm +++ b/perllib/FixMyStreet/Map.pm @@ -10,105 +10,135 @@ package FixMyStreet::Map; use strict; +use Module::Pluggable + sub_name => 'maps', + search_path => __PACKAGE__, + except => 'FixMyStreet::Map::Tilma::Original', + require => 1; + +# Get the list of maps we want and load map classes at compile time +my @ALL_MAP_CLASSES = allowed_maps(); + use Problems; use Cobrand; use mySociety::Config; use mySociety::Gaze; -use mySociety::GeoUtil; use mySociety::Locale; -use mySociety::Web qw(ent NewURL); +use mySociety::Web qw(ent); + +=head2 allowed_maps + +Returns an array of all the map classes that were found and that +are permitted by the config. + +=cut + +sub allowed_maps { + my @allowed = split /,/, mySociety::Config::get('MAP_TYPE'); + @allowed = map { __PACKAGE__.'::'.$_ } @allowed; + my %avail = map { $_ => 1 } __PACKAGE__->maps; + return grep { $avail{$_} } @allowed; +} + +=head2 map_class + +Set and return the appropriate class given a query parameter string. + +=cut + +our $map_class; +sub set_map_class { + my $str = shift; + $str = __PACKAGE__.'::'.$str if $str; + my %avail = map { $_ => 1 } @ALL_MAP_CLASSES; + $str = $ALL_MAP_CLASSES[0] unless $str && $avail{$str}; + $map_class = $str; +} + +sub header_js { + return $map_class->header_js(@_); +} -# Run on module boot up -load(); +sub display_map { + return $map_class->display_map(@_); +} -# This is yucky, but no-one's taught me a better way -sub load { - my $type = mySociety::Config::get('MAP_TYPE'); - my $class = "FixMyStreet::Map::$type"; - eval "use $class"; +sub display_map_end { + my ($type) = @_; + my $out = '</div>'; + $out .= '</form>' if ($type); + return $out; } 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; - my $pc = $q->param('pc') || ''; - my $pc_enc = ent($pc); + $encoding = ' enctype="multipart/form-data"' if $type == 2; + my $pc = ent($q->param('pc') || ''); + my $map = ent($q->param('map') || ''); return <<EOF; <form action="$form_action" method="post" name="mapForm" id="mapForm"$encoding> <input type="hidden" name="submit_map" value="1"> -<input type="hidden" name="pc" value="$pc_enc"> +<input type="hidden" name="map" value="$map"> +<input type="hidden" name="pc" value="$pc"> $cobrand_form_elements EOF } 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 @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); - } - } - my $recentre = NewURL($q); - my $host = Page::base_url_with_lang($q, undef); - return <<EOF; -<table cellpadding="0" cellspacing="0" border="0" id="compass"> -<tr valign="bottom"> -<td align="right"><a rel="nofollow" href="${compass[$x-1][$y+1]}"><img src="$host/i/arrow-northwest.gif" alt="NW" width=11 height=11></a></td> -<td align="center"><a rel="nofollow" href="${compass[$x][$y+1]}"><img src="$host/i/arrow-north.gif" vspace="3" alt="N" width=13 height=11></a></td> -<td><a rel="nofollow" href="${compass[$x+1][$y+1]}"><img src="$host/i/arrow-northeast.gif" alt="NE" width=11 height=11></a></td> -</tr> -<tr> -<td><a rel="nofollow" href="${compass[$x-1][$y]}"><img src="$host/i/arrow-west.gif" hspace="3" alt="W" width=11 height=13></a></td> -<td align="center"><a rel="nofollow" href="$recentre"><img src="$host/i/rose.gif" alt="Recentre" width=35 height=34></a></td> -<td><a rel="nofollow" href="${compass[$x+1][$y]}"><img src="$host/i/arrow-east.gif" hspace="3" alt="E" width=11 height=13></a></td> -</tr> -<tr valign="top"> -<td align="right"><a rel="nofollow" href="${compass[$x-1][$y-1]}"><img src="$host/i/arrow-southwest.gif" alt="SW" width=11 height=11></a></td> -<td align="center"><a rel="nofollow" href="${compass[$x][$y-1]}"><img src="$host/i/arrow-south.gif" vspace="3" alt="S" width=13 height=11></a></td> -<td><a rel="nofollow" href="${compass[$x+1][$y-1]}"><img src="$host/i/arrow-southeast.gif" alt="SE" width=11 height=11></a></td> -</tr> -</table> -EOF +sub map_pins { + return $map_class->map_pins(@_); +} + +sub click_to_wgs84 { + return $map_class->click_to_wgs84(@_); +} + +sub tile_xy_to_wgs84 { + return $map_class->tile_xy_to_wgs84(@_); } 1; |