gmaps.js根据特定条件删除标记

时间:2015-02-15 16:00:00

标签: javascript json google-maps gmaps.js

我正在创建一个地图,使用gmaps.js,它有不同类型的标记(停车,住宅和学术)。 gmaps.js的removeMarkers()函数不接受任何参数,它只隐藏所有内容。

如果选中复选框,我的目标是为每个类别显示/隐藏相应标记的复选框。与JSFiddle链接的此previous question with a similar problem类似。我的代码与上述问题中的代码类似,但当我选中其中一个框时,我在控制台的Uncaught TypeError: Cannot read property 'length' of undefined中获得了jquery.min.js:2。另一件不同的是我从JSON文件获取数据并将其存储到数组中。

这是我的代码:

$.getJSON("json/map-data.json", function(data) {
    gMarkers['parking'] = [], gMarkers['academic'] = [], gMarkers['residence'] = [];
    // Loop through each feature in the JSON file
    for (var i = 0; i < data.features.length; i++) {
        features.push(data.features[i]);
        types.push(features[i].properties.type);
        descriptions.push(features[i].properties.description);
        titles.push(features[i].properties.title);
        markers.push(features[i].geometry.point);
        polygons.push(features[i].geometry.polygon);
        // store JSON data to temporary variable to later push to an array
        var markerForArray = {
            lat: markers[i][0],
            lng: markers[i][4],
            title: titles[i],
            infoWindow: {
                content: descriptions[i]
            }
        };

        // Store markerForArray sorted by "type"
        if (types[i] === 'parking')
            gMarkers['parking'].push(markerForArray);
        else if (types[i] === 'residence')
            gMarkers['residence'].push(markerForArray);
        else if (types[i] === 'academic')
            gMarkers['academic'].push(markerForArray);
    };

    /* Takes the poi type as a parameter */
    GMaps.prototype.addMarkersOfType = function (poi_type) {
        // save the relevant map
        console.log(gMarkers['parking'][0]);
        var theMap = this.map;
        // clear markers of this type
        realMarkers[poi_type]=[];
        // for each Gmaps marker
        $.each(gMarkers[poi_type],function(index, obj){
            // add the marker
            var marker = map.addMarkers(obj);
            // save it as real marker
            realMarkers[poi_type].push(marker);
       });
    }

    /* Takes the poi type as a parameter */
    GMaps.prototype.removeMarkersOfType = function (poi_type) {
        // for each real marker of this type
        $.each(realMarkers[poi_type], function(index, obj){
            // remove the marker
            obj.setMap(null);
        });
        // clear markers of this type
        realMarkers[poi_type]=[];
    }

    $('input[type="checkbox"').click(function() {
        var poi_type = $(this).attr('name');
        if ($(this).is(':checked'))
            map.addMarkersOfType(poi_type);
        else
            map.removeMarkersOfType(poi_type);
    });
});

JSON数据如下所示:

{
    "type": "Feature",
    "properties": {
        "title": "Parking Lot #1",
        "type": "parking",
        "description": ""
      },
    "geometry": {
        "point": [12.12345, -12.12345],
        "polygon":  [
            [12.12245, 12.12845],
            [12.12345,-12.12745],
            [12.12445,-12.12645],
            [12.12545,-12.12545]
        ]
    }
}

以下是我在JSFiddle上的代码:http://jsfiddle.net/88cakes/sw9m4vyo/4/

1 个答案:

答案 0 :(得分:0)

我必须承认我没有尝试找到问题,因为你的方法看起来并不好,所有这些存储不同对象的数组都是不必要的。

而是为每个复选框创建一个MVCObject,并为此MVCObject创建一个属性,其值将通过更改侦听器设置为map(已选中)或null(未选中)。

   mapData.features.forEach(function(item){
     //the checkbox related to the item-type
     var box= $('#'+item.properties.type);

     if(!box.data('mvc')){        
       //create a MVCObject and store it via checkbox-data
       box.data('mvc',new google.maps.MVCObject())
       //add a change-listener
       .change(function(){
       //set the map-property of the MVCObject to the map or null
          box.data('mvc').set('map',(box.prop('checked'))
                                      ? map.map
                                      : null)
       }).trigger('change');          
     }

     //create marker
     var marker=map.createMarker({
       lat:item.geometry.point[0],
       lng: item.geometry.point[1],
       map: box.data('mvc').get('map'),
       title: item.properties.title,
       infoWindow: {
          content: $('<div/>')
                    .append($('<h1/>').text(item.properties.title))
                    .append($('<p/>').text(item.properties.description))[0]
           }
     });

     //create polygon
     var polygon=map.drawPolygon({
       paths:item.geometry.polygon,
       map: box.data('mvc').get('map')
     });

     //bind the map-property of the marker & polygon
     //to the ma-property of the MVCObject
     marker.bindTo('map',box.data('mvc'),'map',true);
     polygon.bindTo('map',box.data('mvc'),'map',true);

   });

