Files
test-map-distance/plan/v0.0.2.md
2026-01-09 23:14:45 +08:00

108 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 地图距离计算网页版 (v0.0.2)
## 需求
创建一个纯网页版的距离计算工具:
- AMAP_KEY 可编辑并保存到浏览器 localStorage
- 上传 JSON 数据文件计算多组距离
- 调用高德地图 API 计算距离
- 表格展示结果:来源地址 | 目的地地址 | 距离(km)
- 导出 CSV 功能
## JSON 输入格式
```json
[
{"from": "北京市", "to": "上海市"},
{"from": "广州市", "to": "深圳市"}
]
```
## 实现方案
1. **Key 管理**:使用 localStorage 保存/读取 AMAP_KEY
2. **文件上传**`<input type="file" accept=".json">` + 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 验证下载