Filter penanda Google Map dengan beberapa kotak centang [dan berpotongan].

Saya tidak dapat membuat sistem pemfilteran beberapa kotak centang berfungsi. Saya akan menjelaskan masalahnya, penelitian yang saya lakukan di sini tentang stackoverflow, dan mengapa saya masih memerlukan bantuan setelah itu.

Masalah saya adalah kotak centang saya tidak dapat mengembalikan penanda ketika saya membatalkan pilihannya secara bertahap. Filter tersebut berfungsi dengan baik ketika saya mengkliknya, karena filter tersebut secara bertahap menghilangkan penanda yang terkait dengannya. Namun, setelah membatalkan pilihan beberapa kotak centang ini, semua penanda kembali muncul di layar, dan kotak terakhir tidak melakukan apa pun ketika akhirnya tidak diklik.

Ini adalah URL sementara proyek: http://www.lcc.gatech.edu/~amartell6/php/main12.php

Ini adalah kode di mana saya terjebak:

//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

Saya menemukan satu postingan blog terkait. Yang ini menyarankan untuk menambahkan kategori ke penanda. Namun, saat saya melakukannya, filter tetap bekerja dengan cara yang sama. Saya pikir ini terjadi karena setiap filter diprogram untuk menyembunyikan setiap penanda yang memenuhi kriteria pemilihannya, namun setiap penanda memiliki lebih dari satu properti yang dapat digunakan untuk memfilter.

Tahukah Anda jika ada cara untuk membuat skrip mendeteksi berapa banyak filter yang mengarah ke penanda yang sama, dan hanya menampilkannya kembali jika tidak ada filter yang mengarah ke penanda tersebut? Ini tebakan saya bagaimana cara mengatasinya, padahal saya tidak tahu bagaimana mewujudkannya dalam kode.

Terakhir, jika Anda mengetahui cara alternatif agar filter berfungsi, beri tahu saya.


person asraelarcangel    schedule 05.03.2012    source sumber
comment
Saya berbagi kode dengan seorang teman. Menurutnya, masalahnya adalah seluruh logika fungsi filter salah, dan disarankan untuk menulis ulang dari awal. Dia mengatakan fungsinya tidak berfungsi karena saat ini menangani opsi pemfilteran secara terpisah satu sama lain. Sebaliknya, saya bisa mulai dengan memeriksa apakah setidaknya salah satu kotak dicentang. Langkah selanjutnya adalah memeriksa berapa banyak dari mereka yang benar-benar diperiksa. Terakhir, kotak harus menggabungkan opsi pemfilteran yang terlampir ke dalam satu pernyataan kondisional yang akan menampilkan/menyembunyikan penanda. Masalahnya adalah mengkodekannya. Saya belum tahu.   -  person asraelarcangel    schedule 06.03.2012


Jawaban (2)


Saya membuat aplikasi dengan logika serupa beberapa tahun lalu http://www.ioos.gov/catalog/ Tapi itu untuk GMap 2.0 tapi menurut saya logikanya akan sama. Pendekatan saya adalah memperluas objek Penanda peta Google (sudah membengkak) dengan fitur yang ingin saya filter. Ini adalah semua properti yang Anda simpan di pendengar 'klik' dan mungkin lebih banyak lagi: mis. item.title, item_start_date, dll. apa pun yang Anda inginkan untuk memfilter penanda Anda.

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

Kemudian ketika Anda ingin memfilter loop melalui semua penanda, periksa nilai penanda terhadap kondisi filter dan setVisible(true) atau false sesuai kebutuhan.

person Eric Bridger    schedule 06.03.2012
comment
Terima kasih banyak. Saya sedang menguji solusi Anda. Saya telah menemukan alternatif tepat sebelum membaca jawaban Anda, tetapi menurut saya itu bukan cara yang paling efisien. - person asraelarcangel; 06.03.2012

Erik sudah memberikan solusi untuk masalah saya. Namun, menurut saya komunitas dapat memperoleh manfaat dengan membaca opsi lain, dan saya ingin berbagi solusi yang saya temukan. Sekalipun ini bukan cara yang paling efektif, namun cara ini berhasil.

Dalam kode yang baru saja saya sebutkan, saya mendeklarasikan semua storyMarkers sekaligus ketika peta diinisialisasi:

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

Sekarang, saya menambahkan argumen baru ke penanda, tetapi alih-alih membuat variabel seperti pada contoh yang saya temukan di postingan lain, argumen ini adalah array kosong:

storyMarker.pointer = [];

Fungsi filter sebelumnya memiliki tiga level. Tingkat pertama mendeteksi perubahan pada kotak centang. Yang kedua memverifikasi apakah kotak centang telah dicentang atau tidak. Tingkat ketiga menjalankan filter pada setiap penanda, baik untuk menampilkan atau menyembunyikannya.

Di sinilah solusi saya dimulai. Dalam pernyataan if yang paling dalam dari fungsi filter, saya menambahkan elemen diskresi dalam array pointer:

storyMarker.pointer.push("elemen");

Tepat setelah ini, saya membuat pernyataan if baru untuk memeriksa apakah array tidak kosong. Jika memang tidak kosong, program akan menyembunyikan penanda milik array ini.

Program ini membalikkan logika ketika sebuah kotak tidak dicentang. Ini membatalkan filter, mengurangi satu elemen dari array yang terkait dengan penanda tersebut, dan kemudian memeriksa apakah ada penanda lain yang terkait dengannya. Sistem kini hanya menampilkan penanda yang susunannya kosong.

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

Singkatnya, skrip masih mengklik penanda beberapa kali jika pengguna mengklik lebih dari satu penanda. Sistem sekarang dapat mengenali berapa kali satu penanda ditunjukkan, dan hanya menampilkan penanda yang tidak memiliki petunjuk sama sekali.

person asraelarcangel    schedule 06.03.2012