From ec43baf6c032842eac86c58788b6029413735307 Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sun, 5 Jul 2026 16:01:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(rail-map):=20=E4=BF=AE=E5=A4=8D=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E8=B7=AF=E7=AB=99=E7=82=B9=E5=9D=90=E6=A0=87=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E5=B9=B6=E4=BC=98=E5=8C=96=E7=BA=BF=E8=B7=AF=E6=B8=B2?= =?UTF-8?q?=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增按规范站名分组计算平均Y坐标的逻辑,解决同一站点对应多代码时的位置偏移问题。将SVG线路的直线段替换为贝塞尔曲线提升视觉流畅度,同时简化站点标记和辅助线的绘制代码,移除冗余的排序操作。 --- web/ticket-order.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/web/ticket-order.js b/web/ticket-order.js index 89e5d8f..0a7df20 100644 --- a/web/ticket-order.js +++ b/web/ticket-order.js @@ -190,10 +190,24 @@ } stationYByCanonical = {}; + const ysByCanonical = {}; for (const c of Object.keys(primaryLineByStation)) { const li = primaryLineByStation[c]; if (li == null) continue; - stationYByCanonical[c] = baseY + li * lineGapY; + const canonical = stationCanonicalByCode[c] || c; + if (!ysByCanonical[canonical]) ysByCanonical[canonical] = []; + ysByCanonical[canonical].push(baseY + li * lineGapY); + } + + const canonicalY = {}; + for (const canonical of Object.keys(ysByCanonical)) { + const ys = ysByCanonical[canonical]; + canonicalY[canonical] = ys.reduce((a,b) => a+b, 0) / ys.length; + } + + for (const c of Object.keys(primaryLineByStation)) { + const canonical = stationCanonicalByCode[c] || c; + stationYByCanonical[c] = canonicalY[canonical]; } const allStations = Object.keys(primaryLineByStation); @@ -229,7 +243,10 @@ let d = `M ${pts[0].x} ${pts[0].y}`; for (let i = 1; i < pts.length; i++) { - d += ` L ${pts[i].x} ${pts[i].y}`; + const prev = pts[i-1]; + const curr = pts[i]; + const midX = (prev.x + curr.x) / 2; + d += ` C ${midX} ${prev.y}, ${midX} ${curr.y}, ${curr.x} ${curr.y}`; } svgContent += ``; } @@ -238,11 +255,10 @@ for (const canonical of Object.keys(stationCodesByCanonical)) { const codes = (stationCodesByCanonical[canonical] || []).filter(code => Number.isFinite(stationYByCanonical[code])); if (codes.length < 2) continue; - const ys = codes.map(code => stationYByCanonical[code]).sort((a, b) => a - b); const x = stationXByCanonical[canonical]; - const labelY = ys[ys.length - 1] + 34; - svgContent += ``; - svgContent += ``; + const y = stationYByCanonical[codes[0]]; + const labelY = y + 34; + svgContent += ``; svgContent += ``; svgContent += `${getStationDisplayName(canonical)}`; labelShownForCanonical.add(canonical);