fix(B05): 초기노선 갈래 화면을 서버 길 모양(PLAN 20장 API 줄)에 맞춤
- 요청 { mode, weights?{expected, earthwork, grade} } — logic · slope 가정을 버림
- 비교값 avg_grade_pct · over_limit.total · offset_avg_m, 기준값 pending(비면 확정) 읽기
- [확인] 몸통 initial 도 { mode, weights }
- 시험 test_b05_routeedit_initial.py 를 서버 답 모양으로
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015sCeZz8z8YnbovsKgn7HK7
This commit is contained in:
@@ -55,10 +55,10 @@ const { DEFAULT_WEIGHTS } = model;
|
||||
const moves = [
|
||||
model.rebalanceWeights(DEFAULT_WEIGHTS, "expected", 70),
|
||||
model.rebalanceWeights(DEFAULT_WEIGHTS, "earthwork", 40),
|
||||
model.rebalanceWeights({ expected: 100, earthwork: 0, slope: 0 }, "expected", 60),
|
||||
model.rebalanceWeights({ expected: 20, earthwork: 30, slope: 50 }, "slope", 100),
|
||||
model.rebalanceWeights({ expected: 33, earthwork: 33, slope: 34 }, "earthwork", 33.4),
|
||||
model.rebalanceWeights(DEFAULT_WEIGHTS, "slope", -5),
|
||||
model.rebalanceWeights({ expected: 100, earthwork: 0, grade: 0 }, "expected", 60),
|
||||
model.rebalanceWeights({ expected: 20, earthwork: 30, grade: 50 }, "grade", 100),
|
||||
model.rebalanceWeights({ expected: 33, earthwork: 33, grade: 34 }, "earthwork", 33.4),
|
||||
model.rebalanceWeights(DEFAULT_WEIGHTS, "grade", -5),
|
||||
];
|
||||
|
||||
// ② 서버 답 펴기 — 노드 목록 꼴과 `/route/plan` 꼴(노드+곡선) 둘 다.
|
||||
@@ -69,16 +69,25 @@ const plain = model.normalizeRouteInitial(
|
||||
{ x: 50, y: 10, curve: true, radius_m: 30 },
|
||||
{ x: 100, y: 0, curve: false },
|
||||
],
|
||||
// 계획서 20 「API」 줄 모양.
|
||||
metrics: {
|
||||
length_m: 1234.56,
|
||||
max_grade_pct: 12.34,
|
||||
mean_grade_pct: 6.1,
|
||||
avg_grade_pct: 6.1,
|
||||
cut_m3: 1500.4,
|
||||
fill_m3: 900,
|
||||
over_limit_count: 2,
|
||||
offset_mean_m: 3.25,
|
||||
over_limit: { grade: 1, radius: 0, stream: 1, total: 2 },
|
||||
offset_avg_m: 3.25,
|
||||
offset_max_m: 9.8,
|
||||
},
|
||||
criteria: {
|
||||
max_grade_pct: 14,
|
||||
min_radius_m: 12,
|
||||
stream_offset_m: 5,
|
||||
road_width_m: 4,
|
||||
corridor_m: 100,
|
||||
pending: ["max_grade_pct", "stream_offset_m"],
|
||||
},
|
||||
criteria: { max_grade_pct: 14, min_radius_m: 12, stream_offset_m: 5 },
|
||||
},
|
||||
"earthwork",
|
||||
null,
|
||||
@@ -105,7 +114,7 @@ const planShape = model.normalizeRouteInitial(
|
||||
],
|
||||
},
|
||||
"weighted",
|
||||
{ expected: 60, earthwork: 20, slope: 20 },
|
||||
{ expected: 60, earthwork: 20, grade: 20 },
|
||||
);
|
||||
let tooShort = "";
|
||||
try {
|
||||
@@ -117,12 +126,23 @@ try {
|
||||
// ③ 글 — 현재 초기값 · 비교값 · 기준값.
|
||||
const labels = {
|
||||
follow: model.choiceLabel("follow", null),
|
||||
weighted: model.choiceLabel("weighted", { expected: 60, earthwork: 20, slope: 20 }),
|
||||
weighted: model.choiceLabel("weighted", { expected: 60, earthwork: 20, grade: 20 }),
|
||||
metrics: model.metricsLine(plain.metrics),
|
||||
metricsNone: model.metricsLine(null),
|
||||
criteria: model.criteriaLine(plain.criteria, 0),
|
||||
criteriaConfirmed: model.criteriaLine({ ...plain.criteria, confirmed: true }, 0),
|
||||
criteriaFallback: model.criteriaLine(null, 15),
|
||||
pendingEmpty: model.normalizeRouteInitial(
|
||||
{
|
||||
nodes: [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 9, y: 9 },
|
||||
],
|
||||
criteria: { pending: [] },
|
||||
},
|
||||
"gentle",
|
||||
null,
|
||||
).criteria.confirmed,
|
||||
};
|
||||
|
||||
// ④ 캐시 왕복 — 결과 통 프로젝트 칸. 꼴이 틀린 값은 안 읽는다.
|
||||
|
||||
@@ -32,19 +32,19 @@ def results():
|
||||
|
||||
def test_비중은_늘_합_100_정수(results):
|
||||
for weights in results["moves"]:
|
||||
assert list(weights) == ["expected", "earthwork", "slope"]
|
||||
assert list(weights) == ["expected", "earthwork", "grade"]
|
||||
assert sum(weights.values()) == 100
|
||||
assert all(isinstance(v, int) and 0 <= v <= 100 for v in weights.values())
|
||||
|
||||
|
||||
def test_비중은_나머지를_지금_비율대로_나눔(results):
|
||||
moves = results["moves"]
|
||||
assert moves[0] == {"expected": 70, "earthwork": 15, "slope": 15}
|
||||
assert moves[1] == {"expected": 40, "earthwork": 40, "slope": 20}
|
||||
assert moves[0] == {"expected": 70, "earthwork": 15, "grade": 15}
|
||||
assert moves[1] == {"expected": 40, "earthwork": 40, "grade": 20}
|
||||
# 나머지가 모두 0 이면 반씩.
|
||||
assert moves[2] == {"expected": 60, "earthwork": 20, "slope": 20}
|
||||
assert moves[3] == {"expected": 0, "earthwork": 0, "slope": 100}
|
||||
assert moves[5]["slope"] == 0
|
||||
assert moves[2] == {"expected": 60, "earthwork": 20, "grade": 20}
|
||||
assert moves[3] == {"expected": 0, "earthwork": 0, "grade": 100}
|
||||
assert moves[5]["grade"] == 0
|
||||
|
||||
|
||||
def test_노드_목록_꼴을_편집값으로(results):
|
||||
@@ -63,7 +63,7 @@ def test_노선계획_꼴도_같은_규칙으로(results):
|
||||
assert snap["planned"] == [[0, 0], [40, 30], [90, 30]]
|
||||
assert snap["curveOn"] == [False, True, False]
|
||||
assert snap["curveRadius"] == [None, 25, None]
|
||||
assert shape["weights"] == {"expected": 60, "earthwork": 20, "slope": 20}
|
||||
assert shape["weights"] == {"expected": 60, "earthwork": 20, "grade": 20}
|
||||
assert shape["metrics"] is None and shape["criteria"] is None
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ def test_비교값과_기준값_글(results):
|
||||
"공통 제약 종단기울기 ≤ 14.0% · 최소 R 12m · 계류 이격 ≥ 5.0m (후보 · 사용자 확정 대기)"
|
||||
)
|
||||
assert labels["criteriaConfirmed"].endswith("5.0m")
|
||||
assert labels["pendingEmpty"] is True
|
||||
assert labels["criteriaFallback"] == (
|
||||
"공통 제약 종단기울기 ≤ — · 최소 R 15m · 계류 이격 ≥ — (후보 · 사용자 확정 대기)"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user