<commit_before>'use strict';

/*
 * @ngdoc directive
 * @name hkMap
 * @description
 * Directive for a map of Hong Kong with GeoJSON layers for district councils and constituency areas
 *
 * @param {string} [height="300px"] Height of the map.
 * @param {class} class Use the class declaration to set width in Bootstrap column system.
 * @param {object} selectedItems Object that stores which elements in the map are selected
 *
 */

angular.module('frontendApp').directive('hkMap', function() {
  return {
    scope: true,
    restrict: 'AE',
    priority: 10,
    compile: function(elem, attrs) {
      var leafletNode = angular.element(elem.children()[0]);
      // If height is specified, then move it to the template, otherwise use default
      leafletNode.css('height', attrs.height || "300px");

      // Need relative positioning for overlay
      elem.css('position', 'relative');

      // If an id is provided, move the id to the child element;
      // This is so that we can get the map object when we have multiple maps on the page
      if (!_.isUndefined(attrs.mapId)) {
        leafletNode.attr('id', attrs.mapId);
      }
    },
    controller: ['$scope', 'GeoFiles', '$attrs', 'AreaSelection', '$parse', 'leafletData', function($scope, GeoFiles, $attrs, AreaSelection, $parse, leafletData) {
      // Default initializations
      $scope.defaults =  {
        scrollWheelZoom: true,
        maxZoom: 18
      };

      // The zoom level after which areas are drawn
      var AREATHRESHOLD = 14;

      // Center object
      if (_.isUndefined($attrs.mapCenter)) {
        $scope.center = {};
      } else {
        $scope.center = $parse($attrs.mapCenter)($scope);
      }

      if (_.isEmpty($scope.center)) {
        angular.extend($scope.center,
          {
            lat: 22.298,
            lng: 114.151,
            zoom: 12
          }
        );
      }
      // Expose the map object
      // Returns a promise
      $scope.getMap = function() {
        if (!_.isUndefined($attrs.mapId)) {
          return leafletData.getMap($attrs.mapId);
        } else {
          return leafletData.getMap();
        }
      };

      // Styles
      $scope._defaultStyle = {
        color: "#2b8cbe",
        fillOpacity: 0,
        weight: 3
      };

      $scope._hoverStyle = {
        color: "#000",
        fillColor: "#2b8cbe",
        fillOpacity: 0.2,
        weight: 6
      };

      $scope._partiallySelectedStyle = {
        color: "#ff0",
        fillColor: "#ff0",
        fillOpacity: 0.2,
        weight: 6
      };

      $scope._selectedStyle = {
        color: "#2ca25f",
        fillColor: "#2ca25f",
        fillOpacity: 0.2,
        weight: 6
      };

      // TODO: Add partially selected district styling

      var _isArea = function(feature) {
        // Checks if a feature is an area
        return !_.isUndefined(feature.properties.CACODE);
      };

      // Styler that styles a layer based on whether it is selected or not
      var featureStyler = function(feature) {
        var code = feature.properties.CACODE || feature.properties.DCCODE;
        if ($scope.selectedAreas.isSelected(code)) {
          return $scope._selectedStyle;
        } else {
          return $scope._defaultStyle;
        }
      };

      // Model for tracking selected areas
      if (_.isUndefined($attrs.selectedAreas)) {
        $scope.selectedAreas = AreaSelection.getModel();
      } else {
        $scope.selectedAreas = $parse($attrs.selectedAreas)($scope);
      }

      // We have to set a watch on the selectedAreas to keep the map styling in sync
      // If it changes, then we need to getMap(), then loop through map._layers and update each layer's style
      // But, we can't use a watch on the selectedAreas object, otherwise layers get styled twice when clicking on the map
      var _applyStylesToMap = function(map) {
        // Given a map, loop through the layers in the map and apply the appropriate style given
        // the current state of selectedAreas
        var layers = _.values(map._layers);
        _.forEach(layers, function(layer) {
          if (!_.isUndefined(layer.feature) &&
            !_.isUndefined(layer.feature.properties) &&
            _isArea(layer.feature)) {
            layer.setStyle(featureStyler(layer.feature));
          }
        });
      };
      // So instead, use a listener.
      $scope.$on('redrawMap', function() {
        console.log('redrawing map');
        $scope.getMap().then(function(map){
          _applyStylesToMap(map);
        });<commit_msg>fix bug in redraw signal<commit_after>'use strict';

/*
 * @ngdoc directive
 * @name hkMap
 * @description
 * Directive for a map of Hong Kong with GeoJSON layers for district councils and constituency areas
 *
 * @param {string} [height="300px"] Height of the map.
 * @param {class} class Use the class declaration to set width in Bootstrap column system.
 * @param {object} selectedItems Object that stores which elements in the map are selected
 *
 */

angular.module('frontendApp').directive('hkMap', function() {
  return {
    scope: true,
    restrict: 'AE',
    priority: 10,
    compile: function(elem, attrs) {
      var leafletNode = angular.element(elem.children()[0]);
      // If height is specified, then move it to the template, otherwise use default
      leafletNode.css('height', attrs.height || "300px");

      // Need relative positioning for overlay
      elem.css('position', 'relative');

      // If an id is provided, move the id to the child element;
      // This is so that we can get the map object when we have multiple maps on the page
      if (!_.isUndefined(attrs.mapId)) {
        leafletNode.attr('id', attrs.mapId);
      }
    },
    controller: ['$scope', 'GeoFiles', '$attrs', 'AreaSelection', '$parse', 'leafletData', function($scope, GeoFiles, $attrs, AreaSelection, $parse, leafletData) {
      // Default initializations
      $scope.defaults =  {
        scrollWheelZoom: true,
        maxZoom: 18
      };

      // The zoom level after which areas are drawn
      var AREATHRESHOLD = 14;

      // Center object
      if (_.isUndefined($attrs.mapCenter)) {
        $scope.center = {};
      } else {
        $scope.center = $parse($attrs.mapCenter)($scope);
      }

      if (_.isEmpty($scope.center)) {
        angular.extend($scope.center,
          {
            lat: 22.298,
            lng: 114.151,
            zoom: 12
          }
        );
      }
      // Expose the map object
      // Returns a promise
      $scope.getMap = function() {
        if (!_.isUndefined($attrs.mapId)) {
          return leafletData.getMap($attrs.mapId);
        } else {
          return leafletData.getMap();
        }
      };

      // Styles
      $scope._defaultStyle = {
        color: "#2b8cbe",
        fillOpacity: 0,
        weight: 3
      };

      $scope._hoverStyle = {
        color: "#000",
        fillColor: "#2b8cbe",
        fillOpacity: 0.2,
        weight: 6
      };

      $scope._partiallySelectedStyle = {
        color: "#ff0",
        fillColor: "#ff0",
        fillOpacity: 0.2,
        weight: 6
      };

      $scope._selectedStyle = {
        color: "#2ca25f",
        fillColor: "#2ca25f",
        fillOpacity: 0.2,
        weight: 6
      };

      // TODO: Add partially selected district styling

      var _isArea = function(feature) {
        // Checks if a feature is an area
        return !_.isUndefined(feature.properties.CACODE);
      };

      // Styler that styles a layer based on whether it is selected or not
      var featureStyler = function(feature) {
        var code = feature.properties.CACODE || feature.properties.DCCODE;
        if ($scope.selectedAreas.isSelected(code)) {
          return $scope._selectedStyle;
        } else {
          return $scope._defaultStyle;
        }
      };

      // Model for tracking selected areas
      if (_.isUndefined($attrs.selectedAreas)) {
        $scope.selectedAreas = AreaSelection.getModel();
      } else {
        $scope.selectedAreas = $parse($attrs.selectedAreas)($scope);
      }

      // We have to set a watch on the selectedAreas to keep the map styling in sync
      // If it changes, then we need to getMap(), then loop through map._layers and update each layer's style
      // But, we can't use a watch on the selectedAreas object, otherwise layers get styled twice when clicking on the map
      var _applyStylesToMap = function(map) {
        // Given a map, loop through the layers in the map and apply the appropriate style given
        // the current state of selectedAreas
        var layers = _.values(map._layers);
        _.forEach(layers, function(layer) {
          if (!_.isUndefined(layer.feature) &&
            !_.isUndefined(layer.feature.properties)) {
            layer.setStyle(featureStyler(layer.feature));
          }
        });
      };
      // So instead, use a listener.
      $scope.$on('redrawMap', function() {
        console.log('redrawing map');
        $scope.getMap().then(function(map){
          _applyStylesToMap(map);
        });
{'fraction_non_alphanumeric': 0.11615105141473081, 'fraction_numerical': 0.011449961466475833, 'mean_word_length': 2.1563585823488536, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5382512', 'n_tokens_mistral': 2665, 'n_tokens_neox': 2546, 'n_words': 769}