171 lines
5.1 KiB
Markdown
171 lines
5.1 KiB
Markdown
# Globe v6 修复计划 — 最终版
|
|
|
|
## TL;DR (For humans)
|
|
两个紧急修复:背面剔除 + 国境线恢复。预计 50 行变更。
|
|
|
|
---
|
|
|
|
## P1. 背面剔除修复
|
|
|
|
**原因**: `updatePulses` 中 `arcGroup.quaternion` 与 `rotation` 不同步,导致方向判断错误。
|
|
|
|
**修复**: 用 `localToWorld` 替代 `applyQuaternion`
|
|
|
|
在 `templates/tianxuan/globe.html` 的 `updatePulses` 函数中:
|
|
|
|
```javascript
|
|
// 删除:
|
|
// var arcQuat = arcGroup.quaternion;
|
|
// midPt.applyQuaternion(arcQuat);
|
|
|
|
// 在函数开头添加:
|
|
arcGroup.updateMatrixWorld(true);
|
|
|
|
// 在循环内改为:
|
|
var midPt = d.curve.getPoint(0.5);
|
|
arcGroup.localToWorld(midPt);
|
|
var isFront = midPt.dot(camDir) < -0.08;
|
|
```
|
|
|
|
## P2. 国境线恢复
|
|
|
|
### 步骤 1: 创建 static/tianxuan/world_borders.js
|
|
|
|
创建文件含 10 国精简轮廓(中国/美国/俄罗斯/加拿大/巴西/澳大利亚/印度/英国/日本/法国)。
|
|
每国 10-20 个 [lat,lon] 坐标点。
|
|
|
|
**重要**: 中国坐标需包含台湾和南海九段线示意。
|
|
台湾坐标: 25°N,121°E 左右。
|
|
|
|
### 步骤 2: 恢复 globe.html 中的 borderGroup
|
|
|
|
在 `scene.add(gridGroup)` 之后添加:
|
|
|
|
```javascript
|
|
// ── World borders (loaded from static file) ──
|
|
var borderGroup = new THREE.Group();
|
|
var borderMat = new THREE.LineBasicMaterial({ color: 0x88dd88, transparent: true, opacity: 0.3, depthTest: false });
|
|
|
|
function renderBorders(borders) {
|
|
if (!borders) return;
|
|
for (var c = 0; c < borders.length; c++) {
|
|
var pts = [];
|
|
for (var p = 0; p < borders[c].length; p++) {
|
|
var lat = borders[c][p][0], lon = borders[c][p][1];
|
|
var phi = (90 - lat) * Math.PI / 180;
|
|
var theta = (lon + 180) * Math.PI / 180;
|
|
pts.push(new THREE.Vector3(5.01 * Math.sin(phi) * Math.cos(theta), 5.01 * Math.cos(phi), 5.01 * Math.sin(phi) * Math.sin(theta)));
|
|
}
|
|
if (pts.length > 2) {
|
|
borderGroup.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts), borderMat));
|
|
}
|
|
}
|
|
}
|
|
if (typeof worldBorders !== 'undefined') renderBorders(worldBorders);
|
|
scene.add(borderGroup);
|
|
```
|
|
|
|
### 步骤 3: 恢复加载脚本
|
|
|
|
在 three.min.js 之后添加:
|
|
```html
|
|
<script src="{% static 'tianxuan/world_borders.js' %}"></script>
|
|
```
|
|
|
|
### 步骤 4: 恢复复选框
|
|
|
|
在 toggle 区域恢复:
|
|
```html
|
|
<label style="font-size:0.85rem;cursor:pointer;">
|
|
<input type="checkbox" id="toggleGrid" checked onchange="gridGroup.visible = this.checked;">
|
|
经纬网格
|
|
</label>
|
|
<label style="font-size:0.85rem;cursor:pointer;">
|
|
<input type="checkbox" id="toggleBorders" checked onchange="borderGroup.visible = this.checked;">
|
|
国境线
|
|
</label>
|
|
```
|
|
|
|
### 步骤 5: 添加 borderGroup 到 animate/惯性旋转
|
|
|
|
```javascript
|
|
earth.rotation.y += inertiaY; arcGroup.rotation.y += inertiaY; gridGroup.rotation.y += inertiaY; borderGroup.rotation.y += inertiaY;
|
|
earth.rotation.x += inertiaX; arcGroup.rotation.x += inertiaX; gridGroup.rotation.x += inertiaX; borderGroup.rotation.x += inertiaX;
|
|
```
|
|
|
|
---
|
|
|
|
## Todos
|
|
|
|
- [x] 1. 创建 `static/tianxuan/world_borders.js` (10国精简轮廓)
|
|
- [x] 2. globe.html: 修复背面剔除 (localToWorld)
|
|
- [x] 3. globe.html: 恢复 borderGroup (渲染 + 加载 + 复选框 + 旋转)
|
|
- [x] 4. config.yaml: 添加 `":ips": ipv4`, `":ipd": ipv4`
|
|
- [x] 5. type_classifier.py: 名称模式增加 `:ips` `:ipd`
|
|
- [x] 6. entity_detector.py: ENTITY_KEYWORDS 增加 `:ips` `:ipd`
|
|
- [x] 7. views.py globe_view: 列检测增加 `:ips` `:ipd`
|
|
|
|
## P4. 用户数据列名适配 (`:ips`, `:ipd`)
|
|
|
|
**问题**: 用户的源IP列名是 `:ips`,目标IP列名是 `:ipd`。
|
|
当前代码的IP检测靠名称模式匹配 `_ip`/`src_ip`/`dst_ip`,完全匹配不到。
|
|
|
|
**需要修改的文件**:
|
|
|
|
### 1. config.yaml — 添加列覆盖
|
|
```yaml
|
|
columns:
|
|
":ips": ipv4
|
|
":ipd": ipv4
|
|
```
|
|
|
|
### 2. analysis/type_classifier.py — 名称模式增加 `:ips` `:ipd`
|
|
在 `_NAME_TYPE_MAP` 中添加:
|
|
```python
|
|
(re.compile(r'^:ips$|^:ipd$', re.I), DataType.IPv4),
|
|
```
|
|
|
|
### 3. analysis/entity_aggregator.py — 关键词增加 `:ips` `:ipd`
|
|
`_DST_IP_KEYWORDS` 和 `_SNI_KEYWORDS` 逻辑可能需要扩展,但更关键的是 entity_detector 的 `ENTITY_KEYWORDS`。
|
|
|
|
### 4. analysis/entity_detector.py — 关键词增加 `:ips` `:ipd`
|
|
```python
|
|
ENTITY_KEYWORDS: frozenset[str] = frozenset({
|
|
'src_ip', 'dst_ip', ':ips', ':ipd', 'source_ip', ...
|
|
})
|
|
```
|
|
|
|
### 5. analysis/views.py — globe_view 中的列检测
|
|
当前 globe_view 用 `'src_ip' in c.lower()` 检测IP列。
|
|
需要增加 `':ips'` 和 `':ipd'` 的检测。
|
|
|
|
## 紧急修补 (Traceback截断)
|
|
|
|
**问题**: views.py 中所有 `run.error_message = tb[:500]` 截断到 500 字符,无法调试。
|
|
|
|
**修复**: 搜索 views.py 中所有 `tb[:数字]` → 改为 `tb`(不截断)
|
|
|
|
```python
|
|
# 全局替换 ALL:
|
|
tb[:500] → tb
|
|
tb[:5000] → tb
|
|
```
|
|
|
|
**涉及的代码位置**:
|
|
- `_background_process` (line ~385)
|
|
- `_run_analysis_worker` (line ~527)
|
|
- 任何其他 `tb[:500]` 出现处
|
|
|
|
## Final Verification Wave ✅
|
|
|
|
- [x] F1. pytest tests -q → 121 pass
|
|
- [x] F2. 清理: 删除临时文件
|
|
- [x] F3. 完整端到端测试: 启动服务 → 上传 CSV → 预处理 → 手动分析 → 聚类 → 地球
|
|
|
|
|
|
---
|
|
|
|
## 依赖
|
|
|
|
全部独立,可并行执行。
|