@@ -76,6 +76,10 @@ interface ClusteredVessel extends Vessel {
7676 clusterCount : number ;
7777 sumLat : number ;
7878 sumLng : number ;
79+ minLat : number ;
80+ maxLat : number ;
81+ minLng : number ;
82+ maxLng : number ;
7983}
8084
8185const IGNORED_VESSEL_NAMES = [ '--' ] ;
@@ -348,6 +352,10 @@ function FleetLayer({
348352 clusterCount : 1 ,
349353 sumLat : v . lat ,
350354 sumLng : v . lng ,
355+ minLat : v . lat ,
356+ maxLat : v . lat ,
357+ minLng : v . lng ,
358+ maxLng : v . lng ,
351359 } ) ) ;
352360 }
353361
@@ -360,6 +368,10 @@ function FleetLayer({
360368 clusterCount : 1 ,
361369 sumLat : vessel . lat ,
362370 sumLng : vessel . lng ,
371+ minLat : vessel . lat ,
372+ maxLat : vessel . lat ,
373+ minLng : vessel . lng ,
374+ maxLng : vessel . lng ,
363375 } ) ;
364376 return ;
365377 }
@@ -377,13 +389,21 @@ function FleetLayer({
377389 filtered [ clusterIndex ] . clusterCount ++ ;
378390 filtered [ clusterIndex ] . sumLat += vessel . lat ;
379391 filtered [ clusterIndex ] . sumLng += vessel . lng ;
392+ filtered [ clusterIndex ] . minLat = Math . min ( filtered [ clusterIndex ] . minLat , vessel . lat ) ;
393+ filtered [ clusterIndex ] . maxLat = Math . max ( filtered [ clusterIndex ] . maxLat , vessel . lat ) ;
394+ filtered [ clusterIndex ] . minLng = Math . min ( filtered [ clusterIndex ] . minLng , vessel . lng ) ;
395+ filtered [ clusterIndex ] . maxLng = Math . max ( filtered [ clusterIndex ] . maxLng , vessel . lng ) ;
380396 } else {
381397 filtered . push ( {
382398 ...vessel ,
383399 isCluster : false ,
384400 clusterCount : 1 ,
385401 sumLat : vessel . lat ,
386402 sumLng : vessel . lng ,
403+ minLat : vessel . lat ,
404+ maxLat : vessel . lat ,
405+ minLng : vessel . lng ,
406+ maxLng : vessel . lng ,
387407 } ) ;
388408 }
389409 } ) ;
@@ -568,11 +588,27 @@ function FleetLayer({
568588 suppressNextMapClickRef . current = true ;
569589 if ( onVesselSelect ) onVesselSelect ( null ) ;
570590 if ( onClusterZoomNotice ) onClusterZoomNotice ( ) ;
571- const nextZoom = Math . min ( Math . max ( map . getZoom ( ) + 2 , 11 ) , 16 ) ;
572- map . flyTo ( [ vessel . lat , vessel . lng ] , nextZoom , {
573- duration : 0.7 ,
574- easeLinearity : 0.25 ,
575- } ) ;
591+
592+ // Zoom to the bounds of the vessels in the cluster for better precision
593+ if ( vessel . minLat !== vessel . maxLat || vessel . minLng !== vessel . maxLng ) {
594+ const bounds = L . latLngBounds (
595+ [ vessel . minLat , vessel . minLng ] ,
596+ [ vessel . maxLat , vessel . maxLng ]
597+ ) ;
598+ map . fitBounds ( bounds , {
599+ padding : [ 50 , 50 ] ,
600+ maxZoom : 16 ,
601+ animate : true ,
602+ duration : 1.5 ,
603+ } ) ;
604+ } else {
605+ // Fallback for overlapping vessels at the same location
606+ const nextZoom = Math . min ( Math . max ( map . getZoom ( ) + 4 , 13 ) , 16 ) ;
607+ map . flyTo ( [ vessel . lat , vessel . lng ] , nextZoom , {
608+ duration : 1.5 ,
609+ easeLinearity : 0.25 ,
610+ } ) ;
611+ }
576612 } ,
577613 [ map , onVesselSelect , onClusterZoomNotice ]
578614 ) ;
@@ -657,6 +693,10 @@ function FleetLayer({
657693 clusterCount : 1 ,
658694 sumLat : selectedVessel . lat ,
659695 sumLng : selectedVessel . lng ,
696+ minLat : selectedVessel . lat ,
697+ maxLat : selectedVessel . lat ,
698+ minLng : selectedVessel . lng ,
699+ maxLng : selectedVessel . lng ,
660700 } as ClusteredVessel ,
661701 e
662702 ) ,
@@ -668,6 +708,10 @@ function FleetLayer({
668708 clusterCount : 1 ,
669709 sumLat : selectedVessel . lat ,
670710 sumLng : selectedVessel . lng ,
711+ minLat : selectedVessel . lat ,
712+ maxLat : selectedVessel . lat ,
713+ minLng : selectedVessel . lng ,
714+ maxLng : selectedVessel . lng ,
671715 } as ClusteredVessel ,
672716 e
673717 ) ,
0 commit comments