谷歌地图apiv3 - 多个下拉类别/过滤器标记结果

时间:2014-02-11 02:02:50

标签: javascript google-maps-api-3

所以我试图用两个下拉菜单过滤标记结果:1)。选择/显示类别一或两个。和2)。选择/仅显示活动或非活动。我得到了主动或非主动工作,但第一个下拉菜单不能与另一个一起使用。

<script>
(function() {
          var geocoder;

        var clusterer;

            window.onload = function() {

              // Creating a new map
              // Create a variable to make the map hover over Manchester upon initialising
    var map = new google.maps.LatLng(53.466808, -2.233936);
            var mapOptions = {
             center: map,
              zoom: 3,
              mapTypeId: google.maps.MapTypeId.ROADMAP,

    // end of the JSON script. If this could be referenced as an external resource that might be useful...
       }; 
       // the MapOptions variable is finished now
    // the map is defined below...
            var map = new google.maps.Map(document.getElementById("map"),
                mapOptions);

              //var selectDiv = $("#category_panel")[0];
              //map.controls[google.maps.ControlPosition.TOP_LEFT].push(selectDiv);


              var json = [
      {
        "title": "One",
        "lat": 58.9,
        "lng": 15.8,
        "description": "this is category Two and nonactive",
        "category" : [ "two" ],
        "status" : [ "nonactive" ]
      },
      {
        "title": "Two",
        "lat": 59.9,
        "lng": 10.8,
        "description": "This is in category One and is non-active",
        "category" : [ "one" ],
        "status" : [ "nonactive" ]
      },
      {
        "title": "Three",
        "lat": 55.7,
        "lng": 12.6,
        "description": "this is cateogory one and is active",
        "category" : [ "one" ],
        "status" : [ "active" ]
      },
      {
        "title": "Four",
        "lat": 59.9,
        "lng": 10.8,
        "description": "this is in category two is and active",
        "category" : [ "two" ],
        "status" : [ "active" ]
      }
    ];




              // Custom marker - Need one for each category
              var image = new google.maps.MarkerImage(
                'http://i.imgur.com/3YJ8z.png',
                new google.maps.Size(19, 25), // size of the image
                new google.maps.Point(0, 0) // origin, in this case top-left corner
              );

              // Creating a global infoWindow object that will be reused by all markers
              var infoWindow = new google.maps.InfoWindow();

              // Marker Clusterer setup
              var mcOptions = {
                gridSize : 50,
                maxZoom : 15
              };
              clusterer = new MarkerClusterer(map, [], mcOptions);

              var markers = {};
              var categoryIcons = {
                "one" : "https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=1%7CFF0000%7C000000",
                "two" : "https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=2%7C00FFFF%7C000000",
                "three" : "https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=3%7CFF00FF%7C000000"
              }

              var statusIcons = {
                "active" : "https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=10%7C00FFFF%7C000000",
                "nonactive" : "https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=20%7C00FFFF%7C000000",

              }

              // Looping through the JSON data
              for (var i = 0, length = json.length; i < length; i++) {
                var data = json[i],
                    latLng = new google.maps.LatLng(data.lat, data.lng),
                    category = data.category;
                    status = data.status;

                if (category in markers == false) {
                  markers[category] = [];
                }

                //adding Status the category

                 if (status in markers == false) {
                  markers[status] = [];
                }



                // Creating a marker and putting it on the map
                var marker = new google.maps.Marker({
                  position : latLng,
                  title : data.title,
                  icon : categoryIcons[data.category],
                  icon: statusIcons[data.status]

                });
                markers[category].push(marker);

                 markers[status].push(marker);

                // Creating a closure to retain the correct data, notice how I pass the current data in the loop into the closure (marker, data)
                (function(marker, data) {

                  // Attaching a click event to the current marker
                  google.maps.event.addListener(marker, "click", function(e) {
                    infoWindow.setContent(data.description);
                    infoWindow.open(map, marker);
                  });
                })(marker, data);

              }// END for loop

              $("#category").change(function(){
                var selected = $(this).val();
                clusterer.clearMarkers();
                clusterer.addMarkers(markers[selected]);
              });
              $("#category").change();



             $("#categoryAlt").change(function(){
                var selected = $(this).val();
                clusterer.clearMarkers();
                clusterer.addMarkers(markers[selected]);
              });
              $("#categoryAlt").change();





            }// END window.onload


          })();


          function initialize() {
        geocoder = new google.maps.Geocoder();


     }
