กรองเครื่องหมาย Google Map ด้วยช่องทำเครื่องหมาย [และตัดกัน] หลายช่อง

ฉันไม่สามารถทำให้ระบบการกรองช่องทำเครื่องหมายหลายช่องทำงานได้ ฉันจะอธิบายปัญหา การวิจัยที่ฉันทำที่นี่เกี่ยวกับ Stackoverflow และสาเหตุที่ฉันยังต้องการความช่วยเหลือหลังจากนั้น

ปัญหาของฉันคือกล่องกาเครื่องหมายของฉันไม่สามารถนำเครื่องหมายกลับมาได้ เมื่อฉันค่อยๆ ยกเลิกการเลือก ตัวกรองเหล่านี้ทำงานได้ดีเมื่อฉันคลิกตัวกรอง เนื่องจากตัวกรองค่อยๆ จางหายไปกับเครื่องหมายที่เกี่ยวข้อง อย่างไรก็ตาม หลังจากยกเลิกการเลือกช่องทำเครื่องหมายเหล่านี้สองสามช่อง เครื่องหมายทั้งหมดจะกลับมาบนหน้าจอ และช่องสุดท้ายจะไม่ทำอะไรเลยเมื่อยกเลิกการคลิกในที่สุด

นี่คือ URL ชั่วคราวของโครงการ: 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

ฉันพบโพสต์ในบล็อกที่เกี่ยวข้องหนึ่งรายการ อันนี้แนะนำให้เพิ่มหมวดหมู่ให้กับเครื่องหมาย อย่างไรก็ตาม เมื่อฉันทำเช่นนั้น ตัวกรองก็ยังคงทำงานเหมือนเดิม ฉันคิดว่าสิ่งนี้เกิดขึ้นเนื่องจากตัวกรองแต่ละตัวได้รับการตั้งโปรแกรมให้ซ่อนเครื่องหมายทุกตัวที่ตรงตามเกณฑ์การเลือก แต่เครื่องหมายแต่ละตัวมีคุณสมบัติมากกว่าหนึ่งรายการที่สามารถกรองได้

คุณรู้หรือไม่ว่ามีวิธีทำให้สคริปต์ตรวจจับจำนวนตัวกรองที่ชี้ไปยังเครื่องหมายเดียวกันหรือไม่ และแสดงกลับเฉพาะในกรณีที่ไม่มีตัวกรองชี้ไปที่นั้น นี่คือการเดาของฉันว่าจะแก้ปัญหาอย่างไร แม้ว่าฉันจะไม่รู้วิธีทำให้มันเกิดขึ้นในโค้ดก็ตาม

สุดท้ายนี้ หากคุณทราบวิธีอื่นในการทำให้ตัวกรองใช้งานได้ โปรดแจ้งให้เราทราบ


person asraelarcangel    schedule 05.03.2012    source แหล่งที่มา
comment
ฉันแบ่งปันรหัสกับเพื่อน ในความเห็นของเขา ปัญหาคือตรรกะทั้งหมดของฟังก์ชันตัวกรองมีข้อบกพร่อง และแนะนำให้เขียนใหม่ตั้งแต่ต้น เขากล่าวว่าฟังก์ชันนี้ใช้งานไม่ได้เนื่องจากขณะนี้กำลังจัดการตัวเลือกการกรองแยกจากกัน แต่ฉันสามารถเริ่มต้นด้วยการตรวจสอบว่าได้ทำเครื่องหมายในช่องอย่างน้อยหนึ่งช่องหรือไม่ ขั้นตอนต่อไปคือการตรวจสอบว่ามีการตรวจสอบจำนวนเท่าใด สุดท้าย กล่องควรรวมตัวเลือกการกรองที่แนบมาเป็นคำสั่งแบบมีเงื่อนไขเดียวที่จะแสดง/ซ่อนเครื่องหมาย ปัญหาคือต้องเขียนโค้ดนั้น ฉันยังไม่มีความคิด   -  person asraelarcangel    schedule 06.03.2012


คำตอบ (2)


ฉันสร้างแอปพลิเคชันที่มีตรรกะคล้ายกันเมื่อหลายปีก่อน http://www.ioos.gov/catalog/ แต่สำหรับ GMap 2.0 แต่ฉันคิดว่าตรรกะจะเหมือนเดิม แนวทางของฉันคือการขยายวัตถุ Google Maps Marker (ป่องแล้ว) ด้วยคุณสมบัติที่ฉันต้องการกรอง สิ่งเหล่านี้จะเป็นคุณสมบัติทั้งหมดที่คุณจัดเก็บไว้ในฟัง 'คลิก' ของคุณและอาจมากกว่านั้น: เช่น 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 ตามความต้องการ

person Eric Bridger    schedule 06.03.2012
comment
ขอบคุณมาก. ฉันกำลังทดสอบวิธีแก้ปัญหาของคุณ ฉันพบทางเลือกอื่นก่อนที่จะอ่านคำตอบของคุณ แต่ฉันไม่คิดว่าเป็นวิธีที่มีประสิทธิภาพที่สุด - person asraelarcangel; 06.03.2012

เอริคได้จัดเตรียมวิธีแก้ไขปัญหาของฉันไว้แล้ว อย่างไรก็ตาม ฉันคิดว่าชุมชนอาจได้รับประโยชน์จากการอ่านตัวเลือกอื่นๆ และฉันต้องการแบ่งปันวิธีแก้ปัญหาที่ฉันคิดขึ้นมา ถึงแม้อาจจะไม่ได้ผลดีที่สุดแต่ก็ใช้ได้

ในโค้ดที่ฉันเพิ่งพูดถึง ฉันประกาศ 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 เพื่อแสดงหรือซ่อน

นี่คือจุดเริ่มต้นของวิธีแก้ปัญหาของฉัน ภายในคำสั่ง if ด้านในสุดของฟังก์ชัน filter ฉันได้เพิ่มองค์ประกอบการตัดสินใจภายในอาร์เรย์ตัวชี้:

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);
                        }
                    }
                }
            });
        }

โดยสรุป สคริปต์ยังคงคลิกเครื่องหมายหลายครั้งหากผู้ใช้คลิกเครื่องหมายมากกว่าหนึ่งตัว ขณะนี้ระบบสามารถรับรู้ได้ว่ามีการชี้เครื่องหมายหนึ่งอันกี่ครั้ง และแสดงเฉพาะเครื่องหมายที่ไม่มีตัวชี้เลยเท่านั้น

person asraelarcangel    schedule 06.03.2012