【问题标题】:How to filter Google Maps markers in one array with select?如何使用选择过滤一个数组中的谷歌地图标记?
【发布时间】:2014-04-14 21:48:00
【问题描述】:

我在我的站点中实现了一个带有一个数组的谷歌地图,如下所示:

var gmarkers1 = [];
var markers1 = [];

markers1 = [
['0', 'Title', 52.4357808, 4.991315699999973],
['1', 'Title', 52.4357808, 4.991315699999973],
['2', 'Title', 52.4555687, 5.039231599999994],
];

在此示例中,有 3 个标记,但实际上还有更多。就我而言,这是唯一的方法(一个数组)。

问题:我希望能够使用选择框在此数组中进行过滤。因此,用户从选择中选择“汽车”,而 Google 地图仅显示带有属性 (?)“汽车”的标记。

标记显示如下:

for (i = 0; i < markers1.length; i++) {
    var category;
    var pos = new google.maps.LatLng(markers1[i][2], markers1[i][3]);
    var content = markers1[i][1];
    bounds.extend(pos);
    marker1 = new google.maps.Marker({
        position: pos,
        map: map,
        icon: image1
    });

    gmarkers1.push(marker1);
    // [START]-Event listener to center view and go to position
    google.maps.event.addListener(marker1, 'click', (function(marker1, content) {
        return function() {
          console.log('Gmarker 1 gets pushed')
            infowindow.setContent(content);
            infowindow.open(map, marker1);
            map.panTo(this.getPosition());
            map.setZoom(15);
        }
    })(marker1, content));
}

