{"version":3,"file":"LocationUtils.mjs","sources":["../src/LocationUtils.ts"],"sourcesContent":["/**\n * @module LocationUtils\n * @description A comprehensive collection of utility functions for working with geographic locations and coordinates.\n * Provides methods for calculating distances, bearings, and destinations using the Haversine formula,\n * converting between coordinate formats (DD, DMS), working with the Geolocation API,\n * managing bounding boxes, and handling coordinate transformations.\n * @example\n * ```typescript\n * import { LocationUtils } from 'houser-js-utils';\n *\n * // Calculate distance between two points\n * const distance = LocationUtils.calculateDistance(40.7128, -74.0060, 51.5074, -0.1278);\n * console.log(`Distance: ${distance.toFixed(2)} km`);\n *\n * // Format coordinates in DMS format\n * const formatted = LocationUtils.formatCoordinate(40.7128, -74.0060, 'DMS');\n * console.log(formatted); // \"40° 42' 46.08\" N, 74° 0' 21.60\" W\"\n *\n * // Get current position\n * const position = await LocationUtils.getCurrentPosition();\n * console.log(`Current location: ${position.coords.latitude}, ${position.coords.longitude}`);\n * ```\n */\n\nexport const LocationUtils = {\n  /**\n   * Calculates the bearing (direction) between two geographic coordinates using the Haversine formula.\n   * @param lat1 - The first latitude in degrees\n   * @param lon1 - The first longitude in degrees\n   * @param lat2 - The second latitude in degrees\n   * @param lon2 - The second longitude in degrees\n   * @returns The bearing in degrees (0-360) from north\n   * @example\n   * ```typescript\n   * // Calculate bearing from New York to London\n   * const bearing = LocationUtils.calculateBearing(40.7128, -74.0060, 51.5074, -0.1278);\n   * console.log(`Bearing: ${bearing.toFixed(1)}°`); // \"Bearing: 77.5°\"\n   *\n   * // Calculate bearing between two points in the same city\n   * const localBearing = LocationUtils.calculateBearing(40.7128, -74.0060, 40.7589, -73.9851);\n   * console.log(`Local bearing: ${localBearing.toFixed(1)}°`); // \"Local bearing: 45.2°\"\n   * ```\n   */\n  calculateBearing(\n    lat1: number,\n    lon1: number,\n    lat2: number,\n    lon2: number\n  ): number {\n    const dLon = this.toRad(lon2 - lon1);\n    const lat1Rad = this.toRad(lat1);\n    const lat2Rad = this.toRad(lat2);\n\n    const y = Math.sin(dLon) * Math.cos(lat2Rad);\n    const x =\n      Math.cos(lat1Rad) * Math.sin(lat2Rad) -\n      Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon);\n\n    let bearing = this.toDeg(Math.atan2(y, x));\n    bearing = (bearing + 360) % 360;\n    return bearing;\n  },\n\n  /**\n   * Calculates a new coordinate point based on a starting point, distance, and bearing using the Haversine formula.\n   * @param lat - The starting latitude in degrees\n   * @param lon - The starting longitude in degrees\n   * @param distance - The distance to travel in kilometers\n   * @param bearing - The bearing (direction) in degrees (0-360)\n   * @returns An object containing the new latitude and longitude coordinates\n   * @example\n   * ```typescript\n   * // Calculate a point 100km northeast of New York\n   * const destination = LocationUtils.calculateDestination(40.7128, -74.0060, 100, 45);\n   * console.log(`Destination: ${destination.latitude.toFixed(4)}, ${destination.longitude.toFixed(4)}`);\n   * // \"Destination: 41.4000, -73.1000\"\n   *\n   * // Calculate a point 50km south of a location\n   * const southPoint = LocationUtils.calculateDestination(40.7128, -74.0060, 50, 180);\n   * console.log(`South point: ${southPoint.latitude.toFixed(4)}, ${southPoint.longitude.toFixed(4)}`);\n   * ```\n   */\n  calculateDestination(\n    lat: number,\n    lon: number,\n    distance: number,\n    bearing: number\n  ): { latitude: number; longitude: number } {\n    const R = 6371; // Earth's radius in kilometers\n    const d = distance / R; // Angular distance\n    const lat1 = this.toRad(lat);\n    const lon1 = this.toRad(lon);\n    const brng = this.toRad(bearing);\n\n    const lat2 = Math.asin(\n      Math.sin(lat1) * Math.cos(d) +\n        Math.cos(lat1) * Math.sin(d) * Math.cos(brng)\n    );\n\n    const lon2 =\n      lon1 +\n      Math.atan2(\n        Math.sin(brng) * Math.sin(d) * Math.cos(lat1),\n        Math.cos(d) - Math.sin(lat1) * Math.sin(lat2)\n      );\n\n    return {\n      latitude: this.toDeg(lat2),\n      longitude: this.toDeg(lon2),\n    };\n  },\n\n  /**\n   * Calculates the great-circle distance between two geographic coordinates using the Haversine formula.\n   * @param lat1 - The first latitude in degrees\n   * @param lon1 - The first longitude in degrees\n   * @param lat2 - The second latitude in degrees\n   * @param lon2 - The second longitude in degrees\n   * @returns The distance in kilometers\n   * @example\n   * ```typescript\n   * // Calculate distance between New York and London\n   * const distance = LocationUtils.calculateDistance(40.7128, -74.0060, 51.5074, -0.1278);\n   * console.log(`Distance: ${distance.toFixed(1)} km`); // \"Distance: 5570.2 km\"\n   *\n   * // Calculate distance between two points in the same city\n   * const localDistance = LocationUtils.calculateDistance(40.7128, -74.0060, 40.7589, -73.9851);\n   * console.log(`Local distance: ${localDistance.toFixed(2)} km`); // \"Local distance: 8.45 km\"\n   * ```\n   */\n  calculateDistance(\n    lat1: number,\n    lon1: number,\n    lat2: number,\n    lon2: number\n  ): number {\n    const R = 6371; // Earth's radius in kilometers\n    const dLat = this.toRad(lat2 - lat1);\n    const dLon = this.toRad(lon2 - lon1);\n    const a =\n      Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n      Math.cos(this.toRad(lat1)) *\n        Math.cos(this.toRad(lat2)) *\n        Math.sin(dLon / 2) *\n        Math.sin(dLon / 2);\n    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n    return R * c;\n  },\n\n  /**\n   * Stops watching the user's position that was previously started with watchPosition.\n   * @param watchId - The watch ID returned by watchPosition\n   * @throws {Error} If geolocation is not supported by the browser\n   * @example\n   * ```typescript\n   * // Start watching position\n   * const watchId = LocationUtils.watchPosition(position => {\n   *   console.log('Position updated:', position.coords);\n   * });\n   *\n   * // Later, stop watching\n   * LocationUtils.clearWatch(watchId);\n   * console.log('Position watching stopped');\n   * ```\n   */\n  clearWatch(watchId: number): void {\n    if (!navigator.geolocation) {\n      throw new Error(\"Geolocation is not supported by your browser\");\n    }\n\n    navigator.geolocation.clearWatch(watchId);\n  },\n\n  /**\n   * Formats geographic coordinates as a string in either decimal degrees (DD) or degrees, minutes, seconds (DMS) format.\n   * @param lat - The latitude in degrees\n   * @param lon - The longitude in degrees\n   * @param format - The format to use: 'DD' for decimal degrees or 'DMS' for degrees, minutes, seconds\n   * @returns A formatted coordinate string\n   * @example\n   * ```typescript\n   * // Decimal degrees format\n   * const dd = LocationUtils.formatCoordinate(40.7128, -74.0060, 'DD');\n   * console.log(dd); // \"40.712800, -74.006000\"\n   *\n   * // Degrees, minutes, seconds format\n   * const dms = LocationUtils.formatCoordinate(40.7128, -74.0060, 'DMS');\n   * console.log(dms); // \"40° 42' 46.08\" N, 74° 0' 21.60\" W\"\n   *\n   * // Southern hemisphere example\n   * const sydney = LocationUtils.formatCoordinate(-33.8688, 151.2093, 'DMS');\n   * console.log(sydney); // \"33° 52' 7.68\" S, 151° 12' 33.48\" E\"\n   * ```\n   */\n  formatCoordinate(\n    lat: number,\n    lon: number,\n    format: \"DMS\" | \"DD\" = \"DD\"\n  ): string {\n    if (format === \"DD\") {\n      return `${lat.toFixed(6)}, ${lon.toFixed(6)}`;\n    }\n\n    const latDir = lat >= 0 ? \"N\" : \"S\";\n    const lonDir = lon >= 0 ? \"E\" : \"W\";\n    const latAbs = Math.abs(lat);\n    const lonAbs = Math.abs(lon);\n\n    const latDeg = Math.floor(latAbs);\n    const latMin = Math.floor((latAbs - latDeg) * 60);\n    const latSec = ((latAbs - latDeg) * 60 - latMin) * 60;\n\n    const lonDeg = Math.floor(lonAbs);\n    const lonMin = Math.floor((lonAbs - lonDeg) * 60);\n    const lonSec = ((lonAbs - lonDeg) * 60 - lonMin) * 60;\n\n    return `${latDeg}° ${latMin}' ${latSec.toFixed(\n      2\n    )}\" ${latDir}, ${lonDeg}° ${lonMin}' ${lonSec.toFixed(2)}\" ${lonDir}`;\n  },\n\n  /**\n   * Gets the user's current position using the browser's Geolocation API.\n   * @param options - Geolocation options for accuracy, timeout, and maximum age\n   * @returns A Promise that resolves with the GeolocationPosition object\n   * @throws {Error} If geolocation is not supported by the browser\n   * @example\n   * ```typescript\n   * try {\n   *   const position = await LocationUtils.getCurrentPosition({\n   *     enableHighAccuracy: true,\n   *     timeout: 5000,\n   *     maximumAge: 0\n   *   });\n   *\n   *   console.log(`Latitude: ${position.coords.latitude}`);\n   *   console.log(`Longitude: ${position.coords.longitude}`);\n   *   console.log(`Accuracy: ${position.coords.accuracy} meters`);\n   * } catch (error) {\n   *   console.error('Error getting position:', error);\n   * }\n   * ```\n   */\n  async getCurrentPosition(\n    options: PositionOptions = {\n      enableHighAccuracy: true,\n      timeout: 5000,\n      maximumAge: 0,\n    }\n  ): Promise<GeolocationPosition> {\n    return new Promise((resolve, reject) => {\n      if (!navigator.geolocation) {\n        reject(new Error(\"Geolocation is not supported by your browser\"));\n        return;\n      }\n\n      navigator.geolocation.getCurrentPosition(resolve, reject, options);\n    });\n  },\n\n  /**\n   * Calculates the center point of a geographic bounding box.\n   * @param bounds - The bounding box with north, south, east, and west coordinates\n   * @returns An object containing the latitude and longitude of the center point\n   * @example\n   * ```typescript\n   * const bounds = {\n   *   north: 41.0,\n   *   south: 40.0,\n   *   east: -73.0,\n   *   west: -74.0\n   * };\n   *\n   * const center = LocationUtils.getBoundsCenter(bounds);\n   * console.log(`Center: ${center.latitude.toFixed(4)}, ${center.longitude.toFixed(4)}`);\n   * // \"Center: 40.5000, -73.5000\"\n   * ```\n   */\n  getBoundsCenter(bounds: {\n    north: number;\n    south: number;\n    east: number;\n    west: number;\n  }): { latitude: number; longitude: number } {\n    return {\n      latitude: (bounds.north + bounds.south) / 2,\n      longitude: (bounds.east + bounds.west) / 2,\n    };\n  },\n\n  /**\n   * Calculates a bounding box for a given radius around a center point.\n   * @param lat - The center latitude in degrees\n   * @param lon - The center longitude in degrees\n   * @param radius - The radius in kilometers\n   * @returns A bounding box with north, south, east, and west coordinates\n   * @example\n   * ```typescript\n   * // Get bounding box for 10km radius around New York\n   * const bounds = LocationUtils.getBoundsForRadius(40.7128, -74.0060, 10);\n   * console.log('Bounding box:', bounds);\n   * // {\n   * //   north: 40.8028,\n   * //   south: 40.6228,\n   * //   east: -73.9060,\n   * //   west: -74.1060\n   * // }\n   *\n   * // Check if a point is within this radius\n   * const isInside = LocationUtils.isWithinBounds(40.7589, -73.9851, bounds);\n   * console.log(`Point is within 10km: ${isInside}`); // true\n   * ```\n   */\n  getBoundsForRadius(\n    lat: number,\n    lon: number,\n    radius: number\n  ): {\n    north: number;\n    south: number;\n    east: number;\n    west: number;\n  } {\n    const R = 6371; // Earth's radius in kilometers\n    const latRad = this.toRad(lat);\n    const lonRad = this.toRad(lon);\n    const d = radius / R; // Angular distance\n\n    const north = this.toDeg(latRad + d);\n    const south = this.toDeg(latRad - d);\n    const east = this.toDeg(lonRad + d / Math.cos(latRad));\n    const west = this.toDeg(lonRad - d / Math.cos(latRad));\n\n    return { north, south, east, west };\n  },\n\n  /**\n   * Checks if a coordinate point is within a geographic bounding box.\n   * @param lat - The latitude to check in degrees\n   * @param lon - The longitude to check in degrees\n   * @param bounds - The bounding box with north, south, east, and west coordinates\n   * @returns True if the coordinate is within the bounds, false otherwise\n   * @example\n   * ```typescript\n   * const bounds = {\n   *   north: 41.0,\n   *   south: 40.0,\n   *   east: -73.0,\n   *   west: -75.0\n   * };\n   *\n   * // Check if New York is within bounds\n   * const isInside = LocationUtils.isWithinBounds(40.7128, -74.0060, bounds);\n   * console.log(`New York is within bounds: ${isInside}`); // true\n   *\n   * // Check if London is within bounds\n   * const isLondonInside = LocationUtils.isWithinBounds(51.5074, -0.1278, bounds);\n   * console.log(`London is within bounds: ${isLondonInside}`); // false\n   * ```\n   */\n  isWithinBounds(\n    lat: number,\n    lon: number,\n    bounds: {\n      north: number;\n      south: number;\n      east: number;\n      west: number;\n    }\n  ): boolean {\n    return (\n      lat <= bounds.north &&\n      lat >= bounds.south &&\n      lon <= bounds.east &&\n      lon >= bounds.west\n    );\n  },\n\n  /**\n   * Parses a coordinate string in decimal degrees format into latitude and longitude values.\n   * @param coordinate - The coordinate string in \"latitude, longitude\" format\n   * @returns An object containing the parsed latitude and longitude\n   * @throws {Error} If the coordinate string is invalid or cannot be parsed\n   * @example\n   * ```typescript\n   * // Parse a coordinate string\n   * const coord = LocationUtils.parseCoordinate(\"40.7128, -74.0060\");\n   * console.log(`Latitude: ${coord.latitude}, Longitude: ${coord.longitude}`);\n   * // \"Latitude: 40.7128, Longitude: -74.0060\"\n   *\n   * try {\n   *   // Invalid format\n   *   const invalid = LocationUtils.parseCoordinate(\"invalid\");\n   * } catch (error) {\n   *   console.error('Error:', error.message); // \"Invalid coordinate format\"\n   * }\n   * ```\n   */\n  parseCoordinate(coordinate: string): { latitude: number; longitude: number } {\n    const parts = coordinate.split(\",\").map((part) => part.trim());\n    if (parts.length !== 2) {\n      throw new Error(\"Invalid coordinate format\");\n    }\n\n    const lat = parseFloat(parts[0]);\n    const lon = parseFloat(parts[1]);\n\n    if (isNaN(lat) || isNaN(lon)) {\n      throw new Error(\"Invalid coordinate values\");\n    }\n\n    return { latitude: lat, longitude: lon };\n  },\n\n  /**\n   * Converts an angle from radians to degrees.\n   * @param radians - The angle in radians\n   * @returns The angle in degrees\n   * @example\n   * ```typescript\n   * const degrees = LocationUtils.toDeg(Math.PI);\n   * console.log(`${degrees}°`); // \"180°\"\n   *\n   * const halfCircle = LocationUtils.toDeg(Math.PI / 2);\n   * console.log(`${halfCircle}°`); // \"90°\"\n   * ```\n   */\n  toDeg(radians: number): number {\n    return (radians * 180) / Math.PI;\n  },\n\n  /**\n   * Converts an angle from degrees to radians.\n   * @param degrees - The angle in degrees\n   * @returns The angle in radians\n   * @example\n   * ```typescript\n   * const radians = LocationUtils.toRad(180);\n   * console.log(radians); // 3.141592653589793 (Math.PI)\n   *\n   * const halfCircle = LocationUtils.toRad(90);\n   * console.log(halfCircle); // 1.5707963267948966 (Math.PI / 2)\n   * ```\n   */\n  toRad(degrees: number): number {\n    return (degrees * Math.PI) / 180;\n  },\n\n  /**\n   * Starts watching the user's position using the browser's Geolocation API.\n   * @param callback - The callback function to be called with position updates\n   * @param options - Geolocation options for accuracy, timeout, and maximum age\n   * @returns A watch ID that can be used to stop watching with clearWatch\n   * @throws {Error} If geolocation is not supported by the browser\n   * @example\n   * ```typescript\n   * // Start watching position with high accuracy\n   * const watchId = LocationUtils.watchPosition(\n   *   position => {\n   *     console.log('Position updated:');\n   *     console.log(`Latitude: ${position.coords.latitude}`);\n   *     console.log(`Longitude: ${position.coords.longitude}`);\n   *     console.log(`Accuracy: ${position.coords.accuracy} meters`);\n   *   },\n   *   {\n   *     enableHighAccuracy: true,\n   *     timeout: 5000,\n   *     maximumAge: 0\n   *   }\n   * );\n   *\n   * // Later, stop watching\n   * LocationUtils.clearWatch(watchId);\n   * ```\n   */\n  watchPosition(\n    callback: (position: GeolocationPosition) => void,\n    options: PositionOptions = {\n      enableHighAccuracy: true,\n      timeout: 5000,\n      maximumAge: 0,\n    }\n  ): number {\n    if (!navigator.geolocation) {\n      throw new Error(\"Geolocation is not supported by your browser\");\n    }\n\n    return navigator.geolocation.watchPosition(callback, undefined, options);\n  },\n};\n"],"names":[],"mappings":"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"}