/** * 高德地图 API 客户端 * 封装路径规划 API 调用 */ import axios from 'axios' import { AMAP_CONFIG, AMAP_ENDPOINTS } from '../config/amap' import { generateCacheKey } from './geoUtils' // 路由缓存 const routeCache = new Map() /** * 清理过期缓存 */ function cleanExpiredCache() { const now = Date.now() for (const [key, value] of routeCache.entries()) { if (now - value.timestamp > AMAP_CONFIG.cacheExpiry) { routeCache.delete(key) } } } // 定期清理缓存(每小时) setInterval(cleanExpiredCache, 60 * 60 * 1000) /** * 调用高德地图驾车路径规划 API * @param {Object} origin - 起点 { lon, lat } * @param {Object} destination - 终点 { lon, lat } * @param {Object} options - 可选参数 * @returns {Promise} 路径规划结果 */ export async function calculateDrivingRoute(origin, destination, options = {}) { const cacheKey = generateCacheKey(origin, destination) // 检查缓存 if (routeCache.has(cacheKey)) { const cached = routeCache.get(cacheKey) console.log('[AmapAPI] 使用缓存路线:', cacheKey) return cached.data } const url = `${AMAP_CONFIG.baseUrl}${AMAP_ENDPOINTS.driving}` const params = { key: AMAP_CONFIG.webServiceKey, origin: `${origin.lon},${origin.lat}`, destination: `${destination.lon},${destination.lat}`, extensions: 'all', // 返回详细路径 output: 'json', strategy: options.strategy ?? AMAP_CONFIG.strategy } try { console.log('[AmapAPI] 请求路径规划:', params) const response = await axios.get(url, { params, timeout: AMAP_CONFIG.timeout }) if (response.data.status !== '1') { throw new Error(`高德API错误: ${response.data.info}`) } if (!response.data.route || !response.data.route.paths || response.data.route.paths.length === 0) { throw new Error('未找到可用路线') } const path = response.data.route.paths[0] // 提取路径数据 const routeData = { distance: parseInt(path.distance), // 米 duration: parseInt(path.duration), // 秒 polyline: extractPolyline(path.steps), steps: path.steps.map(step => ({ instruction: step.instruction, distance: parseInt(step.distance), duration: parseInt(step.duration) })) } // 缓存结果 routeCache.set(cacheKey, { data: routeData, timestamp: Date.now() }) console.log('[AmapAPI] 路径规划成功:', { distance: routeData.distance, duration: routeData.duration, points: routeData.polyline.split(';').length }) return routeData } catch (error) { console.error('[AmapAPI] 路径规划失败:', error.message) throw error } } /** * 从步骤中提取完整的 polyline * @param {Array} steps - 路径步骤数组 * @returns {string} 完整的 polyline 字符串 */ function extractPolyline(steps) { const allPolylines = steps .map(step => step.polyline) .filter(Boolean) return allPolylines.join(';') } /** * 批量计算路线(并行请求) * @param {Array} routePairs - 路线对数组 [{ origin, destination, type, name, id }] * @returns {Promise} 路线结果数组 */ export async function calculateMultipleRoutes(routePairs) { console.log(`[AmapAPI] 批量计算 ${routePairs.length} 条路线`) const promises = routePairs.map(async (pair) => { try { const routeData = await calculateDrivingRoute(pair.origin, pair.destination) return { id: pair.id, name: pair.name, type: pair.type, origin: pair.origin, destination: pair.destination, ...routeData, success: true } } catch (error) { console.warn(`[AmapAPI] 路线计算失败 (${pair.name}):`, error.message) return { id: pair.id, name: pair.name, type: pair.type, origin: pair.origin, destination: pair.destination, error: error.message, success: false } } }) const results = await Promise.all(promises) const successCount = results.filter(r => r.success).length console.log(`[AmapAPI] 批量计算完成: ${successCount}/${routePairs.length} 成功`) return results } /** * 清除所有缓存 */ export function clearRouteCache() { routeCache.clear() console.log('[AmapAPI] 缓存已清空') } /** * 获取缓存统计信息 */ export function getCacheStats() { return { size: routeCache.size, keys: Array.from(routeCache.keys()) } }