使用多个[和相交]复选框过滤Google地图标记

时间:2012-03-05 23:09:49

标签: google-maps-api-3 filter checkbox

我不能让我的多重复选框过滤系统工作。我将解释这个问题,我在这里对stackoverflow进行的研究,以及为什么我之后仍然需要帮助。

我的问题是,当我逐渐取消选中时,我的复选框无法带回标记。当我点击它们时,这些过滤器效果很好,因为它们逐渐淡化与它们相关的标记。但是,在取消选中其中几个复选框后,所有标记都会返回到屏幕上,最后一个框在最终未被点击时不会执行任何操作。

这是项目的临时网址:http://www.lcc.gatech.edu/~amartell6/php/main12.php

这是我陷入困境的代码:

//this getJson function exists within an init funciton where a map 
//has already been called
$.getJSON(theUrl,function(result){



    $.each(result, function(i, item){

        //get Longitude
        var latCoord = item.coordinate;
        var parenthCoord = latCoord.indexOf(",");
        var partiaLat = latCoord.substr(1,parenthCoord-1);
        var lat = parseFloat(partiaLat);
        //alert(lat);

        //get Latitude
        var lngCoord = item.coordinate;
        var commaCoord = lngCoord.indexOf(",");
        var partiaLng = lngCoord.substr(commaCoord+1);
        var lng = parseFloat(partiaLng);
        //alert(lng);


        // display ALL the story markers
        var storyMarker;
        storyMarker = new google.maps.Marker({
            position: new google.maps.LatLng(lat, lng),// ----- > whithin the mutidimentional array, 
            map: map
        });


        //display the stories by clicking on the markers
        google.maps.event.addListener(storyMarker, 'click', function() {
            var from = "From ";
            if(item.end_date != ""){
                item.end_date = " to " + item.end_date;
            }
            else{
                from = "";
            }

            $('#output').html(
                '<p><span class="selected">Type of Entry: </span>' + 
                item.entry_type + ' <br/><br/>'+
                '<span class="selected">Title: </span>'+ item.entry_title + '<br/><br/>' +
                '<span class="selected">Date(s):</span><br/>'+ from +item.start_date+
                //' to '+item.end_date+'<br/><br/>'+
                item.end_date+'<br/><br/>'+
                '<span class="selected">Content:</span><br/><br/> '+ item.entry 
                +'</p>'
            );
        });// end of story displays


        //call filters from filter funciton
        filter('#evacuation-filter',item.evacuation,"Yes");
        filter('#evacuation-order-filter',item.evacuation_order,"Yes");
        filter('#w-nearby-filter',item.w_nearby,"Yes");
        filter('#hurricane-reached-filter',item.hurricane_reached,"Yes");
        filter('#outdoors-filter',item.in_out_doors,"Outdoors Most of the Time");
        filter('#indoors-filter',item.in_out_doors,"Indoors Most of the Time");
        filter('#food-filter',item.food,"Yes");
        filter('#windows-filter',item.windows,"Yes");
        filter('#power-filter',item.power,"Yes");
        filter('#wounded-filter',item.wounded,"Yes");
        filter('#looting-filter',item.looting,"Yes");
        filter('#blackouts-filter',item.blackouts,"Yes");
        filter('#trees-filter',item.trees,"Yes");
        filter('#powerlines-filter',item.powerlines,"Yes");
        filter('#light-filter',item.light,"Yes");
        filter('#sidewalks-filter',item.sidewalks,"Yes");
        filter('#buildings-filter',item.buildings,"Yes");
        filter('#flooding-filter',item.flooding,"Yes");


        //FILTER FUNCTION
        //first parameter is the checkbox id, the second is the filter criteria
        //(the filter function has to be called within the $.each loop to be within scope)

        var otherFilter = false;

        function filter(id, criterion1, value){

            var activeFilters = [];

            $(id).change(function() {
                //evalute if the checkbox has been "checked" or "unchecked"
                var checkBoxVal = $(id).attr("checked");

                //if it's been checked:
                if(checkBoxVal=="checked"){
                    //1 - Get markers that don't talk about the filter
                    if(criterion1!=value && storyMarker.getVisible()==true){
                        //2 - fade them away, and leave only those meet the criteria
                        storyMarker.setVisible(false); 
                        otherFilter = true;
                        activeFilters.push(criterion1);
                        //document.getElementById("text3").innerHTML=activeFilters+"<br/>";
                        //alert(activeFilters.push(criterion1) +","+criterion1.length);
                    }
                }
                //if it's been unchecked:
                else if(checkBoxVal==undefined){
                    //1 - Get markers that don't talk about the filter
                    if(criterion1!=value && storyMarker.getVisible()==false){
                        //2 - Show them again
                        storyMarker.setVisible(true);
                        otherFilter = false;
                        activeFilters.pop(criterion1);
                        //alert(activeFilters.pop(criterion1) +","+criterion1.length);
                    } //end of if to cancel filter and bring markers and stories back
                }

            }); // end of change event

        } // end of filter function


        //var otherDropDown = false;
        filter2("#media-filter",item.media);
        filter2("#authorities-filter",item.authorities);

        //---------------

        function filter2(id2,criterion2){

            $(id2).change(function() {
                //get the value of the drowpdown menu based on its id
                var dropDownVal = $(id2).attr("value");
                var all="All";
                //if the value isn't "All", other filters have not been applied, and marker is on screen
                if(dropDownVal!=all && otherFilter==false){
                    //1 - check if the marker doesn't comply with filter
                    if(criterion2!=dropDownVal){
                        //2 - fade them away if not, and leave only those meet the criteria
                        storyMarker.setVisible(false);
                    //3 - If the marker does comply with it
                    }else if(criterion2==dropDownVal){
                        //4 - keep it there
                        storyMarker.setVisible(true);
                    }//end of filter applier
                //else if if the value IS "All", filters have not been applied, and marker is faded
                }else if(dropDownVal==all && otherFilter==false){
                    //select all the possible values for the cirterion
                    if(criterion2!=undefined){
                        //and show all those markers
                        storyMarker.setVisible(true);
                    }
                }
            }); 
        }   //end of function filter2



    }); // end of $.each
}); // end of $.getJSON

