Leaflet MarkerCluster: Можно ли открыть несколько кластеров-групп?

Я недавно начал работать с листовкой. Я нашел отличный плагин-буклет markercluster. В настоящее время я пытаюсь открыть несколько кластерных групп одновременно. К сожалению, я ничего не могу найти в Google.

У меня есть несколько групп кластеров, и я рисую связи от одного маркера к другому. Пользователь должен иметь возможность открывать обе группы кластеров, к которым идет нарисованная линия:

Мой пример

Поэтому у меня вопрос: есть ли для этого функция, которую я должен включить, или же открытие нескольких групп одновременно не предусмотрено вообще?


person ajl31701    schedule 11.06.2019    source источник
comment
Я хочу, чтобы spiderfy группа secound, когда я нажимаю на нее. Итак, я проверил функцию spiderfy в leaflet.markercluster-src.js. Там говорится, что unspiderfy () последней группы всегда вызывается перед вызовом нового spiderfied. Поэтому я думаю, что мне нужно изменить файл .js и запомнить открытые группы, чтобы закрыть их позже.   -  person ajl31701    schedule 12.06.2019


Ответы (5)


Хорошо, я немного поэкспериментировал с этим сейчас;)

В файле leaflet.markercluster-src.js я создал массив с именем _spiderMan[], который заполняется объектами, по которым щелкнули мышью, в функции spiderfy.

spiderfy: function() {
  if (this._group._spiderfied === this || this._group._inZoomAnimation) {
    return;
  }

  var childMarkers = this.getAllChildMarkers(null, true),
    group = this._group,
    map = group._map,
    center = map.latLngToLayerPoint(this._latlng),
    positions;

  // this._group._unspiderfy();  //deactivated
  var markers = markers + childMarkers;
  _spiderMan.push(this);  //new          

  if (childMarkers.length >= this._circleSpiralSwitchover) {
    positions = this._generatePointsSpiral(childMarkers.length, center);
  } else {
    center.y += 10; 
    positions = this._generatePointsCircle(childMarkers.length, center);
  }

  this._animationSpiderfy(childMarkers, positions);
},

Затем я создал цикл for, который проходит через массив и каждый раз вызывает _spiderMan[i].unspiderfy(zoomDetails). Я встроил этот цикл в функцию _unspiderfyZoomAnim для тестирования. Означает, что каждый раз при увеличении или уменьшении масштаба все открытые группы суммируются.

_unspiderfyZoomAnim: function(zoomDetails) {
  if (L.DomUtil.hasClass(this._map._mapPane, 'leaflet-touching')) {
    return;
  }
  this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
  var i;
  for (i = 0; i < _spiderMan.length; i++) {
    _spiderMan[i].unspiderfy(zoomDetails);
  }
  _spiderMan = [];
},

Кроме того, в функции unspiderfy должны быть деактивированы следующие строки:

unspiderfy: function(zoomDetails) {
  /// <param Name="zoomDetails">Argument from zoomanim if being called in a zoom animation or null otherwise</param>
  // if (this._group._inZoomAnimation) {
  //    return;             
  // }
  this._animationUnspiderfy(zoomDetails);

  // this._group._spiderfied = null;        
},

Итак, теперь можно открывать и закрывать несколько кластерных групп, но это всего лишь обходной путь, и я думаю, что это будет иметь некоторые плохие последствия из-за комментирования или удаления строк кода.

Я думаю, что кто-то с большим опытом работы с JS и этим плагином должен найти лучшее и более удобное решение;).

person ajl31701    schedule 13.06.2019
comment
Если это сработало для вас, вы должны принять свой собственный ответ, так как это поможет другим, кто прочитает этот вопрос в будущем (+1). - person Mawg says reinstate Monica; 16.01.2021

Добро пожаловать в SO!

К сожалению, управление спайдерфикацией в плагине Leaflet.markercluster в настоящее время предполагает, что единовременно может быть спайдерфицирован один кластер.

См. Также комментарий danzel в выпуске Leaflet.markercluster № 744 ( Spiderfy все кластеры в определенном виде):

Leaflet.MarkerCluster на данный момент поддерживает только один кластер, поэтому для его поддержки потребуется немного поработать.

person ghybs    schedule 11.06.2019

Может быть, вы получите лучший ответ, если дадите пример использования ...

Однако можно с уверенностью сказать, что нет функции, которую можно включить для открытия нескольких групп одним щелчком мыши.

С точки зрения удобства использования это не имеет особого смысла, поскольку базовое поведение MarkerCluster состоит в том, чтобы щелкнуть один значок для увеличения и расширения интересующей вас группы.

person YaFred    schedule 11.06.2019

Цитата из https://github.com/Leaflet/Leaflet.markercluster#other-clusters-methods:

  • spiderfy: обрабатывает дочерние маркеры этого кластера.
  • unspiderfy: расщепляет скопление (противоположно spiderfy).

Итак, если у вас есть ссылки на кластеры, которые вы хотите «открыть» (спайдерировать) одновременно, просто вызовите их .spiderify() метод.

например если желаемые кластеры находятся в переменных cluster1 и cluster2:

cluster1.spiderify();
cluster2.spiderify();

См. Также https://github.com/Leaflet/Leaflet.markercluster#getting-the-visible-parent-of-a-marker и https://github.com/Leaflet/Leaflet.markercluster#clusters-methods о том, как получить ссылки на кластеры.

person IvanSanchez    schedule 11.06.2019
comment
Я хочу, чтобы spiderfy группа secound, когда я нажимаю на нее. Итак, я проверил функцию spiderfy в leaflet.markercluster-src.js. Там говорится, что unspiderfy () последней группы всегда вызывается перед вызовом нового spiderfied. Поэтому я думаю, что мне нужно изменить файл .js и запомнить открытые группы, чтобы закрыть их позже. - person ajl31701; 11.06.2019
comment
Эту информацию вы должны добавить к исходному вопросу. - person IvanSanchez; 11.06.2019

Насколько я могу судить, вы можете держать открытыми несколько кластеров, но только по одному для каждой группы. Я предполагаю, что все ваши маркеры принадлежат одной группе. В этом случае вы не можете держать открытыми несколько кластеров.

Вы можете выбрать метод наведения, при котором кластер открывается при наведении на него курсора.

const mymap = L.map('mapid').setView([48.550, 8.207], 6);

L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
  maxZoom: 18,
  id: 'mapbox.streets'
}).addTo(mymap);

const markers = L.markerClusterGroup({zoomToBoundsOnClick: false});
[[47.5617, 7.5504], [47.5255, 7.6163], [47.5691, 7.6355],
 [49.4922, 8.3922], [49.5306, 8.5172], [49.4547, 8.5062]]
  .map(latLng => L.marker(latLng))
  .forEach(marker => markers.addLayer(marker));
mymap.addLayer(markers);

markers.on("clustermouseover", a => a.layer.spiderfy());
markers.on("clustermouseout", a => a.layer.unspiderfy());
html, body, #mapid { margin: auto; height: 100%; }
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/MarkerCluster.Default.css" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/MarkerCluster.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.markercluster.js"></script>

<div id="mapid"></div>

person 3limin4t0r    schedule 11.06.2019
comment
Спасибо за код. К сожалению, мне приходится отображать информацию о маркере, когда я нажимаю на него. Это событие наведения курсора немного затрудняет захват и попадание в маркер; D - person ajl31701; 12.06.2019
comment
@ ajl31701 Вы можете изменить событие на clusterclick. Но, к сожалению, вы не можете открыть несколько кластеров для одной группы без изменения кода JavaScript. - person 3limin4t0r; 12.06.2019