diff options
| author | Dave Arter <davea@mysociety.org> | 2015-06-30 11:03:20 +0100 | 
|---|---|---|
| committer | Dave Arter <davea@mysociety.org> | 2015-06-30 11:03:20 +0100 | 
| commit | bff57817b0a8d9d2ab8ceeecbcba17f259d4ac1a (patch) | |
| tree | a2a755e57e92c3991c3681ae13d74347ddf0fb9c /web/js/map-OpenLayers.js | |
| parent | 1df64a30dd0939d8d9b8b1854f7f7e421d9b20ab (diff) | |
| parent | b2c41d9b9ac0444565cdc8b6dbbaeedf759185ba (diff) | |
Merge branch 'report-filtering-on-map'
This branch allows the map pages to be filtered by report category and
status with the 'filter_category' and 'status' GET parameters.
Diffstat (limited to 'web/js/map-OpenLayers.js')
| -rw-r--r-- | web/js/map-OpenLayers.js | 110 | 
1 files changed, 104 insertions, 6 deletions
| diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js index 3088cc764..a0ab4f34c 100644 --- a/web/js/map-OpenLayers.js +++ b/web/js/map-OpenLayers.js @@ -29,6 +29,13 @@ function fixmystreet_update_pin(lonlat) {              if ( lb.length === 0 ) { lb = $('#form_name').prev(); }              lb.before(data.extra_name_info);          } +        // If the category filter appears on the map and the user has selected +        // something from it, then pre-fill the category field in the report, +        // if it's a value already present in the drop-down. +        var category = $("#filter_categories").val(); +        if (category !== undefined && $("#form_category option[value="+category+"]").length) { +            $("#form_category").val(category); +        }      });      if (!$('#side-form-error').is(':visible')) { @@ -69,6 +76,7 @@ function fixmystreet_zoomToBounds(bounds) {  function fms_markers_list(pins, transform) {      var markers = []; +    var size = fms_marker_size_for_zoom(fixmystreet.map.getZoom() + fixmystreet.zoomOffset);      for (var i=0; i<pins.length; i++) {          var pin = pins[i];          var loc = new OpenLayers.Geometry.Point(pin[1], pin[0]); @@ -81,7 +89,7 @@ function fms_markers_list(pins, transform) {          }          var marker = new OpenLayers.Feature.Vector(loc, {              colour: pin[2], -            size: pin[5] || 'normal', +            size: pin[5] || size,              id: pin[3],              title: pin[4] || ''          }); @@ -90,6 +98,29 @@ function fms_markers_list(pins, transform) {      return markers;  } +function fms_marker_size_for_zoom(zoom) { +    if (zoom >= 15) { +        return 'normal'; +    } else if (zoom >= 13) { +        return 'small'; +    } else { +        return 'mini'; +    } +} + +function fms_markers_resize() { +    var size = fms_marker_size_for_zoom(fixmystreet.map.getZoom() + fixmystreet.zoomOffset); +    for (var i = 0; i < fixmystreet.markers.features.length; i++) { +        fixmystreet.markers.features[i].attributes.size = size; +    } +    fixmystreet.markers.redraw(); +} + +function fms_categories_or_status_changed() { +    // If the category or status has changed we need to re-fetch map markers +    fixmystreet.markers.refresh({force: true}); +} +  function fixmystreet_onload() {      if ( fixmystreet.area.length ) {          for (var i=0; i<fixmystreet.area.length; i++) { @@ -131,7 +162,8 @@ function fixmystreet_onload() {              backgroundWidth: 60,              backgroundHeight: 30,              backgroundXOffset: -7, -            backgroundYOffset: -30 +            backgroundYOffset: -30, +            popupYOffset: -40          },          'big': {              externalGraphic: fixmystreet.pin_prefix + "pin-${colour}-big.png", @@ -144,6 +176,27 @@ function fixmystreet_onload() {              backgroundHeight: 40,              backgroundXOffset: -10,              backgroundYOffset: -35 +        }, +        'small': { +            externalGraphic: fixmystreet.pin_prefix + "pin-${colour}-small.png", +            graphicWidth: 24, +            graphicHeight: 32, +            graphicXOffset: -12, +            graphicYOffset: -32, +            backgroundGraphic: fixmystreet.pin_prefix + "pin-shadow-small.png", +            backgroundWidth: 30, +            backgroundHeight: 15, +            backgroundXOffset: -4, +            backgroundYOffset: -15, +            popupYOffset: -20 +        }, +        'mini': { +            externalGraphic: fixmystreet.pin_prefix + "pin-${colour}-mini.png", +            graphicWidth: 16, +            graphicHeight: 20, +            graphicXOffset: -8, +            graphicYOffset: -20, +            popupYOffset: -10          }      });      var pin_layer_options = { @@ -155,7 +208,7 @@ function fixmystreet_onload() {      if (fixmystreet.page == 'around') {          fixmystreet.bbox_strategy = fixmystreet.bbox_strategy || new OpenLayers.Strategy.BBOX({ ratio: 1 });          pin_layer_options.strategies = [ fixmystreet.bbox_strategy ]; -        pin_layer_options.protocol = new OpenLayers.Protocol.HTTP({ +        pin_layer_options.protocol = new OpenLayers.Protocol.FixMyStreet({              url: '/ajax',              params: fixmystreet.all_pins ? { all_pins: 1 } : { },              format: new OpenLayers.Format.FixMyStreet() @@ -186,17 +239,29 @@ function fixmystreet_onload() {          fixmystreet.markers.events.register( 'featureselected', fixmystreet.markers, function(evt) {              var feature = evt.feature;              selectedFeature = feature; +            var popupYOffset = feature.layer.styleMap.createSymbolizer(feature).popupYOffset || -40;              var popup = new OpenLayers.Popup.FramedCloud("popup",                  feature.geometry.getBounds().getCenterLonLat(),                  null,                  feature.attributes.title + "<br><a href=/report/" + feature.attributes.id + ">" + translation_strings.more_details + "</a>", -                { size: new OpenLayers.Size(0,0), offset: new OpenLayers.Pixel(0,-40) }, +                { size: new OpenLayers.Size(0, 0), offset: new OpenLayers.Pixel(0, popupYOffset) },                  true, onPopupClose);              feature.popup = popup;              fixmystreet.map.addPopup(popup);          });          fixmystreet.map.addControl( fixmystreet.select_feature );          fixmystreet.select_feature.activate(); +        fixmystreet.map.events.register( 'zoomend', null, fms_markers_resize ); + +        // If the category filter dropdown exists on the page set up the +        // event handlers to populate it and react to it changing +        if ($("select#filter_categories").length) { +            $("body").on("change", "#filter_categories", fms_categories_or_status_changed); +        } +        // Do the same for the status dropdown +        if ($("select#statuses").length) { +            $("body").on("change", "#statuses", fms_categories_or_status_changed); +        }      } else if (fixmystreet.page == 'new') {          fixmystreet_activate_drag();      } @@ -354,6 +419,16 @@ $(function(){          fixmystreet.page = 'around';      }); +    // Hide the pin filter submit button. Not needed because we'll use JS +    // to refresh the map when the filter inputs are changed. +    $(".report-list-filters [type=submit]").hide(); + +    if (fixmystreet.page == "my" || fixmystreet.page == "reports") { +        $(".report-list-filters select").change(function() { +            $(this).closest("form").submit(); +        }); +    } +      // Vector layers must be added onload as IE sucks      if ($.browser.msie) {          $(window).load(fixmystreet_onload); @@ -447,6 +522,30 @@ OpenLayers.Control.PermalinkFMSz = OpenLayers.Class(OpenLayers.Control.Permalink      }  }); +/* Pan data request handler */ +// This class is used to get a JSON object from /ajax that contains +// pins for the map and HTML for the sidebar. It does a fetch whenever the map +// is dragged (modulo a buffer extending outside the viewport). +// This subclass is required so we can pass the 'filter_category' and 'status' query +// params to /ajax if the user has filtered the map. +OpenLayers.Protocol.FixMyStreet = OpenLayers.Class(OpenLayers.Protocol.HTTP, { +    read: function(options) { +        // Pass the values of the category and status fields as query params +        var filter_category = $("#filter_categories").val(); +        if (filter_category !== undefined) { +            options.params = options.params || {}; +            options.params.filter_category = filter_category; +        } +        var status = $("#statuses").val(); +        if (status !== undefined) { +            options.params = options.params || {}; +            options.params.status = status; +        } +        return OpenLayers.Protocol.HTTP.prototype.read.apply(this, [options]); +    }, +    CLASS_NAME: "OpenLayers.Protocol.FixMyStreet" +}); +  /* Pan data handler */  OpenLayers.Format.FixMyStreet = OpenLayers.Class(OpenLayers.Format.JSON, {      read: function(json, filter) { @@ -462,8 +561,7 @@ OpenLayers.Format.FixMyStreet = OpenLayers.Class(OpenLayers.Format.JSON, {          if (typeof(obj.current_near) != 'undefined' && (current_near = document.getElementById('current_near'))) {              current_near.innerHTML = obj.current_near;          } -        var markers = fms_markers_list( obj.pins, false ); -        return markers; +        return fms_markers_list( obj.pins, false );      },      CLASS_NAME: "OpenLayers.Format.FixMyStreet"  }); | 