我找到了one related blog post。这个建议在标记中添加一个类别。但是,当我这样做时,过滤器保持相同的工作方式。我认为这是因为每个过滤器都被编程为隐藏符合其选择标准的每个标记,但每个标记都有多个属性可以过滤。

您知道是否有办法让脚本检测到有多少过滤器指向同一个标记,并且只有在没有过滤器指向它时才显示它?这是我对如何解决它的猜测,即使我不知道如何在代码中实现它。

最后,如果你知道使过滤器工作的其他方法,请告诉我。

2 个答案:

答案 0 :(得分:1)

我几年前创建了一个类似逻辑的应用程序http://www.ioos.gov/catalog/但它适用于GMap 2.0,但我认为逻辑是相同的。 我的方法是使用我想过滤它们的功能扩展Google地图标记对象(已经膨胀)。 这些将是您在“点击”收听者中存储的所有属性,或许更多:例如: item.title,item_start_date等等,无论你最终想要过滤你的标记。

var all_markers = [];
storyMarker.end_date = item.end_date;
storMarker.title = item.title;
...
all_markers.push(storyMarker);

然后,当您想要通过所有标记过滤循环时,请根据过滤条件检查标记值,并根据需要检查setVisible(true)或false。

答案 1 :(得分:1)

Erik已经为我的问题提供了解决方案。但是,我认为社区可能会从阅读其他选项中受益,我想分享我想出的解决方案。即使它可能不是最有效的,它也可以。

在我刚才提到的代码中,我在地图初始化时立即声明了所有的storyMarkers:

        // display ALL the story markers
        var storyMarker;
        storyMarker = new google.maps.Marker({
            position: new google.maps.LatLng(lat, lng),// ----- > whithin the mutidimentional array, 
            map: map
        });

现在,我为标记添加了一个新参数,但不是像我在其他帖子中找到的示例中那样创建变量,而是这个参数是一个空数组:

storyMarker.pointer = [];

之前的过滤功能有三个级别。第一级检测到复选框中的更改。第二个验证复选框是已选中还是未选中。第三级在e-v-e-r-y标记上运行过滤器,以显示或隐藏它。

这是我的解决方案开始的地方。在filter函数的最内部if语句中,我在指针数组中添加了一个自由选择元素:

storyMarker.pointer.push( “元素”);

在此之后,我嵌套了一个新的if语句来检查数组是否为空。如果它确实不为空,则程序会隐藏此数组所属的标记。

当取消选中框时,程序会反转逻辑。它调用过滤器,从与该标记关联的数组中减去一个元素,然后检查是否有其他标记与之关联。系统现在只显示其数组为空的标记。

//alert(storyMarker.pointer);
        function filter(id,criterion,value){
            $(id).change(function() {
                var checkBoxVal = $(id).attr("checked");
                if(checkBoxVal=="checked"){
                    if(criterion!=value){
                        storyMarker.pointer.push("element");
                        //alert("array length: "+storyMarker.pointer.length);
                        if(storyMarker.pointer.length>0){
                            storyMarker.setVisible(false);
                        }
                    }
                }
                else if(checkBoxVal!="checked"){
                    if(criterion!=value){
                        storyMarker.pointer.pop("element");
                        //alert("array length: "+storyMarker.pointer.length);
                        if(storyMarker.pointer.length<=0){
                            storyMarker.setVisible(true);
                        }
                    }
                }
            });
        }

总之,如果用户点击多个标记,脚本仍会多次单击标记。系统现在可以识别指出一个标记的次数,并且只显示没有指针的那个。