mapgl map arcs cluster

by Trufi

HTML

<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script src='https://unpkg.com/@turf/turf@6/turf.min.js'></script>
<script src="https://unpkg.com/@2gis/mapgl-clusterer@^2/dist/clustering.js"></script>
<div id="container"></div>

CSS

html,
body,
#container {
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

JavaScript

// API key can be used on jsfiddle.net only!
// You can get more info on https://docs.2gis.com/

const map = new mapgl.Map('container', {
  center: [55.25518830076297, 25.21574489243865],
  zoom: 16.5,
  key: 'bfd8bbca-8abf-11ea-b033-5fa57aae2de7',
});
window.addEventListener('resize', () => map.invalidateSize());
map.on('click', (ev) => console.log(ev.lngLat))

const icon = `<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10">
  <circle fill="#0000ff" cx="5" cy="5" r="5"/>
  <circle fill="#ffffff" cx="5" cy="5" r="2"/>
</svg>`;

function createFovGeometry(lngLatCenter, rotation, fov, radiusInMeters) {
  const lineString = turf.lineArc(lngLatCenter, radiusInMeters / 1000, rotation - fov / 2, rotation + fov / 2);
  const ring = lineString.geometry.coordinates;
  if (fov < 360) {
    ring.unshift(lngLatCenter);
    ring.push(lngLatCenter);
  }
  return [ring];
}

const cameras = [{
  lngLat: [55.255362479893996, 25.217728948395333],
  rotation: 35,
  fov: 360,
  radius: 100,
}, {
  lngLat: [55.25427208651889, 25.216377105791935],
  rotation: 290,
  fov: 60,
  radius: 200,
}, {
  lngLat: [55.25617017872204, 25.215171396597043],
  rotation: 260,
  fov: 45,
  radius: 150,
}, {
  lngLat: [55.25728076495804, 25.216541519824702],
  rotation: 220,
  fov: 120,
  radius: 150,
}, {
  lngLat: [55.25409035473208, 25.215408885647165],
  rotation: 160,
  fov: 45,
  radius: 150,
}, {
  lngLat: [55.25479709160864, 25.213289737407905],
  rotation: 40,
  fov: 45,
  radius: 150,
}, {
  lngLat: [55.24881499153622, 25.212762553741825],
  rotation: 40,
  fov: 45,
  radius: 150,
}];

cameras.forEach((camera) => {
  camera.fovCoordinates = createFovGeometry(camera.lngLat, camera.rotation, camera.fov, camera.radius);
});

const clustringZoom = 15;

const clusterer = new mapgl.Clusterer(map, {
  radius: 60,
  disableClusteringAtZoom: clustringZoom,
});

clusterer.load(cameras.map((camera, index) => ({
  coordinates: camera.lngLat,
  icon:...