add v0.0.2
This commit is contained in:
107
plan/v0.0.2.md
Normal file
107
plan/v0.0.2.md
Normal file
@@ -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. **文件上传**:`<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 验证下载
|
||||
Reference in New Issue
Block a user