179 lines
4.5 KiB
JavaScript
Raw Normal View History

/**
* 高德地图 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<Object>} 路径规划结果
*/
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<Array>} 路线结果数组
*/
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())
}
}