gribnoysup / react-yandex-maps

Yandex Maps API bindings for React
MIT License
328 stars 116 forks source link

Как получить список объектов в кластере? #288

Closed lashevskiy closed 2 years ago

lashevskiy commented 3 years ago

Использую Clusterer в котором отрисовываю Placemark по координатам объектов из массива data. В случае когда я кликаю на Placemark с одним уникальными координатами, то я могу получить данные о данном объекте

<Clusterer>
{data.map(item => <Placemark key={item.id} onClick={() => console.log(item)} />)
</Clusterer>

Но бывают случаи, когда координаты объектов совпадают и они находятся в одном маркере (см скрин). Как получить список этих объектов при клике на маркер?

Снимок экрана 2021-02-18 в 05 50 06
lashevskiy commented 3 years ago

Сейчас попробовал перейти на ObjectManager, но тоже не понимаю как получать объект, либо их список при кластере с одинаковыми координатами

<ObjectManager
                    options={{
                        clusterize: true,
                        gridSize: 32,
                    }}
                    objects={{
                        openBalloonOnClick: true,
                        preset: 'islands#greenDotIcon',
                    }}
                    clusters={{
                        preset: 'islands#redClusterIcons',
                    }}
                    defaultFeatures={{
                        type: 'FeatureCollection',
                        features: [
                            {
                                type: 'Feature',
                                id: 1,
                                geometry: {
                                    type: 'Point',
                                    coordinates: [45.33, 24.33]
                                }
                            },
                            {
                                type: 'Feature',
                                id: 2,
                                geometry: {
                                    type: 'Point',
                                    coordinates: [45.23, 24.34]
                                }
                            },
                            {
                                type: 'Feature',
                                id: 3,
                                geometry: {
                                    type: 'Point',
                                    coordinates: [45.23, 24.34]
                                }
                            },
                        ]
                    }}
                    modules={[
                        'objectManager.addon.objectsBalloon',
                        'objectManager.addon.objectsHint',
                    ]}
                />
mmarkelov commented 3 years ago

@lashevskiy собрал песочницу, может такой вариант поможет?

import { YMaps, Map, Clusterer, Placemark } from "react-yandex-maps";

const mapState = {
  center: [55.751574, 37.573856],
  zoom: 5
};

const points = [
  [55.751574, 37.573856],
  [55.751574, 37.573856],
  [55.651574, 37.773856]
];

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <YMaps>
        <Map modules={["clusterer.addon.balloon"]} state={mapState}>
          <Clusterer
            instanceRef={clusterer}
            onBalloonOpen={(e) => {
              console.log(e.get("cluster").getGeoObjects());
            }}
            // onClick={() => console.log(clusterer.current.state)}
          >
            {points.map((item, idx) => (
              <Placemark
                geometry={item}
                key={idx}
                properties={{
                  balloonContentBody:
                    "балун <strong>метки " + idx + "</strong>",
                  clusterCaption: "метка <strong>" + idx + "</strong>"
                }}
                onClick={() => console.log(item)}
              />
            ))}
          </Clusterer>
        </Map>
      </YMaps>
    </div>
  );
}
lashevskiy commented 3 years ago

@mmarkelov это решило кейс, но как оказалось для нескольких тысяч объектов на карте вариант с Clusterer и Placemark очень плох в производительности =(

Можно ли также получать объекты при использовании ObjectManager?

mmarkelov commented 3 years ago

@lashevskiy нужно посмотреть, думаю, что можно.

mmarkelov commented 3 years ago

@lashevskiy попробуйте так

          <ObjectManager
            instanceRef={objManager}
            onBalloonOpen={(e) => {
              const objectId = e.get("objectId");
              console.log(objManager.current.clusters.getById(objectId));
            }}
            options={{
              clusterize: true,
              gridSize: 32
            }}
            objects={{
              openBalloonOnClick: true,
              preset: "islands#greenDotIcon"
            }}
            clusters={{
              preset: "islands#redClusterIcons"
            }}
            defaultFeatures={data}
            modules={[...]}
          />