我正在创建一个地图,使用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/
答案 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>