2016-02-10 2 views
0

У меня есть карта с пользовательскими маркерами HTML и MarkerClusterer, кластер работает отлично, но я хочу отфильтровать маркеры по радиусу до местоположения, я могу получить маркеры внутри заданного радиуса , однако я не могу скрыть маркеры за пределами данного радиуса и показать только маркеры внутри этого радиуса от MarkerClusterer.Пользовательский HTML-маркер Google Maps и MarkerClustererPlus

я определяю свой собственный маркер, как это:

function CustomMarker(latlng, map, args) 
{ 
    this.latlng = latlng; 
    this.args = args; 
    this.setMap(map); 
    this.map = map; 
} 

CustomMarker.prototype = new google.maps.OverlayView(); 

CustomMarker.prototype.draw = function() 
{ 
    var self = this; 

    if (!this.div) 
    { 
     var div = document.createElement('div'); 

     div.className = 'marker'; 
     div.style.position = 'absolute'; 
     div.style.cursor = 'pointer'; 

     var span = document.createElement('span'); 
     span.innerHTML = 'X'; 

     div.appendChild(span); 

     var panes = this.getPanes(); 
     panes.overlayImage.appendChild(div); 

     this.div = div; 
    } 

    var point = this.getProjection().fromLatLngToDivPixel(this.latlng); 

    if (point) 
    { 
     this.div.style.left = (point.x - 20) + 'px'; 
     this.div.style.top = (point.y - 20) + 'px'; 
    } 

    google.maps.event.addDomListener(this.div, "click", function (event) 
    { 
     google.maps.event.trigger(self, "click"); 
    }); 
}; 

CustomMarker.prototype.remove = function() 
{ 
    if (this.div) 
    { 
     this.div.parentNode.removeChild(this.div); 
     this.div = null; 
    } 
}; 

CustomMarker.prototype.getPosition = function() 
{ 
    return this.latlng; 
}; 

CustomMarker.prototype.getDraggable = function() 
{ 
    return false; 
}; 

CustomMarker.prototype.setVisible = function (visible) 
{ 
    if (this.div) 
    { 
     if (visible) 
     { 
      this.div.style.display = 'table'; 
      this.visible = true; 
     } 
     else 
     { 
      this.div.style.display = 'none'; 
      this.visible = false; 
     } 
    } 
}; 

CustomMarker.prototype.getVisible = function() 
{ 
    return this.visible; 
}; 

Я использую MarkerClustererPlus и используя setIgnoreHidden(true) скроет все маркеры, включая маркер, который должен быть виден.

Я заметил, что marker.getVisible(), который используется MC + при использовании setIgnoreHidden(true), возвращает false для маркеров вне данного радиуса, как и ожидалось, но не определено для маркеров внутри кластера.

Я думаю, что это происходит потому, что когда создается кластер, элементы внутри него удаляются, а не просто скрываются, поэтому устанавливают их на нуль.

CustomMarker.prototype.remove = function() 
{ 
    if (this.div) 
    { 
     this.div.parentNode.removeChild(this.div); 
     this.div = null; 
    } 
}; 

См. Пример JS Fiddle.

https://jsfiddle.net/enriqg9/az21h1b5/

ответ

1

Если вы хотите, маркер, чтобы быть видимым, необходимо установить его map свойство:

for (var n = 0; n < this.markers.length; n++) { 
    var marker = this.markers[n]; 
    var distance = google.maps.geometry.spherical.computeDistanceBetween(marker.getPosition(), location)/1609; 
    if (distance > radius) { 
    // 4 Markers over 10 mile radius should be hidden 
    marker.setVisible(false); 
    } else { 
    // Only 1 marker should be kept visible 
    marker.setMap(this.map); 
    visibleMarkers.push(marker); 
    } 
    console.log(marker.getVisible()); 
} 

proof of concept fiddle

фрагмент кода:

/* ========================================================================== 
 
Google Maps 
 
========================================================================== */ 
 
var map = { 
 
    'map': '', 
 
    'markers': [], 
 
    'lat': 31.862491, 
 
    'lng': -106.3650707, 
 
    'createMap': function() { 
 
    this.map = new google.maps.Map(document.getElementById('map'), { 
 
     center: { 
 
     lat: this.lat, 
 
     lng: this.lng 
 
     }, 
 
     zoom: 6, 
 
     maxZoom: 18, 
 
     scrollwheel: false, 
 
     disableDefaultUI: true, 
 
     zoomControl: true 
 
    }); 
 
    this.createMarkers($object); 
 
    }, 
 
    'createMarkers': function(response) { 
 
    var self = this; 
 
    var infoWindow = new google.maps.InfoWindow({ 
 
     content: 'Loading' 
 
    }); 
 
    var bounds = new google.maps.LatLngBounds(); 
 
    for (var n = 0; n < response.length; n++) { 
 
     var el = response[n]; 
 
     var lat = parseFloat(el.lat); 
 
     var lng = parseFloat(el.lng); 
 
     var latLng = new google.maps.LatLng(lat, lng); 
 
     var marker = new CustomMarker(latLng, this.map, { 
 
     title: el.title 
 
     }); 
 
     this.markers.push(marker); 
 
     bounds.extend(marker.getPosition()); 
 
     google.maps.event.addListener(marker, 'click', function() { 
 
     infoWindow.setContent('<b>' + this.args.title + '</b>'); 
 
     infoWindow.open(self.map, this); 
 
     self.map.panTo(this.getPosition()); 
 
     self.map.setZoom(14); 
 
     }); 
 
    } 
 
    // New markerClustererPlus 
 
    this.mc = new MarkerClusterer(this.map, this.markers); 
 
    }, 
 
    'filter': function(location) { 
 
    var bounds = new google.maps.LatLngBounds(); 
 
    var visibleMarkers = []; 
 
    // For testing purposes 
 
    var radius = 10; 
 
    var location = new google.maps.LatLng(this.lat, this.lng); 
 
    // Hide Markers not inside given radius 
 
    for (var n = 0; n < this.markers.length; n++) { 
 
     var marker = this.markers[n]; 
 
     var distance = google.maps.geometry.spherical.computeDistanceBetween(marker.getPosition(), location)/1609; 
 
     if (distance > radius) { 
 
     // 4 Markers over 10 mile radius should be hidden 
 
     marker.setVisible(false); 
 
     } else { 
 
     // Only 1 marker should be kept visible 
 
     marker.setMap(this.map); 
 
     visibleMarkers.push(marker); 
 
     } 
 
     console.log(marker.getVisible()); 
 
    } 
 
    for (var n = 0; n < visibleMarkers.length; n++) { 
 
     bounds.extend(visibleMarkers[n].getPosition()); 
 
    } 
 
    this.mc.setIgnoreHidden(true); 
 
    this.map.fitBounds(bounds); 
 
    } 
 
}; 
 
