具有可过滤标记的Google Maps API V3标记群集

时间:2014-11-18 12:41:46

标签: javascript google-maps google-maps-api-3

有很多关于Stackoverflow的问题,人们已经帮助解决了MarkerClusterer的问题,但是,我正在使用Twilliamson90的一个很棒的小项目而不是Github。基本上,它允许我对标记进行一些很好的过滤,并允许我链接一些不错的外部数据集。

我现在的问题是,我有太多的数据可以轻松地在页面上显示而不会看起来太拥挤。最明显的解决方案是添加标记聚类 - 遗憾的是,我发现它并不那么容易。

我已经完成了几个教程,但我无法使用过滤功能。

我已粘贴下面的javascript,任何帮助都会非常感激。巨大。

var TEST_MAP = 'custom_style';
var myMap = function() {

    var featureOpts = [
    {
      stylers: [
        { hue: '#782B8B' },
        { visibility: 'simplified' },
        { gamma: 0.5 },
        { weight: 0.5 }
      ]
    },
    {
      elementType: 'labels',
      stylers: [
        { visibility: 'off' }
      ]
    },
    {
      featureType: 'water',
      stylers: [
        { color: '#782B8B' }
      ]
    }
  ];
    var options = {
        zoom: 7,
        center: new google.maps.LatLng(53.967397, -2.043457),
        streetViewControl: false,
        zoomControlOptions: {
          style: google.maps.ZoomControlStyle.SMALL
        },
        mapTypeControl: false,
        mapTypeControlOptions: {
            mapTypeIds: [TEST_MAP]
        },
        mapTypeId: TEST_MAP
    }

    /*
        Load the map then markers
        @param object settings (configuration options for map)
        @return undefined
    */
    function init(settings) {
        map = new google.maps.Map(document.getElementById( settings.idSelector ), options);

        var styledMapOptions = {
            name: 'Custom Style'
        };
        var customMapType = new google.maps.StyledMapType(featureOpts, styledMapOptions);

        map.mapTypes.set(TEST_MAP, customMapType);

        markerLocation = settings.markerLocation;
        loadMarkers();
    }

    /*
        =======
        MARKERS
        =======
    */
    markers = {};
    markerList = [];

    /*
        Load markers onto the Google Map party a provided array or demo personData (data.js)
        @param array personList [optional] (list of people to load)
        @return undefined
    */
    function loadMarkers(personList) {

        // optional argument of person
        var people = ( typeof personList !== 'undefined' ) ? personList : personData;

        var j = 1; // for lorempixel

        for( i=0; i < people.length; i++ ) {
            var person = people[i];

            // if its already on the map, dont put it there again
            if( markerList.indexOf(person.id) !== -1 ) continue;

            var lat = person.lat,
                lng = person.lng,
                markerId = person.id;

            var infoWindow = new google.maps.InfoWindow({
                maxWidth: 500
            });

            var iconImage = {
                url: person.markerIcon,
                size: new google.maps.Size(30, 40),
                origin: new google.maps.Point(0,0),
                anchor: new google.maps.Point(0,40)
            };

            var marker = new google.maps.Marker({
                position: new google.maps.LatLng( lat, lng ),
                title: person.name,
                markerId: markerId,
                icon: iconImage,
                map: map
            });

            markers[markerId] = marker;
            markerList.push(person.id);



var MarkerCluster = new MarkerClusterer(TEST_MAP, markers);

            var content = ['<div class="iw"><img src="', person.image, '">', '<div class="iw-text"><strong>', person.name, '</strong><br><strong>Applications:</strong> ', person.applications, '<br><strong>SIC Sub Class:</strong> ', person.sicSubClass, '<br><strong>Constituency:</strong> ', person.constituency, '<br><strong>Stream:</strong> ', person.stream, '<br><strong>Town:</strong> ', person.town, '<br><strong>Start date:</strong> ', person.startDate, '<br><strong>Offer grant:</strong> &pound;', person.grant, '<br><strong>Offer cost:</strong> &pound;', person.cost, '<br><strong>Payments to date:</strong> &pound;', person.payments, '<br><a target="blank_" href="', person.url, '">', person.url, '</a></div></div>'].join('');

            google.maps.event.addListener(marker, 'click', (function (marker, content) {
                return function() {
                    infoWindow.setContent(content);
                    infoWindow.open(map, marker);
                }
            })(marker, content));   

        }

    }



    /*
        Remove marker party map and our list of current markers
        @param int id (id of the marker element)
        @return undefined
    */
    function removePersonMarker(id) {
        if( markers[id] ) {
            markers[id].setMap(null);
            loc = markerList.indexOf(id);
            if (loc > -1) markerList.splice(loc, 1);
            delete markers[id];
        }
    }

    /*
        ======
        FILTER
        ======
    */

    // default all filters off
    var filter = {
        applications: 0,
        constituency: 0,
        town: 0,
        stream: 0,
        startDate: 0,
        party: 0
    }
    var filterMap;

    /*
        Helper function
        @param array a (array of arrays)
        @return array (common elements party all arrays)
    */
    function reduceArray(a) {
        r = a.shift().reduce(function(res, v) {
            if (res.indexOf(v) === -1 && a.every(function(a) {
                return a.indexOf(v) !== -1;
            })) res.push(v);
            return res;
        }, []);
        return r;
    }

    /*
        Helper function
        @param string n
        @return bool
    */
    function isInt(n) {
        return n % 1 === 0;
    }


    /*
        Decides which filter function to call and stacks all filters together
        @param string filterType (the property that will be filtered upon)
        @param string value (selected filter value)
        @return undefined
    */
    function filterCtrl(filterType, value) {
        // result array
        var results = [];

        if( isInt(value) ) {
            filter[filterType] = parseInt(value);
        } else {
            filter[filterType] = value;
        }

        for( k in filter ) {
            if( !filter.hasOwnProperty(k) && !( filter[k] !== 0 ) ) {
                // all the filters are off
                loadMarkers();
                return false;
            } else if ( filter[k] !== 0 ) {
                // call filterMap function and append to r array
                results.push( filterMap[k]( filter[k] ) );
            } else {
                // fail silently
            }
        }

        if( filter[filterType] === 0 ) results.push( personData );

        /*
            if there is 1 array (1 filter applied) set it,
            else find markers that are common to every results array (pass every filter)
        */
        if( results.length === 1 ) {
            results = results[0];
        } else {
            results = reduceArray( results );
        }

        loadMarkers( results );

    }

    /* 
        The keys in this need to be mapped 1-to-1 with the keys in the filter variable.
    */
    filterMap = {
        applications: function( value ) {
            return filterIntsLessThan('applications', value);
        },

        town: function( value ) {
            return filterByString('town', value);
        },

        constituency: function( value ) {
            return filterByString('constituency', value);
        },

        stream: function( value ) {
            return filterByString('stream', value);
        },

        party: function( value ) {
            return filterByString('party', value);
        },

        startDate: function( value ) {
            return filterByString('startDate', value);
        }

    }

    /*
        Filters marker data based upon a string match
        @param string dataProperty (the key that will be filtered upon)
        @param string value (selected filter value)
        @return array (applicants that made it through the filter)
    */
    function filterByString( dataProperty, value ) {
        var applicants = [];

        for( var i=0; i < personData.length; i++ ) {
            var person = personData[i];
            if( person[dataProperty] == value ) {
                applicants.push( person );
            } else {
                removePersonMarker( person.id );
            }
        }
        return applicants;
    }

    /*
        Filters out integers that are under the provided value
        @param string dataProperty (the key that will be filtered upon)
        @param int value (selected filter value)
        @return array (applicants that made it through the filter)
    */
    function filterIntsLessThan( dataProperty, value ) {
            var applicants = [];

            for( var i=0; i < personData.length; i++ ) {
                var person = personData[i];
                if( person[dataProperty] > value ) {
                    applicants.push( person )
                } else {
                    removePersonMarker( person.id );
                }
            }
            return applicants;
    }

    // Takes all the filters off
    function resetFilter() {
        filter = {
            applications: 0,
            constituency: 0,
            town: 0,
            stream: 0,
            startDate: 0,
            party: 0
        }
    }

    return {
        init: init,
        loadMarkers: loadMarkers,
        filterCtrl: filterCtrl,
        resetFilter: resetFilter
    };
}();


