diff options
-rw-r--r-- | perllib/FixMyStreet/Cobrand/CheshireEast.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/Map/CheshireEast.pm | 70 | ||||
-rw-r--r-- | perllib/FixMyStreet/Map/OSM.pm | 40 | ||||
-rw-r--r-- | t/map/cheshireeast.t | 18 | ||||
-rw-r--r-- | t/map/tests.t | 1 | ||||
-rw-r--r-- | templates/web/cheshireeast/report/new/_form_labels.html | 4 | ||||
-rw-r--r-- | templates/web/cheshireeast/report/new/roads_message.html | 6 | ||||
-rw-r--r-- | web/cobrands/cheshireeast/assets.js | 29 | ||||
-rw-r--r-- | web/js/map-OpenLayers.js | 12 | ||||
-rw-r--r-- | web/js/map-cheshireeast.js | 33 | ||||
-rw-r--r-- | web/js/map-wmts-bristol.js | 12 | ||||
-rw-r--r-- | web/js/map-wmts-buckinghamshire.js | 12 | ||||
-rw-r--r-- | web/js/map-wmts-hounslow.js | 12 | ||||
-rw-r--r-- | web/js/map-wmts-isleofwight.js | 23 | ||||
-rw-r--r-- | web/js/map-wmts-zurich.js | 12 |
15 files changed, 183 insertions, 105 deletions
diff --git a/perllib/FixMyStreet/Cobrand/CheshireEast.pm b/perllib/FixMyStreet/Cobrand/CheshireEast.pm index a2c6c1c19..3ac81ab95 100644 --- a/perllib/FixMyStreet/Cobrand/CheshireEast.pm +++ b/perllib/FixMyStreet/Cobrand/CheshireEast.pm @@ -32,7 +32,7 @@ sub disambiguate_location { } sub enter_postcode_text { - 'Enter a postcode or street name and area in Cheshire East'; + 'Enter a postcode, or a road and place name'; } sub admin_user_domain { 'cheshireeast.gov.uk' } @@ -46,6 +46,8 @@ sub geocoder_munge_results { $result->{display_name} =~ s/, Cheshire East, North West England, England//; } +sub map_type { 'CheshireEast' } + sub default_map_zoom { 3 } sub on_map_default_status { 'open' } diff --git a/perllib/FixMyStreet/Map/CheshireEast.pm b/perllib/FixMyStreet/Map/CheshireEast.pm new file mode 100644 index 000000000..4e59f2593 --- /dev/null +++ b/perllib/FixMyStreet/Map/CheshireEast.pm @@ -0,0 +1,70 @@ +package FixMyStreet::Map::CheshireEast; +use base 'FixMyStreet::Map::OSM'; + +use strict; +use Utils; + +use constant MIN_ZOOM_LEVEL => 7; + +sub map_javascript { [ + '/vendor/OpenLayers/OpenLayers.wfs.js', + '/js/map-OpenLayers.js', + '/js/map-cheshireeast.js', +] } + +sub tile_parameters { { + origin_x => -3276800, + origin_y => 3276800, +} } + +sub resolutions { ( + 1792.003584007169, + 896.0017920035843, + 448.0008960017922, + 224.0004480008961, + 112.000224000448, + 56.000112000224014, + 28.000056000111993, + 14.000028000056004, + 7.000014000028002, + 2.8000056000112004, + 1.4000028000056002, + 0.7000014000028001, + 0.35000070000140004, + 0.14000028000056003, +) } + +my $url = 'https://maps-cache.cheshiresharedservices.gov.uk/maps/?wmts/CE_OS_AllBasemaps_COLOUR/oscce_grid/%d/%d/%d.jpeg&KEY=3a3f5c60eca1404ea114e6941c9d3895'; + +sub map_tiles { + my ( $self, %params ) = @_; + my ( $x, $y, $z ) = ( $params{x_tile}, $params{y_tile}, $params{zoom_act} ); + return [ + sprintf($url, $z, $x-1, $y-1), + sprintf($url, $z, $x, $y-1), + sprintf($url, $z, $x-1, $y), + sprintf($url, $z, $x, $y), + ]; +} + +sub latlon_to_tile($$$$) { + my ($self, $lat, $lon, $zoom) = @_; + my ($x, $y) = eval { Utils::convert_latlon_to_en($lat, $lon) }; + my $tile_params = $self->tile_parameters; + my $res = ($self->resolutions)[$zoom]; + my $fx = ( $x - $tile_params->{origin_x} ) / ($res * 256); + my $fy = ( $tile_params->{origin_y} - $y ) / ($res * 256); + return ( $fx, $fy ); +} + +sub tile_to_latlon { + my ($self, $fx, $fy, $zoom) = @_; + my $tile_params = $self->tile_parameters; + my $res = ($self->resolutions)[$zoom]; + my $x = $fx * $res * 256 + $tile_params->{origin_x}; + my $y = $tile_params->{origin_y} - $fy * $res * 256; + my ($lat, $lon) = Utils::convert_en_to_latlon($x, $y); + return ( $lat, $lon ); +} + +1; diff --git a/perllib/FixMyStreet/Map/OSM.pm b/perllib/FixMyStreet/Map/OSM.pm index a6cb6acea..ef465d7dc 100644 --- a/perllib/FixMyStreet/Map/OSM.pm +++ b/perllib/FixMyStreet/Map/OSM.pm @@ -87,10 +87,10 @@ sub generate_map_data { $zoom = $numZoomLevels - 1 if $zoom >= $numZoomLevels; $zoom = 0 if $zoom < 0; $params{zoom_act} = $zoomOffset + $zoom; - ($params{x_tile}, $params{y_tile}) = latlon_to_tile_with_adjust($params{latitude}, $params{longitude}, $params{zoom_act}); + ($params{x_tile}, $params{y_tile}) = $self->latlon_to_tile_with_adjust($params{latitude}, $params{longitude}, $params{zoom_act}); foreach my $pin (@{$params{pins}}) { - ($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $params{x_tile}, $params{y_tile}, $params{zoom_act}); + ($pin->{px}, $pin->{py}) = $self->latlon_to_px($pin->{latitude}, $pin->{longitude}, $params{x_tile}, $params{y_tile}, $params{zoom_act}); } return { @@ -102,24 +102,24 @@ sub generate_map_data { zoom => $zoom, zoomOffset => $zoomOffset, numZoomLevels => $numZoomLevels, - compass => compass( $params{x_tile}, $params{y_tile}, $params{zoom_act} ), + compass => $self->compass( $params{x_tile}, $params{y_tile}, $params{zoom_act} ), }; } sub compass { - my ( $x, $y, $z ) = @_; + my ( $self, $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 ) ], + north => [ map { Utils::truncate_coordinate($_) } $self->tile_to_latlon( $x, $y-1, $z ) ], + south => [ map { Utils::truncate_coordinate($_) } $self->tile_to_latlon( $x, $y+1, $z ) ], + west => [ map { Utils::truncate_coordinate($_) } $self->tile_to_latlon( $x-1, $y, $z ) ], + east => [ map { Utils::truncate_coordinate($_) } $self->tile_to_latlon( $x+1, $y, $z ) ], + here => [ map { Utils::truncate_coordinate($_) } $self->tile_to_latlon( $x, $y, $z ) ], }; } # Given a lat/lon, convert it to OSM tile co-ordinates (precise). -sub latlon_to_tile($$$) { - my ($lat, $lon, $zoom) = @_; +sub latlon_to_tile($$$$) { + my ($self, $lat, $lon, $zoom) = @_; my $x_tile = ($lon + 180) / 360 * 2**$zoom; my $y_tile = (1 - log(tan(deg2rad($lat)) + sec(deg2rad($lat))) / pi) / 2 * 2**$zoom; return ( $x_tile, $y_tile ); @@ -127,9 +127,9 @@ sub latlon_to_tile($$$) { # Given a lat/lon, convert it to OSM tile co-ordinates (nearest actual tile, # adjusted so the point will be near the centre of a 2x2 tiled map). -sub latlon_to_tile_with_adjust($$$) { - my ($lat, $lon, $zoom) = @_; - my ($x_tile, $y_tile) = latlon_to_tile($lat, $lon, $zoom); +sub latlon_to_tile_with_adjust($$$$) { + my ($self, $lat, $lon, $zoom) = @_; + my ($x_tile, $y_tile) = $self->latlon_to_tile($lat, $lon, $zoom); # Try and have point near centre of map if ($x_tile - int($x_tile) > 0.5) { @@ -143,7 +143,7 @@ sub latlon_to_tile_with_adjust($$$) { } sub tile_to_latlon { - my ($x, $y, $zoom) = @_; + my ($self, $x, $y, $zoom) = @_; my $n = 2 ** $zoom; my $lon = $x / $n * 360 - 180; my $lat = rad2deg(atan(sinh(pi * (1 - 2 * $y / $n)))); @@ -151,9 +151,9 @@ sub tile_to_latlon { } # Given a lat/lon, convert it to pixel co-ordinates from the top left of the map -sub latlon_to_px($$$$$) { - my ($lat, $lon, $x_tile, $y_tile, $zoom) = @_; - my ($pin_x_tile, $pin_y_tile) = latlon_to_tile($lat, $lon, $zoom); +sub latlon_to_px($$$$$$) { + my ($self, $lat, $lon, $x_tile, $y_tile, $zoom) = @_; + my ($pin_x_tile, $pin_y_tile) = $self->latlon_to_tile($lat, $lon, $zoom); my $pin_x = tile_to_px($pin_x_tile, $x_tile); my $pin_y = tile_to_px($pin_y_tile, $y_tile); return ($pin_x, $pin_y); @@ -182,8 +182,8 @@ 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 = MIN_ZOOM_LEVEL + (defined $c->get_param('zoom') ? $c->get_param('zoom') : 3); - my ($lat, $lon) = tile_to_latlon($tile_x, $tile_y, $zoom); + my $zoom = $self->MIN_ZOOM_LEVEL + (defined $c->get_param('zoom') ? $c->get_param('zoom') : 3); + my ($lat, $lon) = $self->tile_to_latlon($tile_x, $tile_y, $zoom); return ( $lat, $lon ); } diff --git a/t/map/cheshireeast.t b/t/map/cheshireeast.t new file mode 100644 index 000000000..a90a1606e --- /dev/null +++ b/t/map/cheshireeast.t @@ -0,0 +1,18 @@ +use Test::More; +use FixMyStreet::Map::CheshireEast; + +# https://maps-cache.cheshiresharedservices.gov.uk/maps/?wmts/CE_OS_AllBasemaps_COLOUR/oscce_grid/10/10187/8134.jpeg&KEY=3a3f5c60eca1404ea114e6941c9d3895 +my $tiles = FixMyStreet::Map::CheshireEast->map_tiles(x_tile => 10187, y_tile => 8134, zoom_act => 10); +$tiles = [ map { m{(\d+/\d+/\d+)}; $1; } @$tiles ]; +is_deeply $tiles, [ '10/10186/8133', '10/10187/8133', '10/10186/8134', '10/10187/8134' ]; + +use Data::Dumper; +my ($x, $y) = FixMyStreet::Map::CheshireEast->latlon_to_tile_with_adjust(53.150624, -2.386809, 10); +is $x, 10187; +is $y, 8134; + +my ($lat, $lon) = FixMyStreet::Map::CheshireEast->tile_to_latlon(10187, 8134, 10); +is sprintf("%.6f", $lat), 53.150624; +is sprintf("%.6f", $lon), -2.386809; + +done_testing(); diff --git a/t/map/tests.t b/t/map/tests.t index 499447ad5..02ec4e69d 100644 --- a/t/map/tests.t +++ b/t/map/tests.t @@ -7,6 +7,7 @@ my $requires = { 'Bromley' => 'map-fms.js', 'Buckinghamshire' => 'map-wmts-buckinghamshire.js', 'Lincolnshire' => 'lincolnshire/assets.js', + 'CheshireEast' => 'map-cheshireeast.js', 'FMS' => 'map-fms.js', 'Google' => 'map-google.js', 'GoogleOL' => 'map-google-ol.js', diff --git a/templates/web/cheshireeast/report/new/_form_labels.html b/templates/web/cheshireeast/report/new/_form_labels.html new file mode 100644 index 000000000..1897a5ff2 --- /dev/null +++ b/templates/web/cheshireeast/report/new/_form_labels.html @@ -0,0 +1,4 @@ +[% +SET form_title = 'Location of the problem'; +SET form_title_placeholder = 'Exact location, including any landmarks'; +%] diff --git a/templates/web/cheshireeast/report/new/roads_message.html b/templates/web/cheshireeast/report/new/roads_message.html index 3a62e052c..71fa3332d 100644 --- a/templates/web/cheshireeast/report/new/roads_message.html +++ b/templates/web/cheshireeast/report/new/roads_message.html @@ -1,8 +1,8 @@ <div id="js-roads-responsibility" class="box-warning hidden"> <strong>Not maintained by Cheshire East Council</strong> - <div id="js-not-council-road" class="hidden js-responsibility-message"> - <p>The selected road is not maintained by Cheshire East Council; - to find out who owns this land/road please contact the Land Registry at + <div id="js-not-a-road" class="hidden js-responsibility-message"> + <p>Cheshire East Council is not responsible for this location; + to find out who is responsible visit <a href="https://www.gov.uk/search-property-information-land-registry">https://www.gov.uk/search-property-information-land-registry</a>. </p> </div> diff --git a/web/cobrands/cheshireeast/assets.js b/web/cobrands/cheshireeast/assets.js index 1b1c254e3..435576408 100644 --- a/web/cobrands/cheshireeast/assets.js +++ b/web/cobrands/cheshireeast/assets.js @@ -6,8 +6,11 @@ if (!fixmystreet.maps) { var defaults = { wfs_url: "https://tilma.mysociety.org/mapserver/cheshireeast", - max_resolution: 4.777314267158508, - min_resolution: 0.5971642833948135, + max_resolution: { + fixmystreet: 4.777314267158508, + cheshireeast: 1.4000028000056002 + }, + min_resolution: 0.00001, attributes: { central_asset_id: 'central_as', site_code: 'site_code' @@ -62,29 +65,23 @@ fixmystreet.assets.add(labeled_defaults, { asset_item_message: 'You can pick a <b class="asset-spot">street light</b> from the map »' }); -var road_defaults = $.extend(true, {}, defaults, { +fixmystreet.assets.add(defaults, { stylemap: fixmystreet.assets.stylemap_invisible, always_visible: true, - non_interactive: true -}); - -fixmystreet.assets.add(road_defaults, { + non_interactive: true, wfs_feature: 'AdoptedRoads', usrn: { attribute: 'site_code', field: 'site_code' - } -}); - -fixmystreet.assets.add(road_defaults, { - wfs_feature: 'UnAdoptedRoads', + }, road: true, + no_asset_msg_id: '#js-not-a-road', + asset_item: 'road', + asset_type: 'road', all_categories: true, - no_asset_msg_id: '#js-not-council-road', - // The functions assume allow when found, disallow when not found, so we want the reverse actions: { - found: fixmystreet.message_controller.road_not_found, - not_found: fixmystreet.message_controller.road_found + found: fixmystreet.message_controller.road_found, + not_found: fixmystreet.message_controller.road_not_found } }); diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js index 7781d845b..4af5e61d4 100644 --- a/web/js/map-OpenLayers.js +++ b/web/js/map-OpenLayers.js @@ -250,9 +250,11 @@ $.extend(fixmystreet.utils, { marker_size: function() { var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 15) { + var size_normal = fixmystreet.maps.zoom_for_normal_size || 15; + var size_small = fixmystreet.maps.zoom_for_small_size || 13; + if (zoom >= size_normal) { return window.selected_problem_id ? 'small' : 'normal'; - } else if (zoom >= 13) { + } else if (zoom >= size_small) { return window.selected_problem_id ? 'mini' : 'small'; } else { return 'mini'; @@ -261,9 +263,11 @@ $.extend(fixmystreet.utils, { selected_marker_size: function() { var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 15) { + var size_normal = fixmystreet.maps.zoom_for_normal_size || 15; + var size_small = fixmystreet.maps.zoom_for_small_size || 13; + if (zoom >= size_normal) { return 'big'; - } else if (zoom >= 13) { + } else if (zoom >= size_small) { return 'normal'; } else { return 'small'; diff --git a/web/js/map-cheshireeast.js b/web/js/map-cheshireeast.js new file mode 100644 index 000000000..cedc92dba --- /dev/null +++ b/web/js/map-cheshireeast.js @@ -0,0 +1,33 @@ +fixmystreet.maps.config = function() { + fixmystreet.controls = [ + new OpenLayers.Control.Attribution(), + new OpenLayers.Control.ArgParserFMS(), + new OpenLayers.Control.Navigation(), + new OpenLayers.Control.PermalinkFMS('map'), + new OpenLayers.Control.PanZoomFMS({id: 'fms_pan_zoom' }) + ]; + /* Linking back to around from report page, keeping track of map moves */ + if ( fixmystreet.page == 'report' ) { + fixmystreet.controls.push( new OpenLayers.Control.PermalinkFMS('key-tool-problems-nearby', '/around') ); + } + fixmystreet.map_type = OpenLayers.Layer.CheshireEast; +}; + +OpenLayers.Layer.CheshireEast = OpenLayers.Class(OpenLayers.Layer.XYZ, { + url: 'https://maps-cache.cheshiresharedservices.gov.uk/maps/?wmts/CE_OS_AllBasemaps_COLOUR/oscce_grid/${z}/${x}/${y}.jpeg&KEY=3a3f5c60eca1404ea114e6941c9d3895', + + initialize: function(name, options) { + options = OpenLayers.Util.extend({ + units: "m", + projection: new OpenLayers.Projection("EPSG:27700"), + maxExtent: new OpenLayers.Bounds(-3276800, -3276800, 3276800, 3276800), + resolutions: [1792.003584007169, 896.0017920035843, 448.0008960017922, 224.0004480008961, 112.000224000448, 56.000112000224014, 28.000056000111993, 14.000028000056004, 7.000014000028002, 2.8000056000112004, 1.4000028000056002, 0.7000014000028001, 0.35000070000140004, 0.14000028000056003].slice(fixmystreet.zoomOffset || 0), + }, options); + OpenLayers.Layer.XYZ.prototype.initialize.call(this, name, this.url, options); + }, + + CLASS_NAME: "OpenLayers.Layer.CheshireEast" +}); + +fixmystreet.maps.zoom_for_normal_size = 7; +fixmystreet.maps.zoom_for_small_size = 4; diff --git a/web/js/map-wmts-bristol.js b/web/js/map-wmts-bristol.js index 757f347df..2090fa0cf 100644 --- a/web/js/map-wmts-bristol.js +++ b/web/js/map-wmts-bristol.js @@ -115,13 +115,5 @@ fixmystreet.maps.config = function() { this.setup_wmts_base_map(); }; -fixmystreet.maps.marker_size = function() { - var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 7) { - return 'normal'; - } else if (zoom >= 4) { - return 'small'; - } else { - return 'mini'; - } -}; +fixmystreet.maps.zoom_for_normal_size = 7; +fixmystreet.maps.zoom_for_small_size = 4; diff --git a/web/js/map-wmts-buckinghamshire.js b/web/js/map-wmts-buckinghamshire.js index ee5ac8753..ae44cdf13 100644 --- a/web/js/map-wmts-buckinghamshire.js +++ b/web/js/map-wmts-buckinghamshire.js @@ -130,13 +130,5 @@ fixmystreet.maps.config = function() { this.setup_wmts_base_map(); }; -fixmystreet.maps.marker_size = function() { - var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 7) { - return 'normal'; - } else if (zoom >= 4) { - return 'small'; - } else { - return 'mini'; - } -}; +fixmystreet.maps.zoom_for_normal_size = 7; +fixmystreet.maps.zoom_for_small_size = 4; diff --git a/web/js/map-wmts-hounslow.js b/web/js/map-wmts-hounslow.js index 1f8927b3f..d021fab50 100644 --- a/web/js/map-wmts-hounslow.js +++ b/web/js/map-wmts-hounslow.js @@ -177,13 +177,5 @@ fixmystreet.maps.config = function() { this.setup_wmts_base_map(); }; -fixmystreet.maps.marker_size = function() { - var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 8) { - return 'normal'; - } else if (zoom >= 4) { - return 'small'; - } else { - return 'mini'; - } -}; +fixmystreet.maps.zoom_for_normal_size = 8; +fixmystreet.maps.zoom_for_small_size = 4; diff --git a/web/js/map-wmts-isleofwight.js b/web/js/map-wmts-isleofwight.js index 464bee913..57e41e696 100644 --- a/web/js/map-wmts-isleofwight.js +++ b/web/js/map-wmts-isleofwight.js @@ -183,24 +183,5 @@ fixmystreet.maps.config = function() { this.setup_wmts_base_map(); }; -fixmystreet.maps.marker_size = function() { - var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 7) { - return 'normal'; - } else if (zoom >= 4) { - return 'small'; - } else { - return 'mini'; - } -}; - -fixmystreet.maps.selected_marker_size = function() { - var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 7) { - return 'big'; - } else if (zoom >= 4) { - return 'normal'; - } else { - return 'small'; - } -}; +fixmystreet.maps.zoom_for_normal_size = 7; +fixmystreet.maps.zoom_for_small_size = 4; diff --git a/web/js/map-wmts-zurich.js b/web/js/map-wmts-zurich.js index 346e9b89a..436dca6ff 100644 --- a/web/js/map-wmts-zurich.js +++ b/web/js/map-wmts-zurich.js @@ -152,13 +152,5 @@ fixmystreet.maps.config = function() { fixmystreet.area_format = { fillColor: 'none', strokeWidth: 4, strokeColor: 'black' }; }; -fixmystreet.maps.marker_size = function() { - var zoom = fixmystreet.map.getZoom() + fixmystreet.zoomOffset; - if (zoom >= 6) { - return 'normal'; - } else if (zoom >= 3) { - return 'small'; - } else { - return 'mini'; - } -}; +fixmystreet.maps.zoom_for_normal_size = 6; +fixmystreet.maps.zoom_for_small_size = 3; |