/** * 高德地图服务模块 * 提供地理编码和逆地理编码功能 */ /** * 使用高德地图逆地理编码API * 将经纬度坐标转换为地址信息 * * @param {number} longitude - 经度 * @param {number} latitude - 纬度 * @returns {Promise} 地址信息 */ export const amapReverseGeocode = async (longitude: number, latitude: number): Promise => { try { const url = new URL('https://restapi.amap.com/v3/geocode/regeo') url.searchParams.append('location', `${longitude},${latitude}`) url.searchParams.append('key', '65bddc1c5df7d381507bc3ea3128b242') url.searchParams.append('radius', '1000') url.searchParams.append('extensions', 'base') url.searchParams.append('batch', 'false') const response = await fetch(url.toString()) const data = await response.json() // 检查响应状态 if (data.status === '1') { // 返回格式化的地址 return data.regeocode?.formatted_address || '位置信息获取失败' } else { console.error('高德地图API错误:', data.info) return '位置信息获取失败' } } catch (error) { console.error('逆地理编码失败:', error) return '位置服务不可用' } } /** * 使用高德地图地理编码API * 将地址转换为经纬度坐标 * * @param {string} address - 地址信息 * @returns {Promise<{longitude: number, latitude: number} | null>} 坐标信息 */ export const amapGeocode = async ( address: string ): Promise<{ longitude: number; latitude: number } | null> => { try { const url = new URL('https://restapi.amap.com/v3/geocode/geo') url.searchParams.append('address', address) url.searchParams.append('key', '65bddc1c5df7d381507bc3ea3128b242') url.searchParams.append('batch', 'false') url.searchParams.append('extensions', 'base') const response = await fetch(url.toString()) const data = await response.json() if (data.status === '1' && data.geocodes && data.geocodes.length > 0) { const location = data.geocodes[0].location const [longitude, latitude] = location.split(',') return { longitude: parseFloat(longitude), latitude: parseFloat(latitude) } } else { console.error('地理编码API错误:', data.info) return null } } catch (error) { console.error('地理编码失败:', error) return null } } /** * 计算两个坐标点之间的距离(单位:米) * 使用 Haversine 公式 * * @param {number} lon1 - 第一个点的经度 * @param {number} lat1 - 第一个点的纬度 * @param {number} lon2 - 第二个点的经度 * @param {number} lat2 - 第二个点的纬度 * @returns {number} 距离(米) */ export const calculateDistance = ( lon1: number, lat1: number, lon2: number, lat2: number ): number => { const R = 6371000 // 地球半径(米) const dLat = ((lat2 - lat1) * Math.PI) / 180 const dLon = ((lon2 - lon1) * 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(dLon / 2) * Math.sin(dLon / 2) const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) return R * c } /** * 获取地址的详细信息 * 包括省份、城市、区县等 * * @param {number} longitude - 经度 * @param {number} latitude - 纬度 * @returns {Promise} 详细地址信息 */ export const getAddressDetail = async (longitude: number, latitude: number): Promise => { try { const url = new URL('https://restapi.amap.com/v3/geocode/regeo') url.searchParams.append('location', `${longitude},${latitude}`) url.searchParams.append('key', '65bddc1c5df7d381507bc3ea3128b242') url.searchParams.append('radius', '1000') url.searchParams.append('extensions', 'all') url.searchParams.append('batch', 'false') const response = await fetch(url.toString()) const data = await response.json() if (data.status === '1') { return data.regeocode } else { console.error('获取地址详情失败:', data.info) return null } } catch (error) { console.error('获取地址详情异常:', error) return null } }