import { IMapMarkers, IRoutePath } from '../../models'; export class MapHelper { static getIconForUnitViewStops = (color: string, id: number | string) => { const svgTemplate = ` ${id} `; const url = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svgTemplate); return url; }; static getIconForDriveMiles = (color: string, id: number | string) => { const svgTemplate = ` ${id} `; const url = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svgTemplate); return url; }; static getLocationIcon(color: string) { let svgTemplate = ``; const url = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svgTemplate); return url; } static getFillColorForState( stateDensity: number, View: string ): { fillColor: string; fillOpacity: number } { let fillColor = '#EEEEEE'; let fillOpacity = 1; const getFleetViewColor = (density: number) => { if (density < 50) return { fillColor: '#EF5350', fillOpacity: 0.8 }; else if (density < 100) return { fillColor: '#EF5350', fillOpacity: 1 }; else if (density < 500) return { fillColor: '#00967E', fillOpacity: 0.8 }; else if (density < 1000) return { fillColor: '#00967E', fillOpacity: 1 }; return { fillColor: '#EEEEEE', fillOpacity: 1 }; }; const getUnitViewColor = (density: number) => { if (density < 50) return { fillColor: '#FFA726', fillOpacity: 0.3 }; else if (density < 100) return { fillColor: '#FFA726', fillOpacity: 0.6 }; else if (density < 500) return { fillColor: '#FFA726', fillOpacity: 0.9 }; else if (density < 1000) return { fillColor: '#FFA726', fillOpacity: 1 }; return { fillColor: '#EEEEEE', fillOpacity: 1 }; }; switch (View) { case 'fleetView': ({ fillColor, fillOpacity } = getFleetViewColor(stateDensity)); break; case 'unitView': ({ fillColor, fillOpacity } = getUnitViewColor(stateDensity)); break; default: break; } return { fillColor: fillColor, fillOpacity: fillOpacity, }; } static getMapCenterAndZoom(markers: IMapMarkers[]): { mapCenter: IRoutePath; bounds?: google.maps.LatLngBounds | null; mapZoom?: number | null; } { // Calculate center const coordinates: { lat: number[]; lng: number[] } = { lat: [], lng: [], }; // Calculate zoom const bounds: google.maps.LatLngBounds | null = markers?.length > 1 ? new google.maps.LatLngBounds() : null; if (markers?.length > 1) { markers.forEach((marker) => { coordinates.lat.push(Number(marker.position.lat)); coordinates.lng.push(Number(marker.position.lng)); bounds?.extend({ lat: Number(marker.position.lat), lng: Number(marker.position.lng), }); }); } const averageLng = markers?.length > 1 ? (Math.max(...coordinates.lng) + Math.min(...coordinates.lng)) / 2 : markers[0].position.lng; const averageLat = markers?.length > 1 ? (Math.max(...coordinates.lat) + Math.min(...coordinates.lat)) / 2 : markers[0].position.lat; const mapCenter = { lat: averageLat, lng: averageLng }; const mapZoom = markers.length === 1 ? 8 : null; return { mapCenter, bounds, mapZoom }; } static getMapScaleDistance(map: google.maps.Map): { roundedMiles: number; pixelLength: number; } { const center = map.getCenter(); const zoom = map.getZoom(); if (!center || zoom == null) return { roundedMiles: 0, pixelLength: 0 }; const lat = center.lat(); const metersPerPixel = (156543.03392 * Math.cos((lat * Math.PI) / 180)) / Math.pow(2, zoom); const maxBarPx = 100; const rawMeters = metersPerPixel * maxBarPx; const rawMiles = rawMeters / 1609.34; const roundedMiles = this.getRoundedMiles(rawMiles); const roundedMeters = roundedMiles * 1609.34; const pixelLength = roundedMeters / metersPerPixel; return { roundedMiles, pixelLength, }; } static getRoundedMiles(miles: number): number { if (miles <= 0) return 0; const exponent = Math.floor(Math.log10(miles)); const fraction = miles / Math.pow(10, exponent); let roundedFraction: number; if (fraction < 1.5) roundedFraction = 1; else if (fraction < 3) roundedFraction = 2; else if (fraction < 7) roundedFraction = 5; else roundedFraction = 10; return roundedFraction * Math.pow(10, exponent); } }