$(function() {

    var mapConfig = {
        idSelector: 'map-canvas'
    }

    myMap.init( mapConfig );

    $('.load-btn').on('click', function() {
        var $this = $(this);
        // reset everything
        $('select').val(0);
        myMap.resetFilter();
        myMap.loadMarkers();

        if( $this.hasClass('is-success') ) {
            $this.removeClass('is-success').addClass('is-default');
        }
    });

    $('.applications-select').on('change', function() {
        myMap.filterCtrl('applications', this.value);
    });

    $('.town-select').on('change', function() {
        myMap.filterCtrl('town', this.value);
    });

    $('.constituency-select').on('change', function() {
        myMap.filterCtrl('constituency', this.value);
    });

    $('.stream-select').on('change', function() {
        myMap.filterCtrl('stream', this.value);
    });

    $('.party-select').on('change', function() {
        myMap.filterCtrl('party', this.value);
    });

    $('.startDate-select').on('change', function() {
        myMap.filterCtrl('startDate', this.value);
    });
});

1 个答案:

答案 0 :(得分:0)

已编辑尝试使用: 在地图上绘制所有标记后。在您拥有pushed all markers的地方使用markers数组。

new MarkerClusterer(map,markers);

请参阅此示例代码。它可能会帮助您:

<script>

$(document).ready(function(){ 

       ShowHelperMap();
}); 
  function ShowHelperMap() {
        var ctr =new google.maps.LatLng(17.3660, 78.4760);
        var Locations=JSON.parse('[{"Lat":"17.5048667","Lng":"78.4143219"},{"Lat":"17.501313","Lng":"78.4286192"},{"Lat":"17.4865184","Lng":"78.449826"},{"Lat":"17.4963517","Lng":"78.4326133"},{"Lat":"17.4939323","Lng":"78.4420625"},{"Lat":"17.4654334","Lng":"78.4554779"},{"Lat":"17.465164","Lng":"78.45617"},{"Lat":"17.4667402","Lng":"78.4576088"},{"Lat":"17.5043837","Lng":"78.4155832"}]');
         var mapOptions = {
                    center: ctr,
                    zoom: parseInt(10),
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: false,
                    streetViewControl: false
                  };
         var myInfoWindow = new google.maps.InfoWindow;
        var locationMap = new google.maps.Map(document.getElementById("map"), mapOptions);
        var l;
        var markers=[];
            if (Locations && Locations.length > 0) {
                for (l = 0; l < Locations.length; l++) {
                    store = Locations[l];               
                    var centerMarker = new google.maps.Marker({
                        position: new google.maps.LatLng(parseFloat(store.Lat), parseFloat(store.Lng)),
                        map: locationMap
                    });

                    markers.push(centerMarker);
                }
            }
            new MarkerClusterer(locationMap,markers);

        }

<div id="map" style="width:98%;height:100%;margin:0 auto;" ></div>