var btn = document.getElementById('filter'); 
 
btn.addEventListener('click', function() { 
 
    map.filter(); 
 
}); 
 
var $object = [{ 
 
    "lat": -20.823485, 
 
    "lng": 23.24177, 
 
    "title": "Explicabo voluptates voluptatibus quas sed laborum minus quia." 
 
}, { 
 
    "lat": -27.503418, 
 
    "lng": 32.594705, 
 
    "title": "Repellat ea reiciendis quae dolores sit facilis ut." 
 
}, { 
 
    "lat": -53.468797, 
 
    "lng": -125.400102, 
 
    "title": "Perspiciatis voluptates consectetur nulla inventore illo debitis delectus alias." 
 
}, { 
 
    "lat": "31.80666009999999", 
 
    "lng": "-106.50467950000001", 
 
    "title": "321 Mesa St" 
 
}, { 
 
    "lat": "31.831369", 
 
    "lng": "-106.55140799999998", 
 
    "title": "123 Main St" 
 
}]; 
 
/* ========================================================================== 
 
Custom Maker 
 
========================================================================== */ 
 
function CustomMarker(latlng, map, args) { 
 
    this.latlng = latlng; 
 
    this.args = args; 
 
    this.setMap(map); 
 
    this.map = map; 
 
} 
 
CustomMarker.prototype = new google.maps.OverlayView(); 
 
CustomMarker.prototype.draw = function() { 
 
    var self = this; 
 
    if (!this.div) { 
 
    var div = document.createElement('div'); 
 
    div.className = 'marker'; 
 
    div.style.position = 'absolute'; 
 
    div.style.cursor = 'pointer'; 
 
    var span = document.createElement('span'); 
 
    span.innerHTML = 'X'; 
 
    div.appendChild(span); 
 
    var panes = this.getPanes(); 
 
    panes.overlayImage.appendChild(div); 
 
    this.div = div; 
 
    } 
 
    var point = this.getProjection().fromLatLngToDivPixel(this.latlng); 
 
    if (point) { 
 
    this.div.style.left = (point.x - 20) + 'px'; 
 
    this.div.style.top = (point.y - 20) + 'px'; 
 
    } 
 
    google.maps.event.addDomListener(this.div, "click", function(event) { 
 
    google.maps.event.trigger(self, "click"); 
 
    }); 
 
}; 
 
CustomMarker.prototype.remove = function() { 
 
    if (this.div) { 
 
    this.div.parentNode.removeChild(this.div); 
 
    this.div = null; 
 
    } 
 
}; 
 
CustomMarker.prototype.getPosition = function() { 
 
    return this.latlng; 
 
}; 
 
CustomMarker.prototype.getDraggable = function() { 
 
    return false; 
 
}; 
 
CustomMarker.prototype.setVisible = function(visible) { 
 
    if (this.div) { 
 
    if (visible) { 
 
     this.div.style.display = 'table'; 
 
     this.visible = true; 
 
    } else { 
 
     this.div.style.display = 'none'; 
 
     this.visible = false; 
 
    } 
 
    } 
 
}; 
 
CustomMarker.prototype.getVisible = function() { 
 
    return this.visible; 
 
}; 
 
map.createMap();
#map { 
 
    height: 400px; 
 
} 
 
.marker { 
 
    display: table; 
 
    width: 40px; 
 
    height: 40px; 
 
    background-color: #353535; 
 
    border: 3px solid #FF9000; 
 
    border-radius: 50px; 
 
    color: #fff; 
 
    font-size: 1em; 
 
    font-weight: bold; 
 
    text-align: center; 
 
} 
 
.marker span { 
 
    display: table-cell; 
 
    vertical-align: middle; 
 
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script> 
 
<script src="https://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.1.2/src/markerclusterer.js"></script> 
 
<div id="map"></div> 
 

 
<button id="filter">Filter</button> 
 

 
<p> 
 
    Clicking the Filter button should display 1 marker, bounds get properly set but marker is not visible. 
 
</p> 
 

 
<p> 
 
    If you click on the cluster before clicking the filter button, the markers inside it get visible, and clicking filter will work as expected, as there are no markers inside a cluster. 
 
</p>

+0

Спасибо! Ваше решение действительно работает. – enriqg9

Смежные вопросы