Files
tianxuan/.omo/plans/globe-v6.md
T

5.1 KiB

Globe v6 修复计划 — 最终版

TL;DR (For humans)

两个紧急修复:背面剔除 + 国境线恢复。预计 50 行变更。


P1. 背面剔除修复

原因: updatePulsesarcGroup.quaternionrotation 不同步,导致方向判断错误。

修复: 用 localToWorld 替代 applyQuaternion

templates/tianxuan/globe.htmlupdatePulses 函数中:

// 删除:
// 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) 之后添加:

// ── 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 之后添加:

<script src="{% static 'tianxuan/world_borders.js' %}"></script>

步骤 4: 恢复复选框

在 toggle 区域恢复:

<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/惯性旋转

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

  • 1. 创建 static/tianxuan/world_borders.js (10国精简轮廓)
  • 2. globe.html: 修复背面剔除 (localToWorld)
  • 3. globe.html: 恢复 borderGroup (渲染 + 加载 + 复选框 + 旋转)
  • 4. config.yaml: 添加 ":ips": ipv4, ":ipd": ipv4
  • 5. type_classifier.py: 名称模式增加 :ips :ipd
  • 6. entity_detector.py: ENTITY_KEYWORDS 增加 :ips :ipd
  • 7. views.py globe_view: 列检测增加 :ips :ipd

P4. 用户数据列名适配 (:ips, :ipd)

问题: 用户的源IP列名是 :ips,目标IP列名是 :ipd。 当前代码的IP检测靠名称模式匹配 _ip/src_ip/dst_ip,完全匹配不到。

需要修改的文件:

1. config.yaml — 添加列覆盖

columns:
  ":ips": ipv4
  ":ipd": ipv4

2. analysis/type_classifier.py — 名称模式增加 :ips :ipd

_NAME_TYPE_MAP 中添加:

(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

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(不截断)

# 全局替换 ALL:
tb[:500]     tb
tb[:5000]    tb

涉及的代码位置:

  • _background_process (line ~385)
  • _run_analysis_worker (line ~527)
  • 任何其他 tb[:500] 出现处

Final Verification Wave

  • F1. pytest tests -q → 121 pass
  • F2. 清理: 删除临时文件
  • F3. 完整端到端测试: 启动服务 → 上传 CSV → 预处理 → 手动分析 → 聚类 → 地球

依赖

全部独立,可并行执行。