tombatossals / angular-leaflet-directive

AngularJS directive to embed an interact with maps managed by Leaflet library
http://tombatossals.github.io/angular-leaflet-directive
MIT License
1.5k stars 635 forks source link

Angular Leaflet-directive GeoJSON filter on Clusters #1054

Open JonahKE opened 8 years ago

JonahKE commented 8 years ago

I am attempting to filter clustered markers using multiple geojson properties. The filter is working with non-clustered markers. I have a large dataset thus the need for clustering. My controller code is shown below:

angular.module('bizvizmap').controller('controller', [
    '$scope', '$http', '$filter', 'leafletData',
    function ($scope, $http, $filter, leafletData){
    $scope.center = {
        lat: 39.5500507,
        lng: -105.7820674,
        zoom: 5
            },
    $scope.defaults = {
        scrollWheelZoom: true
            },
    $scope.events = {
            map: {
            enable: ['zoomstart', 'drag', 'click', 'mousemove'],
            logic: 'emit'
            }
            },
    $scope.layers = {
            baselayers: {
            osm: {
            name: 'OpenStreetMap',
            url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            type: 'xyz'
                    }
                },
            markers:{}
    },
    $scope.search = {
            'NAICS':'',
            'SIC':'',
            };
    $scope.map = null;
    leafletData.getMap("bizvizmap").then(function(map){
        $scope.map = map;
    });
    $scope.geojson = {};
    $http.get('data/bizvizmap_3.geojson').success(function (data, status){
            //$scope.geojson.data = data;
            addGeoJsonLayerWithClustering(data);
        });
    function addGeoJsonLayerWithClustering(data){
        var markers = L.markerClusterGroup({
            showCoverageOnHover:false,
            chunkedLoading: true
            });
        var geojsonLayer = L.geoJson(data, {
            onEachFeature: function(feature, layer){
            var popupContent = '<table><tr><th scope="row">Name</th><td>' + (feature.properties['Name'] !== null ? Autolinker.link(String(feature.properties['Name'])) : '') + '</td></tr><tr><th scope="row">Address</th><td>' + (feature.properties['Address'] !== null ? Autolinker.link(String(feature.properties['Address'])) : '') + '</td></tr><tr><th scope="row">City</th><td>' + (feature.properties['City'] !== null ? Autolinker.link(String(feature.properties['City'])) : '') + '</td></tr><tr><th scope="row">State</th><td>' + (feature.properties['State'] !== null ? Autolinker.link(String(feature.properties['State'])) : '') + '</td></tr><tr><th scope="row">Phone</th><td>' + (feature.properties['Phone'] !== null ? Autolinker.link(String(feature.properties['Phone'])) : '') + '</td></tr><tr><th scope="row">County</th><td>' + (feature.properties['County'] !== null ? Autolinker.link(String(feature.properties['County'])) : '') + '</td></tr><tr><th scope="row">Latitude</th><td>' + (feature.properties['Latitude'] !== null ? Autolinker.link(String(feature.properties['Latitude'])) : '') + '</td></tr><tr><th scope="row">Longitude</th><td>' + (feature.properties['Longitude'] !== null ? Autolinker.link(String(feature.properties['Longitude'])) : '') + '</td></tr><tr><th scope="row">BusinessDescription</th><td>' + (feature.properties['BusinessDescription'] !== null ? Autolinker.link(String(feature.properties['BusinessDescription'])) : '') + '</td></tr><tr><th scope="row">SIC</th><td>' + (feature.properties['SIC'] !== null ? Autolinker.link(String(feature.properties['SIC'])) : '') + '</td></tr><tr><th scope="row">SICDescription</th><td>' + (feature.properties['SICDescription'] !== null ? Autolinker.link(String(feature.properties['SICDescription'])) : '') + '</td></tr><tr><th scope="row">NAICS</th><td>' + (feature.properties['NAICS'] !== null ? Autolinker.link(String(feature.properties['NAICS'])) : '') + '</td></tr><tr><th scope="row">NAICSDescription</th><td>' + (feature.properties['NAICSDescription'] !== null ? Autolinker.link(String(feature.properties['NAICSDescription'])) : '') + '</td></tr><tr><th scope="row">Website</th><td>' + (feature.properties['Website'] !== null ? Autolinker.link(String(feature.properties['Website'])) : '') + '</td></tr></table>';
                layer.bindPopup(popupContent);
            }
    });
    markers.addLayer(geojsonLayer);
    leafletData.getMap().then(function(map){
        map.addLayer(markers);
        map.fitBounds(markers.getBounds());
        });
    }
      // Filtering markers
        $scope.$watch('search', function(newVal, oldVal){
            if(!angular.equals(newVal, oldVal)) {
                var geojson = angular.copy($scope.data);
                angular.forEach(newVal, function(value, property){
                    console.log(property + ':' + value);
                    if (value !== ''){
                        geojson = $filter('filter')(geojson, property, value);
                    }
                });
                $scope.geojson.data = geojson;
            } else {
                $scope.geojson.data = $scope.data;
            }
        }, true);
    }
]);

The code for the filter is:

angular.module('bizvizmap').filter('filter', [function() {
        return function(geojson, searchProperty, searchValue) {
            var matches = {'type': 'FeatureCollection', 'features': []};
            angular.forEach(geojson.features, function(featureObject, featureKey) {
                if (featureObject.properties.hasOwnProperty(searchProperty)) {
                    var property = featureObject.properties[searchProperty].toLowerCase();
                    var search = searchValue.toLowerCase();
                    if (property.indexOf(search) > -1) {
                        matches.features.push(featureObject);
                    }
                }
            });
            return matches;
        };
    }]);

I have a feeling that the last bit of code of the controller needs to be changed but I dont know how to it. Here is that code block:

 $scope.$watch('search', function(newVal, oldVal){
            if(!angular.equals(newVal, oldVal)) {
                var geojson = angular.copy($scope.data);
                angular.forEach(newVal, function(value, property){
                    console.log(property + ':' + value);
                    if (value !== ''){
                        geojson = $filter('filter')(geojson, property, value);
                    }
                });
                $scope.geojson.data = geojson;
            } else {
                $scope.geojson.data = $scope.data;
            }
        }, true);
    }