diff --git a/plan/v0.0.2.md b/plan/v0.0.2.md new file mode 100644 index 0000000..f0eeb20 --- /dev/null +++ b/plan/v0.0.2.md @@ -0,0 +1,107 @@ +# 地图距离计算网页版 (v0.0.2) + +## 需求 + +创建一个纯网页版的距离计算工具: +- AMAP_KEY 可编辑并保存到浏览器 localStorage +- 上传 JSON 数据文件计算多组距离 +- 调用高德地图 API 计算距离 +- 表格展示结果:来源地址 | 目的地地址 | 距离(km) +- 导出 CSV 功能 + +## JSON 输入格式 + +```json +[ + {"from": "北京市", "to": "上海市"}, + {"from": "广州市", "to": "深圳市"} +] +``` + +## 实现方案 + +1. **Key 管理**:使用 localStorage 保存/读取 AMAP_KEY +2. **文件上传**:`` + FileReader 解析 +3. **高德 API**:使用 `Geocode` 地理编码 API + - URL: `https://restapi.amap.com/v3/geocode/geo?address={address}&key={key}` + - 将地址转换为经纬度坐标 +4. **距离计算**:使用 Haversine 公式计算两点间直线距离 + - 地球半径: 6371000 米 + - 转换为公里,保留2位小数 +5. **CSV 导出**:原生 JS 生成 Blob 下载 + +## 依赖 + +- **无外部 JS 库**,纯原生 HTML/CSS/JavaScript 实现 + +## 文件结构 + +``` +public/ + web.html # 完整的网页实现 +``` + +## 关键代码 + +### 地理编码 +```javascript +async function geocode(address, key) { + const url = `https://restapi.amap.com/v3/geocode/geo?address=${encodeURIComponent(address)}&key=${key}`; + const res = await fetch(url).then(r => r.json()); + if (res.status === '1' && res.geocodes?.length > 0) { + const [lng, lat] = res.geocodes[0].location.split(',').map(Number); + return { lng, lat }; + } + return null; +} +``` + +### Haversine 距离计算 +```javascript +function calculateDistance(from, to) { + const R = 6371000; // 地球半径(米) + const dLat = (to.lat - from.lat) * Math.PI / 180; + const dLng = (to.lng - from.lng) * Math.PI / 180; + const a = + Math.sin(dLat / 2) ** 2 + + Math.cos(from.lat * Math.PI / 180) * + Math.cos(to.lat * Math.PI / 180) * + Math.sin(dLng / 2) ** 2; + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return R * c; +} +``` + +### 获取距离 +```javascript +async function getDistance(fromAddress, toAddress, key) { + const [from, to] = await Promise.all([ + geocode(fromAddress, key), + geocode(toAddress, key) + ]); + if (!from || !to) return '解析失败'; + const distance = calculateDistance(from, to); + return (distance / 1000).toFixed(2) + ' km'; +} +``` + +### CSV 导出 +```javascript +function exportCSV(results) { + const csv = 'from,to,distance\n' + results.map(r => `${r.from},${r.to},${r.distance}`).join('\n'); + const blob = new Blob([csv], { type: 'text/csv' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'distance_results.csv'; + a.click(); +} +``` + +## 验证步骤 + +1. 浏览器打开 `public/web.html` +2. 输入 AMAP_KEY 并保存 +3. 上传测试 JSON 文件 +4. 查看计算结果表格 +5. 点击导出 CSV 验证下载 diff --git a/public/docs-web.md b/public/docs-web.md new file mode 100644 index 0000000..808a3cc --- /dev/null +++ b/public/docs-web.md @@ -0,0 +1,48 @@ +# 网页版地图距离计算器 + +在线使用:[https://kevisual.xiongxiao.me/root/test-map-distance/web.html](https://kevisual.xiongxiao.me/root/test-map-distance/web.html) + +## 功能特性 + +- AMAP_KEY 保存到浏览器localStorage,无需重复输入 +- 上传 JSON 文件批量计算距离 +- 使用 Haversine 公式计算两点间直线距离 +- 结果表格展示 +- 导出 CSV 文件 + +## 使用方法 + +### 1. 配置高德地图 Key + +1. 访问 [高德开放平台](https://console.amap.com/dev/key/app) 注册/登录账号 +2. 创建 Web 应用,获取 API Key +3. 在网页中输入 Key,点击「保存 Key」 + +### 2. 准备 JSON 数据 + +创建 JSON 文件,格式如下: + +```json +[ + {"from": "北京市", "to": "上海市"}, + {"from": "广州市", "to": "深圳市"}, + {"from": "杭州市", "to": "南京市"} +] +``` + +### 3. 上传并计算 + +1. 点击「选择文件」,上传准备好的 JSON 文件 +2. 点击「开始计算」 +3. 等待计算完成,查看结果表格 + +### 4. 导出结果 + +计算完成后,点击「导出 CSV」下载结果文件。 + +## 注意事项 + +- 需要有效的 AMAP_KEY 才能正常使用 +- 地理编码服务有每日调用限制 +- 地址越精确,计算结果越准确 +- 直线距离与实际行驶距离可能存在差异 diff --git a/public/index.html b/public/index.html index 6ae1cce..c421f78 100644 --- a/public/index.html +++ b/public/index.html @@ -132,6 +132,13 @@

地图距离计算工具 - 使用说明

+ +
+
+ + +
+
@@ -154,9 +161,24 @@ diff --git a/public/web.html b/public/web.html new file mode 100644 index 0000000..ee0b5d3 --- /dev/null +++ b/public/web.html @@ -0,0 +1,270 @@ + + + + + + 地图距离计算器 + + + +

地图距离计算器

+ + +
+

高德地图 Key

+
+ + +
+
Key 将保存到浏览器本地存储
+
+
+ + +
+

上传 JSON 数据

+
+ + +
+
JSON 格式: [{"from": "北京市", "to": "上海市"}, ...]
+
+
+
+ + + + + + +