turash/bugulma/frontend/utils/coordinates.ts
Damir Mukimov 6347f42e20
Consolidate repositories: Remove nested frontend .git and merge into main repository
- Remove nested git repository from bugulma/frontend/.git
- Add all frontend files to main repository tracking
- Convert from separate frontend/backend repos to unified monorepo
- Preserve all frontend code and development history as tracked files
- Eliminate nested repository complexity for simpler development workflow

This creates a proper monorepo structure with frontend and backend
coexisting in the same repository for easier development and deployment.
2025-11-25 06:02:57 +01:00

77 lines
2.3 KiB
TypeScript

/**
* Coordinate validation and utility functions
* Ensures coordinates are within valid ranges and handles edge cases
*/
/**
* Validates if a latitude is within valid range [-90, 90]
*/
export function isValidLatitude(lat: number): boolean {
return typeof lat === 'number' && !isNaN(lat) && lat >= -90 && lat <= 90;
}
/**
* Validates if a longitude is within valid range [-180, 180]
*/
export function isValidLongitude(lng: number): boolean {
return typeof lng === 'number' && !isNaN(lng) && lng >= -180 && lng <= 180;
}
/**
* Validates if a coordinate pair [lat, lng] is valid
*/
export function isValidCoordinate(lat: number, lng: number): boolean {
return isValidLatitude(lat) && isValidLongitude(lng);
}
/**
* Validates and normalizes a coordinate pair
* Returns null if invalid, otherwise returns normalized [lat, lng]
*/
export function normalizeCoordinate(lat: number, lng: number): [number, number] | null {
if (!isValidCoordinate(lat, lng)) {
return null;
}
return [lat, lng];
}
/**
* Checks if a coordinate is within viewport bounds
*/
export function isCoordinateInBounds(
lat: number,
lng: number,
bounds: { north: number; south: number; east: number; west: number }
): boolean {
if (!isValidCoordinate(lat, lng)) return false;
// Handle longitude wrapping (e.g., -180 to 180 crossing)
const lngInBounds =
(bounds.west <= bounds.east && lng >= bounds.west && lng <= bounds.east) ||
(bounds.west > bounds.east && (lng >= bounds.west || lng <= bounds.east));
return lat >= bounds.south && lat <= bounds.north && lngInBounds;
}
/**
* Calculates distance between two coordinates using Haversine formula
* Returns distance in kilometers
*/
export function calculateDistance(lat1: number, lng1: number, lat2: number, lng2: number): number {
if (!isValidCoordinate(lat1, lng1) || !isValidCoordinate(lat2, lng2)) {
return Infinity;
}
const R = 6371; // Earth's radius in km
const dLat = ((lat2 - lat1) * Math.PI) / 180;
const dLng = ((lng2 - lng1) * Math.PI) / 180;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((lat1 * Math.PI) / 180) *
Math.cos((lat2 * Math.PI) / 180) *
Math.sin(dLng / 2) *
Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}