import { IMapMarkers, IRoutePath } from '../../models';
export class MapHelper {
static getIconForUnitViewStops = (color: string, id: number | string) => {
const svgTemplate = ``;
const url =
'data:image/svg+xml;charset=UTF-8,' +
encodeURIComponent(svgTemplate);
return url;
};
static getIconForDriveMiles = (color: string, id: number | string) => {
const svgTemplate = ``;
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);
}
}