fix(D03 겹): 급경사 범례 = 서버 단계 색 · 넓이 비율 그대로 · 지적 선 분홍 · 지형 없을 때 빈 범례 숨김 (PLAN 569-2)

- 범례가 응답 bands(색 · 비율)를 그대로 씀 — 화면 급경사 색 값 셋 뺌(test_551_2 그림 값 개수 24 → 21)
- 지적 경계 노랑 → 분홍(등고선 · 급경사 노랑과 겹쳐 안 보임)
- 겹 판 만들 때 상태 한 번 맞춤 — 지형 못 읽으면 범례 빈 칸이 남던 것

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 07:10:42 +09:00
co-authored by Claude Opus 5.5
parent b4e1b89943
commit 200149553a
5 changed files with 17 additions and 17 deletions
+2 -1
View File
@@ -135,10 +135,11 @@ export async function fetchPlanSurface(projectId: string): Promise<PlanSurface |
return { modelId: model.id, grid: parseDtmGrid(await fetchCachedBytes(projectId, url)) };
}
/** 지도 겹 그림(569-1) — 작업 좌표계 m 상자 · data URL. */
/** 지도 겹 그림(569-1) — 작업 좌표계 m 상자(칸 가장자리) · data URL(위 = 북) · 단계 색 · 넓이 비율. */
export interface PlanRaster {
box_m: [number, number, number, number];
image: string;
bands: Array<{ min_deg: number; max_deg: number; color: string; ratio: number }>;
}
export const fetchPlanCadastral = (projectId: string): Promise<GeoJsonCollection> =>
+13 -10
View File
@@ -60,11 +60,6 @@ const LAYERS: readonly LayerDef[] = [
const PREF_KEY = "aislo:pref:d03.layers";
/** 등고선을 받아 올 그은 선 둘레(m). */
const CONTOUR_PAD_M = 600;
const SLOPE_STEPS = [
{ label: "15°", token: "--draw-slope-15" },
{ label: "35°", token: "--draw-slope-35" },
{ label: "40°", token: "--draw-slope-40" },
];
interface Prepared {
contour: PreparedLayer;
@@ -142,10 +137,7 @@ export function createPlanLayers(opts: {
bar.classList.add("d03-plan__layers");
const legend = document.createElement("div");
legend.className = "d03-plan__legend";
legend.title = "급경사 색 — 그 값 이상";
legend.append(
createLegend(SLOPE_STEPS.map((step) => ({ label: step.label, color: `var(${step.token})` }))),
);
legend.title = "급경사 색 — 단계 · 받은 지형 안 넓이 비율";
function sync(): void {
for (const def of LAYERS) {
@@ -159,6 +151,8 @@ export function createPlanLayers(opts: {
legend.hidden = !meta || !on.slope || !data.slope;
}
sync();
function toggle(key: PlanLayerKey): void {
on[key] = !on[key];
writeByKey(PREF_KEY, JSON.stringify(on));
@@ -239,6 +233,15 @@ export function createPlanLayers(opts: {
} else {
const raster = await fetchPlanRaster(projectId, "slope");
data.slope = { raster, image: await loadImage(raster.image) };
// 범례 = 서버 단계 색 그대로(색 한 곳)
legend.replaceChildren(
createLegend(
raster.bands.map((band) => ({
label: `${band.min_deg}${band.max_deg < 90 ? `~${band.max_deg}°` : "°↑"} ${(band.ratio * 100).toFixed(1)} %`,
color: band.color,
})),
),
);
}
}
@@ -271,7 +274,7 @@ export function createPlanLayers(opts: {
draw: (context, map) => {
if (!on.cadastral || !data.cadastral) return;
context.globalAlpha = 0.8;
stroke(context, map, data.cadastral, themeColor("--draw-map-parcel", "#facc15"), 0.8);
stroke(context, map, data.cadastral, themeColor("--draw-map-parcel", "#f0abfc"), 0.8);
},
},
{
@@ -29,7 +29,6 @@
position: absolute;
top: var(--spacing-8);
right: var(--spacing-8);
align-items: flex-end;
}
/* 569-2 바탕 겹 단추 — 왼쪽 위 · 급경사 범례 — 왼쪽 아래 */
+1 -1
View File
@@ -124,7 +124,7 @@ def test_draw_values_are_literal_hex():
assert draws, mode
for name, value in draws.items():
assert HEX.fullmatch(value), (mode, name, value)
assert len([k for k in blocks["light"] if k.startswith("--draw-")]) == 24
assert len([k for k in blocks["light"] if k.startswith("--draw-")]) == 21
def test_drawing_css_uses_no_screen_tokens():
+1 -4
View File
@@ -554,10 +554,7 @@ html.is-bm-route .m01lab-src__body * {
--draw-map-contour: #ffd68c; /* 위성 위 겹(노선분석) — 도엽 등고선 */
--draw-map-stream: #38bdf8; /* 세류 · 하천 */
--draw-map-road: #f8fafc; /* 기존 도로 */
--draw-map-parcel: #facc15; /* 지적 경계 */
--draw-slope-15: #fde047; /* 급경사 색 15° 이상 */
--draw-slope-35: #f97316; /* 35° 이상 */
--draw-slope-40: #dc2626; /* 40° 이상 */
--draw-map-parcel: #f0abfc; /* 지적 경계 */
}
:root[data-theme="dark"] {