aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Somerville <matthew@mysociety.org>2011-05-25 20:55:25 +0100
committerMatthew Somerville <matthew@mysociety.org>2011-05-25 20:55:25 +0100
commit99c9095b0028e6139e2732f7405991b1d8a5cc98 (patch)
tree873e57c5a37006ecc9c332f282c34ce1054c7c00
parent498b51cc608c4fbd8bae187bf1c9849177134e58 (diff)
Integrate BingOL map package into the OSM one, thereby gaining non-JS functionality etc.
-rw-r--r--perllib/FixMyStreet/Map/BingOL.pm63
-rw-r--r--perllib/FixMyStreet/Map/OSM.pm51
-rw-r--r--templates/web/default/maps/osm.html20
-rw-r--r--web/js/map-OpenLayers.js4
-rw-r--r--web/js/map-bing-ol.js2
5 files changed, 94 insertions, 46 deletions
diff --git a/perllib/FixMyStreet/Map/BingOL.pm b/perllib/FixMyStreet/Map/BingOL.pm
index 70f9dbda1..94df6fff9 100644
--- a/perllib/FixMyStreet/Map/BingOL.pm
+++ b/perllib/FixMyStreet/Map/BingOL.pm
@@ -7,9 +7,12 @@
# Email: matthew@mysociety.org; WWW: http://www.mysociety.org/
package FixMyStreet::Map::BingOL;
+use base 'FixMyStreet::Map::OSM';
use strict;
-use mySociety::Gaze;
+
+use constant ZOOM_LEVELS => 5;
+use constant MIN_ZOOM_LEVEL => 13;
sub header_js {
return '
@@ -20,25 +23,45 @@ sub header_js {
';
}
-# display_map C PARAMS
-# PARAMS include:
-# latitude, longitude for the centre point of the map
-# CLICKABLE is set if the map is clickable
-# PINS is array of pins to show, location and colour
-sub display_map {
- my ($self, $c, %params) = @_;
-
- my $dist = mySociety::Gaze::get_radius_containing_population( $params{latitude}, $params{longitude}, 200_000 );
- my $zoom = 2;
- $zoom = 3 if $dist < 10;
-
- $c->stash->{map} = {
- %params,
- type => 'osm',
- zoom => $zoom,
- map_type => '""', # Is set by the JavaScript
- copyright => _('Map contains Ordnance Survey data &copy; Crown copyright and database right 2010. Microsoft'),
- };
+# Is set by the JavaScript
+sub map_type {
+ return '""';
+}
+
+sub copyright {
+ return _('Map contains Ordnance Survey data &copy; Crown copyright and database right 2010. Microsoft');
+}
+
+sub get_quadkey {
+ my ($x, $y, $z) = @_;
+ my $key = '';
+ for (my $i = $z; $i > 0; $i--) {
+ my $digit = 0;
+ my $mask = 1 << ($i - 1);
+ $digit++ if ($x & $mask) != 0;
+ $digit += 2 if ($y & $mask) != 0;
+ $key .= $digit;
+ }
+ return $key;
+}
+
+sub map_tiles {
+ my ($self, $x, $y, $z) = @_;
+ if ($z >= 16) {
+ return [
+ "http://a.os.openstreetmap.org/sv/$z/" . ($x-1) . "/" . ($y-1) . ".png",
+ "http://b.os.openstreetmap.org/sv/$z/$x/" . ($y-1) . ".png",
+ "http://c.os.openstreetmap.org/sv/$z/" . ($x-1) . "/$y.png",
+ "http://os.openstreetmap.org/sv/$z/$x/$y.png",
+ ];
+ } else {
+ return [
+ "http://ecn.t0.tiles.virtualearth.net/tiles/r" . get_quadkey($x-1, $y-1, $z) . ".png?g=587&productSet=mmOS",
+ "http://ecn.t1.tiles.virtualearth.net/tiles/r" . get_quadkey($x, $y-1, $z) . ".png?g=587&productSet=mmOS",
+ "http://ecn.t2.tiles.virtualearth.net/tiles/r" . get_quadkey($x-1, $y, $z) . ".png?g=587&productSet=mmOS",
+ "http://ecn.t3.tiles.virtualearth.net/tiles/r" . get_quadkey($x, $y, $z) . ".png?g=587&productSet=mmOS",
+ ];
+ }
}
1;
diff --git a/perllib/FixMyStreet/Map/OSM.pm b/perllib/FixMyStreet/Map/OSM.pm
index 194f403c9..363f4b01e 100644
--- a/perllib/FixMyStreet/Map/OSM.pm
+++ b/perllib/FixMyStreet/Map/OSM.pm
@@ -10,8 +10,12 @@ package FixMyStreet::Map::OSM;
use strict;
use Math::Trig;
+use mySociety::Gaze;
use Utils;
+use constant ZOOM_LEVELS => 5;
+use constant MIN_ZOOM_LEVEL => 13;
+
sub header_js {
return '
<script type="text/javascript" src="/jslib/OpenLayers-2.10/OpenLayers.js"></script>
@@ -24,6 +28,17 @@ sub map_type {
return 'OpenLayers.Layer.OSM.Mapnik';
}
+sub map_tiles {
+ my ($self, $x, $y, $z) = @_;
+ my $tile_url = $self->base_tile_url();
+ return [
+ "http://a.$tile_url/$z/" . ($x - 1) . "/" . ($y - 1) . ".png",
+ "http://b.$tile_url/$z/$x/" . ($y - 1) . ".png",
+ "http://c.$tile_url/$z/" . ($x - 1) . "/$y.png",
+ "http://$tile_url/$z/$x/$y.png",
+ ];
+}
+
sub base_tile_url {
return 'tile.openstreetmap.org';
}
@@ -40,40 +55,50 @@ sub copyright {
sub display_map {
my ($self, $c, %params) = @_;
+ # Adjust zoom level dependent upon population density
+ my $dist = mySociety::Gaze::get_radius_containing_population( $params{latitude}, $params{longitude}, 200_000 );
+ my $default_zoom = ZOOM_LEVELS - 3;
+ $default_zoom = ZOOM_LEVELS - 2 if $dist < 10;
+
# Map centre may be overridden in the query string
$params{latitude} = Utils::truncate_coordinate($c->req->params->{lat} + 0)
if defined $c->req->params->{lat};
$params{longitude} = Utils::truncate_coordinate($c->req->params->{lon} + 0)
if defined $c->req->params->{lon};
- my $zoom = defined $c->req->params->{zoom} ? $c->req->params->{zoom} + 0 : 2;
- $zoom = 3 if $zoom > 3;
+ my $zoom = defined $c->req->params->{zoom} ? $c->req->params->{zoom} + 0 : $default_zoom;
+ $zoom = ZOOM_LEVELS - 1 if $zoom >= ZOOM_LEVELS;
$zoom = 0 if $zoom < 0;
- my $zoom_act = 14 + $zoom;
+ my $zoom_act = MIN_ZOOM_LEVEL + $zoom;
my ($x_tile, $y_tile) = latlon_to_tile_with_adjust($params{latitude}, $params{longitude}, $zoom_act);
foreach my $pin (@{$params{pins}}) {
($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $x_tile, $y_tile, $zoom_act);
}
- my $compass = {
- north => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x_tile, $y_tile-1, $zoom_act ) ],
- south => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x_tile, $y_tile+1, $zoom_act ) ],
- west => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x_tile-1, $y_tile, $zoom_act ) ],
- east => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x_tile+1, $y_tile, $zoom_act ) ],
- here => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x_tile, $y_tile, $zoom_act ) ],
- };
$c->stash->{map} = {
%params,
type => 'osm',
map_type => $self->map_type(),
- tile_url => $self->base_tile_url(),
+ tiles => $self->map_tiles( $x_tile, $y_tile, $zoom_act ),
copyright => $self->copyright(),
x_tile => $x_tile,
y_tile => $y_tile,
zoom => $zoom,
zoom_act => $zoom_act,
- compass => $compass,
+ zoom_levels => ZOOM_LEVELS,
+ compass => compass( $x_tile, $y_tile, $zoom_act ),
+ };
+}
+
+sub compass {
+ my ( $x, $y, $z ) = @_;
+ return {
+ north => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x, $y-1, $z ) ],
+ south => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x, $y+1, $z ) ],
+ west => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x-1, $y, $z ) ],
+ east => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x+1, $y, $z ) ],
+ here => [ map { Utils::truncate_coordinate($_) } tile_to_latlon( $x, $y, $z ) ],
};
}
@@ -141,7 +166,7 @@ sub click_to_wgs84 {
my ($self, $c, $pin_tile_x, $pin_x, $pin_tile_y, $pin_y) = @_;
my $tile_x = click_to_tile($pin_tile_x, $pin_x);
my $tile_y = click_to_tile($pin_tile_y, $pin_y);
- my $zoom = 14 + (defined $c->req->params->{zoom} ? $c->req->params->{zoom} : 2);
+ my $zoom = MIN_ZOOM_LEVEL + (defined $c->req->params->{zoom} ? $c->req->params->{zoom} : 2);
my ($lat, $lon) = tile_to_latlon($tile_x, $tile_y, $zoom);
return ( $lat, $lon );
}
diff --git a/templates/web/default/maps/osm.html b/templates/web/default/maps/osm.html
index a3e6ea27d..ae670ce13 100644
--- a/templates/web/default/maps/osm.html
+++ b/templates/web/default/maps/osm.html
@@ -12,8 +12,8 @@ var fixmystreet = {
[% IF map.zoom -%]
'zoom': [% map.zoom %],
[%- END %]
- 'pins': [% INCLUDE maps/pins_js.html %],
- 'map_type': [% map.map_type %]
+ 'map_type': [% map.map_type %],
+ 'pins': [% INCLUDE maps/pins_js.html %]
}
</script>
<div id="map_box">
@@ -22,19 +22,19 @@ var fixmystreet = {
<div id="drag"><[% map.img_type %]
alt="NW map tile" id="t2.2"
name="tile_[% map.x_tile - 1 %].[% map.y_tile - 1 %]"
- src="http://a.[% map.tile_url %]/[% map.zoom_act %]/[% map.x_tile - 1 %]/[% map.y_tile - 1 %].png"
+ src="[% map.tiles.0 %]"
style="top:0; left:0;"><[% map.img_type %]
alt="NE map tile" id="t2.3"
name="tile_[% map.x_tile %].[% map.y_tile - 1 %]"
- src="http://b.[% map.tile_url %]/[% map.zoom_act %]/[% map.x_tile %]/[% map.y_tile - 1 %].png"
+ src="[% map.tiles.1 %]"
style="top:0px; left:256px;"><br><[% map.img_type %]
alt="SW map tile" id="t3.2"
name="tile_[% map.x_tile - 1 %].[% map.y_tile %]"
- src="http://c.[% map.tile_url %]/[% map.zoom_act %]/[% map.x_tile - 1 %]/[% map.y_tile %].png"
+ src="[% map.tiles.2 %]"
style="top:256px; left:0;"><[% map.img_type %]
alt="SE map tile" id="t3.3"
name="tile_[% map.x_tile %].[% map.y_tile %]"
- src="http://[% map.tile_url %]/[% map.zoom_act %]/[% map.x_tile %]/[% map.y_tile %].png"
+ src="[% map.tiles.3 %]"
style="top:256px; left:256px;"></div>
<div id="pins">[% FOR pin IN map.pins %][% INCLUDE pin %][% END %]</div>
[% INCLUDE compass %]
@@ -51,10 +51,10 @@ var fixmystreet = {
east = c.uri_with( { lat = map.compass.east.0, lon = map.compass.east.1, zoom = map.zoom } )
west = c.uri_with( { lat = map.compass.west.0, lon = map.compass.west.1, zoom = map.zoom } )
world = c.uri_with( { zoom = 0 } );
- zoom_in = c.uri_with( { zoom = map.zoom + 1 } ) IF map.zoom < 3;
- zoom_out = c.uri_with( { zoom = map.zoom - 1 } ) IF map.zoom > 0;
- zoom_in = '#' IF map.zoom >= 3;
- zoom_out = '#' IF map.zoom <= 0
+ SET zoom_in = c.uri_with( { zoom = map.zoom + 1 } ) IF map.zoom < map.zoom_levels - 1;
+ SET zoom_out = c.uri_with( { zoom = map.zoom - 1 } ) IF map.zoom > 0;
+ SET zoom_in = '#' IF map.zoom >= map.zoom_levels - 1;
+ SET zoom_out = '#' IF map.zoom <= 0;
%]
<div style="position: absolute; left: 4px; top: 4px; z-index: 1007;" class="olControlPanZoom olControlNoSelect" unselectable="on">
<div style="position: absolute; left: 13px; top: 4px; width: 18px; height: 18px;"><a href="[% north %]"><img style="position: relative; width: 18px; height: 18px;" src="/jslib/OpenLayers-2.10/img/north-mini.png" border="0"></a></div>
diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js
index ed3ca4653..d912b4b5f 100644
--- a/web/js/map-OpenLayers.js
+++ b/web/js/map-OpenLayers.js
@@ -1,6 +1,6 @@
YAHOO.util.Event.onContentReady('map', function() {
- fixmystreet.ZOOM_OFFSET = 14;
+ fixmystreet.ZOOM_OFFSET = 13;
var perm = new OpenLayers.Control.Permalink();
set_map_config(perm);
@@ -13,7 +13,7 @@ YAHOO.util.Event.onContentReady('map', function() {
fixmystreet.layer_options = OpenLayers.Util.extend({
zoomOffset: fixmystreet.ZOOM_OFFSET,
transitionEffect: 'resize',
- numZoomLevels: 4
+ numZoomLevels: 5
}, fixmystreet.layer_options);
var layer = new fixmystreet.map_type("", fixmystreet.layer_options);
fixmystreet.map.addLayer(layer);
diff --git a/web/js/map-bing-ol.js b/web/js/map-bing-ol.js
index 254d407f4..00c3a487f 100644
--- a/web/js/map-bing-ol.js
+++ b/web/js/map-bing-ol.js
@@ -51,7 +51,7 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
OpenLayers.Util.indexOf(this.serverResolutions, res) :
this.map.getZoom() + this.zoomOffset;
- if (z == 16) {
+ if (z >= 16) {
var url = [
"http://a.os.openstreetmap.org/sv/${z}/${x}/${y}.png",
"http://b.os.openstreetmap.org/sv/${z}/${x}/${y}.png",