asset-marker-cluster.svelte 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. <script lang="ts" context="module">
  2. import { createContext } from '$lib/utils/context';
  3. const { get: getContext, set: setClusterContext } = createContext<() => L.MarkerClusterGroup>();
  4. export const getClusterContext = () => {
  5. return getContext()();
  6. };
  7. </script>
  8. <script lang="ts">
  9. import { onDestroy, onMount } from 'svelte';
  10. import 'leaflet.markercluster';
  11. import { getMapContext } from './map.svelte';
  12. import { AssetResponseDto, getFileUrl } from '@api';
  13. import { Marker, Icon } from 'leaflet';
  14. import { assetInteractionStore } from '$lib/stores/asset-interaction.store';
  15. export let assets: AssetResponseDto[];
  16. const map = getMapContext();
  17. let cluster: L.MarkerClusterGroup;
  18. setClusterContext(() => cluster);
  19. onMount(() => {
  20. cluster = new L.MarkerClusterGroup({
  21. showCoverageOnHover: false,
  22. zoomToBoundsOnClick: true,
  23. spiderfyOnMaxZoom: true,
  24. maxClusterRadius: 30,
  25. spiderLegPolylineOptions: { opacity: 0 },
  26. spiderfyDistanceMultiplier: 3
  27. });
  28. for (let asset of assets) {
  29. if (!asset.exifInfo) continue;
  30. const lat = asset.exifInfo.latitude;
  31. const lon = asset.exifInfo.longitude;
  32. if (!lat || !lon) continue;
  33. const icon = new Icon({
  34. iconUrl: getFileUrl(asset.id, true),
  35. iconRetinaUrl: getFileUrl(asset.id, true),
  36. iconSize: [60, 60],
  37. iconAnchor: [12, 41],
  38. popupAnchor: [1, -34],
  39. tooltipAnchor: [16, -28],
  40. shadowSize: [41, 41]
  41. });
  42. const marker = new Marker([lat, lon], {
  43. icon,
  44. alt: ''
  45. });
  46. marker.on('click', () => {
  47. assetInteractionStore.setViewingAsset(asset);
  48. });
  49. cluster.addLayer(marker);
  50. }
  51. map.addLayer(cluster);
  52. });
  53. onDestroy(() => {
  54. if (cluster) cluster.remove();
  55. });
  56. </script>
  57. {#if cluster}
  58. <slot />
  59. {/if}