</script>

这是我的Html

<div id="category_panel">
    category:<select id="category">

      <option value="two">one</option>
      <option value="one">two</option>
      <!--<option value="three">three</option>-->

    </select>


    Status:<select id="categoryAlt">
        <option value="">Nothing</option>
      <option value="active">Active</option>
      <option value="nonactive">Non-active</option>


    </select>

  </div>

2 个答案:

答案 0 :(得分:2)

下拉列表中存在错误:值已反转:

    Category:<select id="category">
        <option value="two">one</option>
        <option value="one">two</option>
        <!--<option value="three">three</option>-->
    </select>

他们应该是:

    Category:<select id="category">
        <option value="one">one</option>
        <option value="two">two</option>
        <!--<option value="three">three</option>-->
    </select>

以下错误:

Uncaught TypeError: Cannot read property 'length' of undefined 
通过处理程序

选择下拉状态Nothing来触发

$("#status").change(function() {
    var selected = $(this).val();
    clusterer.clearMarkers();
    clusterer.addMarkers(markers[selected]);
});
$("#status").change();

标记[&#39; Nothing&#39;]不存在。所以,我评论了它。

从json数据我们得到带有4个两个元素数组的marker数组。要正确过滤它,我们必须更改categorystatus更改处理程序,并使用其他下拉列表中的选择。过滤是根据标题完成的,更好的选择是在位置上(它需要更多的工作):

$("#category").change(function() {
    var selected = $(this).val();
    var statusSelected = $("#status").val();

    clusterer.clearMarkers();

    for (var i = 0; i < markers[selected].length; i++) {
        for (var j = 0; j < markers[statusSelected].length; j++) {
            if (markers[selected][i]['title'] == 
                markers[statusSelected][j]['title']) {
                clusterer.addMarkers([markers[selected][i]]);
            }
        }
    }
    // clusterer.addMarkers(markers[selected]);
});
$("#category").change();

$("#status").change(function() {
    var selected = $(this).val();
    var categorySelected = $("#category").val();

    clusterer.clearMarkers();
    for (var i = 0; i < markers[selected].length; i++) {
        for (var j = 0; j < markers[categorySelected].length; j++) {
            if (markers[selected][i]['title'] == 
                markers[categorySelected][j]['title']) {
                clusterer.addMarkers([markers[selected][i]]);
            }
        }
    }
    //clusterer.addMarkers(markers[selected]);
});
$("#status").change();

更改的代码位于jsbin example注意:它没有在那里工作,因为markerclusterer.js文件没有有效的链接。

顺便说一句,我从来没有像这样设计它。我只构建一个标记列表,其中包含有关状态和类别的信息,可以一次性过滤掉。

更新:回答@Freddie评论

我没有写任何东西,但它会像下面这样。 MarkerInfo对象包含有关已创建标记的信息:

function MarkerInfo(marker, status, category) {
    this.marker = marker;
    this.status = status;
    this.category = category;
}

markerList数组包含已创建的MarkerInfo列表(在init上为空,最后长度应与标记数相同):

var markerList = [];

如何填写:

for/while reading from json
    read data for new marker (location, status, category...)
    create marker
    var markerInfo = new MarkerInfo(marker, status, category);
    markerList.push(markerInfo);

$("#category").change(function() {...})$("#status").change(function() {...})可以通过一个循环过滤掉标记。

类似的东西。

答案 1 :(得分:0)

类别的选择框似乎显示文本和值不匹配。

这些下拉不会互相过滤。您正在查看所有活动/非活动或全部一个/两个。

如果您想同时选择两个框来过滤地图,请尝试以下方法:



generateMarkers= function(category, status){
    return json.filter(function(item){
        return (!category || item.category.indexOf(category) !== -1) 
               && (!status || item.status.indexOf(status) !== -1);
    }).map(function(item){
        // generate your markers here
        return item.category+'_'+item.status;
    });
};
console.log(generateMarkers('two','nonactive'));

//clusterer.addMarkers(generateMarkers('two','nonactive'));