Перекрывающийся маркер Значок маркера Spiderfier, когда в одном месте несколько маркеров
Карты Google не позволяют разбить несколько маркеров, находящихся в одном месте. Это может произойти с людьми или предприятиями в нескольких местах проживания, таких как многоквартирный дом или здание профессиональных услуг. В зависимости от уровня масштабирования это также может происходить в торговых центрах и т. Д.
Обходной путь заключается в том, чтобы "спайдерфить" их: при щелчке по первому он выделяет их с линией к месту. Это сделано в Google Earth, и Джордж МакКеррон написал пакет, чтобы сделать это для Google Maps. ( https://github.com/jawj/OverlappingMarkerSpiderfier)
Он может быть интегрирован с markerclusterer, хотя он не поддерживает групповое создание маркеров кластером маркеров.
Моя проблема в том, что приложение, над которым я работаю, хочет иметь определенные значки для различных типов действий. Spiderfier ставит один из маркеров сверху. Человек, смотрящий на карту, не может знать, что под верхним маркером может быть 10 или более других маркеров.
В идеале был бы способ поместить верхний маркер, который отображается, когда есть несколько маркеров, похожих на другой значок в markercluster. Это не прямое соотношение 1 к 1, поскольку spiderfier также работает, когда они находятся близко, но не совсем в одном и том же месте (по умолчанию 20 пикселей), а у markercluster нет доступа к нескольким маркерам в одном и том же месте.
Идеальным поведением будет иметь специальную иконку для пауков, которые при нажатии нажимают на отдельные иконки. Похож на markerclusterer, но без изменения масштаба и обработки того же места. Специальная иконка в идеале будет указывать, сколько других маркеров находится на месте, опять же, как markerclusterer. Специальная иконка может быть скрыта или стать частью группы пауков.
Без некоторого размещения пользователи не могли бы знать, что несколько действий находятся на месте. Они могут даже предположить, что желаемая активность находится не в этом месте, поскольку отображается другой маркер активности.
У этого плунжера есть проблема: http://plnkr.co/edit/vimZNq?p=info
var markers = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < 100; ++i) {
var latLng = new google.maps.LatLng(Math.floor(Math.random() * 10) / 10 + 39,
Math.floor(Math.random() * 10) / 10 - 100);
var marker = new google.maps.Marker({
position: latLng,
title: "marker " + i + " pos: " + latLng,
maxZoom: 8,
map: map
});
marker.desc = marker.getTitle();
bounds.extend(latLng);
markers.push(marker);
oms.addMarker(marker);
}
map.fitBounds(bounds);
var markerCluster = new MarkerClusterer(map, markers);
Спасибо за вашу помощь,
Дэвид
3 ответа
Вот как я заставил это работать. куда map
это экземпляр Gmap и oms
экземпляр перекрывающего маркера Spiderfier Мы также используем Marker Clusterer при начальном увеличении, которое дает нам перерыв.
map.addListener('zoom_changed', function() {
map.addListenerOnce('idle', function() {
// change spiderable markers to plus sign markers
// we are lucky here in that initial map is completely clustered
// for there is no init listener in oms :(
// so we swap on the first zoom/idle
// and subsequently any other zoom/idle
var spidered = oms.markersNearAnyOtherMarker();
for (var i = 0; i < spidered.length; i ++) {
// this was set when we created the markers
url = spidered[i].icon.url;
// code to manipulate your spidered icon url
};
});
});
oms.addListener('unspiderfy', function(markers) {
var spidered = markers;
for (var i = 0; i < spidered.length; i ++) {
url = spidered[i].icon.url;
// change it back
};
});
oms.addListener('click', function(marker) {
// put the clicked-on marker on top
// when oms un-spiders
marker.zIndex=999;
// set infowindow, panning etc.
});
Мне удалось сопоставить следующие версии:
- MarkerClusterer 2.0.13
- OverlappingMarkerSpiderfier 3.27
При каждом создании нового маркера я сохраняю initialIconUrl
в объекте маркера
var marker = new google.maps.Marker({
position: //some position
});
marker.setIcon(iconUrl);
marker.initialIconUrl = iconUrl;
При объявлении OverlappingMarkerSpiderfier установите nearbyDistance
до 0,001 (или какое-то другое очень маленькое значение).
this.oms = new OverlappingMarkerSpiderfier(this.map, {
markersWontMove: true,
markersWontHide: true,
nearbyDistance: 0.001 //This will only spiderfy the Markers if they have the exact same position
});
Затем нам нужен слушатель на событии 'idle' карт, чтобы вручную отформатировать маркеры. Мне это нужно, потому что мой маркер SPIDERFIABLE не будет корректно отображаться на первом шаге при переходе от кластерного маркера к отдельным маркерам.
var me = this;
google.maps.event.addListener(this.map, 'idle', function () {
me.oms.formatMarkers();
});
Прослушайте событие oms 'format' и установите iconURL для маркеров, которые являются SPIDERFIABLE. Если маркер не является паучьим, сбросьте иконку к исходному URL.
var spiderfiableIconUrl = //Whatever you need
this.oms.addListener('format', function (marker, status) {
var iconURL = status == OverlappingMarkerSpiderfier.markerStatus.SPIDERFIABLE
? spiderfiableIconUrl :
marker.initialIconUrl;
marker.setIcon(iconURL);
});
Надеюсь это поможет.
Некоторые методы, кажется, интересны, как markersNearAnyOtherMarker
но я не могу заставить его работать. Интересным способом может быть использование событий spiderfy и unspiderfy и изменение маркера при его запуске
overlappingMarkers = new OverlappingMarkerSpiderfier(map, overlapOptions);
overlappingMarkers.addListener('spiderfy', function (markers) {
markers.forEach(function (marker) {
marker.setLabel('*');
marker.setIcon(myNormalIcon);
})
})
overlappingMarkers.addListener('unspiderfy', function (markers) {
markers.forEach(function (marker) {
marker.setLabel(''+markers.length);
marker.setIcon(myOverlapIcon);
})
})
К сожалению, unspiderfy
событие не запускается, пока мы не откроем и не закроем маркер перекрытия. Если я найду заключение по этому решению, я обновлю этот пост.