$(window).load(function(){
   $(document).ready(function () {
       var mapData = {
           "type": "FeatureCollection",
               "features": [{
               "type": "Feature",
                   "properties": {
                   "title": "Parking Lot 1",
                       "type": "parking",
                       "description": ""
               },
                   "geometry": {
                   "point": [39.298211, -70.439326],
                       "polygon": [
                       [39.298038, -70.439311],
                       [39.29804, -70.439267],
                       [39.298115, -70.439177],
                       [39.298137, -70.439177],
                       [39.298338, -70.438986],
                       [39.298472, -70.439384],
                       [39.298165, -70.439604],
                       [39.298038, -70.439311]
                   ]
               }
           },

           {
               "type": "Feature",
                   "properties": {
                   "title": "academic 1",
                       "type": "academic",
                       "description": ""
               },
                   "geometry": {
                   "point": [39.296499, -70.435279],
                       "polygon": [
                       [39.29657, -70.434978],
                       [39.296466, -70.434965],
                       [39.296466, -70.435131],
                       [39.296412, -70.435129],
                       [39.296404, -70.435598],
                       [39.296537, -70.435606],
                       [39.296559, -70.435589],
                       [39.296563, -70.435422],
                       [39.296541, -70.435417],
                       [39.296542, -70.435378],
                       [39.296563, -70.435375]
                   ]
               }
           },

           {
               "type": "Feature",
                   "properties": {
                   "title": "residence 1",
                       "type": "residence",
                       "description": ""
               },
                   "geometry": {
                   "point": [39.296183, -70.436438],
                       "polygon": [
                       [39.29633, -70.436782],
                       [39.296272, -70.436781],
                       [39.296257, -70.436845],
                       [39.296161, -70.436838],
                       [39.296166, -70.436602],
                       [39.296132, -70.436598],
                       [39.296118, -70.436578],
                       [39.296124, -70.436431],
                       [39.296046, -70.436417],
                       [39.296047, -70.43636],
                       [39.296001, -70.436353],
                       [39.29602, -70.436179],
                       [39.296283, -70.436197],
                       [39.296284, -70.436263],
                       [39.29627, -70.436672],
                       [39.296328, -70.4367]
                   ]
               }
           }]
       },


       map = new GMaps({
           el: '#map',
           lat: 39.298,
           lng: -72.4375,
           zoom: 15,
           zoomControl: true
       }),
       bounds=new google.maps.LatLngBounds();
       //use checkboxes  as map-controls
       map.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push($('.nav')[0]);
       
       mapData.features.forEach(function(item){
       
         var box= $('#'+item.properties.type);
         
         if(!box.data('mvc')){        
           //create a MVCObject and store it via checkbox-data
           box.data('mvc',new google.maps.MVCObject())
           //add a chang-listener
           .change(function(){
           //set the map-property of the MVCObject to the map or null
              box.data('mvc').set('map',(box.prop('checked'))
                                          ? map.map
                                          : null)
           }).trigger('change');          
         }
         
         //create marker
         var marker=map.createMarker({
           lat:item.geometry.point[0],
           lng: item.geometry.point[1],
           map: box.data('mvc').get('map'),
           title: item.properties.title,
           infoWindow: {
              content: $('<div/>')
                        .append($('<h1/>').text(item.properties.title))
                        .append($('<p/>').text(item.properties.description))[0]
               }
         });
         
         //create polygon
         var polygon=map.drawPolygon({
           paths:item.geometry.polygon,
           map: box.data('mvc').get('map')
         });
         
         bounds.extend(marker.getPosition());
         
         //bind the map-property of the marker & polygon
         //to the ma-property of the MVCObject
         marker.bindTo('map',box.data('mvc'),'map',true);
         polygon.bindTo('map',box.data('mvc'),'map',true);
         
       });
       //bring all markers into the viewport
       map.map.fitBounds(bounds);
   });
});
body, html, #map {
    height: 100%;
    margin: 0;
    
}
.nav{
     padding:2px;
     margin:3px;
     border:1px solid #919191;
     border-radius:2px;
     background:#fff;
     text-align:right;
    }
<script type='text/javascript' src='http://code.jquery.com/jquery-1.6.4.js'></script>
<script type='text/javascript' src="https://maps.googleapis.com/maps/api/js"></script>
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/gmaps.js/0.4.12/gmaps.min.js"></script>
<div class="nav">
    <form>
        <label for="parking">Parking</label>
        <input type="checkbox" id="parking" value="parking" checked/>
        <br>
        <label for="academic">Academic</label>
        <input type="checkbox" id="academic" value="academic"  checked/>
        <br>
        <label for="residence">Residence</label>
        <input type="checkbox" id="residence" value="residence" />
    </form>
</div>
<div id="map"></div>