【问题讨论】:

    标签: arrays google-maps google-maps-api-3 drop-down-menu google-maps-markers


    【解决方案1】:

    您应该将类​​别添加为标记属性。

    markers1 = [
        ['0', 'Title 1', 52.4357808, 4.991315699999973, 'car'],
        ['1', 'Title 2', 52.4357808, 4.981315699999973, 'third'],
        ['2', 'Title 3', 52.4555687, 5.039231599999994, 'car'],
        ['3', 'Title 4', 52.4555687, 5.029231599999994, 'second']
    ];
    

    创建标记。标记是对象,所以添加类别作为属性。

    var category = markers1[i][4];
    var pos = new google.maps.LatLng(markers1[i][2], markers1[i][3]);
    marker1 = new google.maps.Marker({
        position: pos,
        map: map,
        category: category,
        icon: image1
    });
    

    在选择更改时,调用函数检查类别是否与选择的相同。

    /**
     * Function to filter markers by category
     */
    
    filterMarkers = function(category)
    {
       for (i = 0; i < gmarkers1.length; i++) {
          marker = gmarkers1[i];
    
          // If is same category or category not picked
          if(marker.category == category || category.length == 0)
          {
              marker.setVisible(true);
          }
          // Categories don't match 
          else
          {          
              marker.setVisible(false);
          }
        }  
    }
    

    工作示例

    var gmarkers1 = [];
    var markers1 = [];
    var infowindow = new google.maps.InfoWindow({
        content: ''
    });
    
    // Our markers
    markers1 = [
        ['0', 'Title 1', 52.4357808, 4.991315699999973, 'car'],
        ['1', 'Title 2', 52.4357808, 4.981315699999973, 'third'],
        ['2', 'Title 3', 52.4555687, 5.039231599999994, 'car'],
        ['3', 'Title 4', 52.4555687, 5.029231599999994, 'second']
    ];
    
    /**
     * Function to init map
     */
    
    function initialize() {
        var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
        var mapOptions = {
            zoom: 12,
            center: center,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };
    
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        for (i = 0; i < markers1.length; i++) {
            addMarker(markers1[i]);
        }
    }
    
    /**
     * Function to add marker to map
     */
    
    function addMarker(marker) {
        var category = marker[4];
        var title = marker[1];
        var pos = new google.maps.LatLng(marker[2], marker[3]);
        var content = marker[1];
    
        marker1 = new google.maps.Marker({
            title: title,
            position: pos,
            category: category,
            map: map
        });
    
        gmarkers1.push(marker1);
    
        // Marker click listener
        google.maps.event.addListener(marker1, 'click', (function (marker1, content) {
            return function () {
                console.log('Gmarker 1 gets pushed');
                infowindow.setContent(content);
                infowindow.open(map, marker1);
                map.panTo(this.getPosition());
                map.setZoom(15);
            }
        })(marker1, content));
    }
    
    /**
     * Function to filter markers by category
     */
    
    filterMarkers = function (category) {
        for (i = 0; i < gmarkers1.length; i++) {
            marker = gmarkers1[i];
            // If is same category or category not picked
            if (marker.category == category || category.length === 0) {
                marker.setVisible(true);
            }
            // Categories don't match 
            else {
                marker.setVisible(false);
            }
        }
    }
    
    // Init map
    initialize();
    #map-canvas {
        width: 500px;
        height: 500px;
    }
    <script src="https://maps.googleapis.com/maps/api/js?key=&v=3.0&sensor=true&language=ee&dummy=dummy.js"></script>
    <div id="map-canvas"></div>
    <select id="type" onchange="filterMarkers(this.value);">
        <option value="">Please select category</option>
        <option value="second">second</option>
        <option value="car">car</option>
        <option value="third">third</option>
    </select>

    按标记上的多个类别过滤

    编辑@Myoji 评论

    要在每个标记上使用多个类别,只需将它们添加为array 并在filterMarkers 上编辑if 条件。

    markers1 = [
        ['0', 'Title 1', 52.4357808, 4.991315699999973, ['car', 'second']],
        ['1', 'Title 2', 52.4357808, 4.981315699999973, ['third']],
        ['2', 'Title 3', 52.4555687, 5.039231599999994, ['car', 'third']],
        ['3', 'Title 4', 52.4555687, 5.029231599999994, ['second']]
    ];
    

    filterMarkers 会是

    /**
     * Function to filter markers by category
     */
    
    filterMarkers = function(category)
    {
       for (i = 0; i < gmarkers1.length; i++) {
          marker = gmarkers1[i];
    
          // If is same category or category not picked
          if((typeof marker.category == 'object' && marker.category.indexOf(category) >= 0) || category.length == 0){
          {
              marker.setVisible(true);
          }
          // Categories don't match 
          else
          {          
              marker.setVisible(false);
          }
        }  
    }
    

    工作示例

    var gmarkers1 = [];
    var markers1 = [];
    var infowindow = new google.maps.InfoWindow({
        content: ''
    });
    
    // Our markers
    markers1 = [
      ['0', 'Title 1', 52.4357808, 4.991315699999973, ['car', 'second']],
      ['1', 'Title 2', 52.4357808, 4.981315699999973, ['third']],
      ['2', 'Title 3', 52.4555687, 5.039231599999994, ['car', 'third']],
      ['3', 'Title 4', 52.4555687, 5.029231599999994, ['second']]
    ];
    
    /**
     * Function to init map
     */
    
    function initialize() {
        var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
        var mapOptions = {
            zoom: 12,
            center: center,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };
    
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        for (i = 0; i < markers1.length; i++) {
            addMarker(markers1[i]);
        }
    }
    
    /**
     * Function to add marker to map
     */
    
    function addMarker(marker) {
        var category = marker[4];
        var title = marker[1];
        var pos = new google.maps.LatLng(marker[2], marker[3]);
        var content = marker[1];
    
        marker1 = new google.maps.Marker({
            title: title,
            position: pos,
            category: category,
            map: map
        });
    
        gmarkers1.push(marker1);
    
        // Marker click listener
        google.maps.event.addListener(marker1, 'click', (function (marker1, content) {
            return function () {
                console.log('Gmarker 1 gets pushed');
                infowindow.setContent(content);
                infowindow.open(map, marker1);
                map.panTo(this.getPosition());
                map.setZoom(15);
            }
        })(marker1, content));
    }
    
    /**
     * Function to filter markers by category
     */
    
    filterMarkers = function (category) {
        for (i = 0; i < gmarkers1.length; i++) {
            marker = gmarkers1[i];
            // If is same category or category not picked
            if((typeof marker.category == 'object' && marker.category.indexOf(category) >= 0) || category.length == 0){
                marker.setVisible(true);
            }
            // Categories don't match 
            else {
                marker.setVisible(false);
            }
        }
    }
    
    // Init map
    initialize();
    #map-canvas {
        width: 500px;
        height: 500px;
    }
    <script src="https://maps.googleapis.com/maps/api/js?key=&v=3.0&sensor=true&language=ee&dummy=dummy.js"></script>
    <div id="map-canvas"></div>
    <select id="type" onchange="filterMarkers(this.value);">
        <option value="">Please select category</option>
        <option value="second">second</option>
        <option value="car">car</option>
        <option value="third">third</option>
    </select>

    过滤后拟合边界

    编辑@bluantinoo 评论

    /**
     * Function to filter markers by category
     */
    
    filterMarkers = function(category)
    {
        var bounds = new google.maps.LatLngBounds();
        for (i = 0; i < gmarkers1.length; i++) {
            marker = gmarkers1[i];
    
            // If is same category or category not picked
            if(marker.category == category || category.length == 0)
            {
                marker.setVisible(true);
                bounds.extend(marker.getPosition());
            }
            // Categories don't match 
            else
            {          
                marker.setVisible(false);
            }
            map.fitBounds(bounds);
        }  
    }
    

    工作示例

    var gmarkers1 = [];
    var markers1 = [];
    var infowindow = new google.maps.InfoWindow({
        content: ''
    });
    
    // Our markers
    markers1 = [
        ['0', 'Title 1', 52.4357808, 4.991315699999973, 'car'],
        ['1', 'Title 2', 52.4357808, 4.981315699999973, 'third'],
        ['2', 'Title 3', 52.4555687, 5.039231599999994, 'car'],
        ['3', 'Title 4', 52.4555687, 5.029231599999994, 'second']
    ];
    
    /**
     * Function to init map
     */
    
    function initialize() {
        var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
        var mapOptions = {
            zoom: 12,
            center: center,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };
    
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        for (i = 0; i < markers1.length; i++) {
            addMarker(markers1[i]);
        }
    }
    
    /**
     * Function to add marker to map
     */
    
    function addMarker(marker) {
        var category = marker[4];
        var title = marker[1];
        var pos = new google.maps.LatLng(marker[2], marker[3]);
        var content = marker[1];
    
        marker1 = new google.maps.Marker({
            title: title,
            position: pos,
            category: category,
            map: map
        });
    
        gmarkers1.push(marker1);
    
        // Marker click listener
        google.maps.event.addListener(marker1, 'click', (function (marker1, content) {
            return function () {
                console.log('Gmarker 1 gets pushed');
                infowindow.setContent(content);
                infowindow.open(map, marker1);
                map.panTo(this.getPosition());
                map.setZoom(15);
            }
        })(marker1, content));
    }
    
    /**
     * Function to filter markers by category
     */
    
    filterMarkers = function(category)
    {
        var bounds = new google.maps.LatLngBounds();
        for (i = 0; i < gmarkers1.length; i++) {
            marker = gmarkers1[i];
    
            // If is same category or category not picked
            if(marker.category == category || category.length == 0)
            {
                marker.setVisible(true);
                bounds.extend(marker.getPosition());
            }
            // Categories don't match 
            else
            {          
                marker.setVisible(false);
            }
            map.fitBounds(bounds);
        }  
    }
    
    // Init map
    initialize();
    #map-canvas {
        width: 500px;
        height: 500px;
    }
    <script src="https://maps.googleapis.com/maps/api/js?key=&v=3.0&sensor=true&language=ee&dummy=dummy.js"></script>
    <div id="map-canvas"></div>
    <select id="type" onchange="filterMarkers(this.value);">
        <option value="">Please select category</option>
        <option value="second">second</option>
        <option value="car">car</option>
        <option value="third">third</option>
    </select>

    【讨论】:

    • @Rene Korss 你可以在每个标记上使用多个类别,例如 ['car, 'second' 'blue'] 吗?
    • @ReneKorss,你能展示如何使用多个选择列表进行过滤吗?
    • @monymirza 你能提供更多信息吗?你的意思是多个过滤器?
    • @ReneKorss 这仍然是网络上最好的答案,但我们还可以改进一点:有没有办法在过滤后对可见标记进行限制?
    • @bluantinoo 查看我的编辑,“过滤后拟合边界”部分。
    【解决方案2】:

    在@Rene Korss 的解决方案之上构建,这里是基于复选框的多选过滤器,但可以很容易地成为多选列表 - 只需获取带有要比较的选项名称的数组。

    var gmarkers1 = [];
    var markers1 = [];
    var infowindow = new google.maps.InfoWindow({
      content: ''
    });
    // Our markers
    markers1 = [
      ['0', 'Title 1', 52.4357808, 4.991315699999973, ['car', 'second']],
      ['1', 'Title 2', 52.4357808, 4.981315699999973, ['third']],
      ['2', 'Title 3', 52.4555687, 5.039231599999994, ['car', 'third']],
      ['3', 'Title 4', 52.4555687, 5.029231599999994, ['second']]
    ];
    markerCount = markers1.length
    // Function to init map
    function initialize() {
      var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
      var mapOptions = {
        zoom: 12,
        center: center,
        mapTypeId: google.maps.MapTypeId.TERRAIN
      };
    
      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
      for (i = 0; i < markerCount; i++) {
        addMarker(markers1[i]);
      }
    }
    // Function to add marker to map
    function addMarker(marker) {
      var category = marker[4];
      var title = marker[1];
      var pos = new google.maps.LatLng(marker[2], marker[3]);
      var content = marker[1];
    
      marker1 = new google.maps.Marker({
        title: title,
        position: pos,
        category: category,
        map: map
      });
    
      gmarkers1.push(marker1);
    
      // Marker click listener
      google.maps.event.addListener(marker1, 'click', (function(marker1, content) {
        return function() {
          console.log('Gmarker 1 gets pushed');
          infowindow.setContent(content);
          infowindow.open(map, marker1);
          map.panTo(this.getPosition());
          map.setZoom(15);
        }
      })(marker1, content));
    }
    // Function on Change of checkbox
    updateView = function(element) {
      if (element) {
        //Get array with names of the checked boxes
        checkedBoxes = ([...document.querySelectorAll('input[type=checkbox]:checked')]).map(function(o) {
          return o.id;
        });
        console.log(checkedBoxes);
        for (i = 0; i < markerCount; i++) {
          marker = gmarkers1[i];
          console.log(marker.category)
          //Filter to show any markets containing ALL of the selected options
          if (typeof marker.category == 'object' && checkedBoxes.every(function(o) {
              return (marker.category).indexOf(o) >= 0;
            })) {
            marker.setVisible(true);
          } else {
            marker.setVisible(false);
          }
        }
      } else {
        console.log('No param given');
      }
    }
    // Init map
    initialize();
    #map-canvas {
      width: 500px;
      height: 500px;
    }
    <script src="https://maps.googleapis.com/maps/api/js?key=&v=3&language=ee&dummy=dummy.js"></script>
    <div id="map-canvas"></div>
    <div id="options">
      <input type="checkbox" id="car" onchange="updateView(this);" /> Car
      <input type="checkbox" id="second" onchange="updateView(this);" /> Second
      <input type="checkbox" id="third" onchange="updateView(this);" /> Third
    </div>

    基本上,您只需得到一个包含所选复选框 id 名称的数组:

    checkedBoxes = ([...document.querySelectorAll('input[type=checkbox]:checked')]).map(function(o) { return o.id; });

    然后,您比较每个位置类别,如果包含所有选中的复选框但可能有更多未选中的复选框,则显示它。如果没有选择,则显示全部:

    if(typeof marker.category == 'object' && checkedBoxes.every(function (o) {return (marker.category).indexOf(o) >= 0;})){
          marker.setVisible(true);
    }
    else {
          marker.setVisible(false);
    }
    

    这里也是JSfiddle

    更新: 根据此处的评论请求,代码 sn-p 除非您检查某些内容,否则不会显示任何内容。此外,逻辑是您需要选择完全相同的类别作为标记才能可见。

    var gmarkers1 = [];
    var markers1 = [];
    var infowindow = new google.maps.InfoWindow({
      content: ''
    });
    // Our markers
    markers1 = [
      ['0', 'Title 1', 52.4357808, 4.991315699999973, ['car', 'second']],
      ['1', 'Title 2', 52.4357808, 4.981315699999973, ['third']],
      ['2', 'Title 3', 52.4555687, 5.039231599999994, ['third', 'car']],
      ['3', 'Title 4', 52.4555687, 5.029231599999994, ['second']]
    ];
    markerCount = markers1.length
    // Function to init map
    function initialize() {
      var center = new google.maps.LatLng(52.4357808, 4.991315699999973);
      var mapOptions = {
        zoom: 12,
        center: center,
        mapTypeId: google.maps.MapTypeId.TERRAIN
      };
    
      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
      for (i = 0; i < markerCount; i++) {
        addMarker(markers1[i]);
      }
    }
    // Function to add marker to map
    function addMarker(marker) {
      var category = marker[4];
      var title = marker[1];
      var pos = new google.maps.LatLng(marker[2], marker[3]);
      var content = marker[1];
    
      marker1 = new google.maps.Marker({
        title: title,
        position: pos,
        category: category,
        map: map
      });
    
      gmarkers1.push(marker1);
    
      // Marker click listener
      google.maps.event.addListener(marker1, 'click', (function(marker1, content) {
        return function() {
          console.log('Gmarker 1 gets pushed');
          infowindow.setContent(content);
          infowindow.open(map, marker1);
          map.panTo(this.getPosition());
          map.setZoom(15);
        }
      })(marker1, content));
    }
    // Function on Change of checkbox
    updateView = function(element) {
      if (element) {
        //Get array with names of the checked boxes
        checkedBoxes = ([...document.querySelectorAll('input[type=checkbox]:checked')]).map(function(o) {
          return o.id;
        });
        console.log(checkedBoxes);
        for (i = 0; i < markerCount; i++) {
          marker = gmarkers1[i];
          console.log(marker.category)
          //Filter to show any markets containing ALL of the selected options
          if(typeof marker.category == 'object' && marker.category.length === checkedBoxes.length && checkedBoxes.reduce((a, b) => a && marker.category.includes(b), true)){
            marker.setVisible(true);
          } else {
            marker.setVisible(false);
          }
        }
      } else {
        console.log('No param given');
      }
    }
    // Init map
    initialize();
    #map-canvas {
      width: 500px;
      height: 500px;
    }
    <script src="https://maps.googleapis.com/maps/api/js?key=&v=3&language=ee&dummy=dummy.js"></script>
    <div id="map-canvas"></div>
    <div id="options">
      <input type="checkbox" id="car" onchange="updateView(this);" /> Car
      <input type="checkbox" id="second" onchange="updateView(this);" /> Second
      <input type="checkbox" id="third" onchange="updateView(this);" /> Third
    </div>

    还有JSfiddle

    【讨论】:

    • 感谢您的回答。您能否更改脚本以添加标记。例如,我检查了“Car”和“Second”,它显示了三个包含“car”或“second”的标记。根本不在一个标记中。
    • 用反向逻辑更新了我的评论。
    • 您如何使用街道地址而不是 lat、lng 坐标来实现上述功能?
    猜你喜欢
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    相关资源
    最近更新 更多