feat(D 예정노선): Page 지점 넘김 꼴 — 지점 이름 · commit(points, names, network) · 보기 가운데 center (PLAN 596 이음 · 597 받음)
- Snap 에 pointNames · 캐시 판 4 - Points 인자 꼴만 맞춤(이름 함께 넘김) · 칸 고침은 597-2 몫 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,12 +79,13 @@ const SITE_RADIUS_M = 1000;
|
||||
/** 되돌리기 쌓는 수. */
|
||||
const UNDO_MAX = 100;
|
||||
/** 캐시 꼴 판 — 옛 꼴(지점 없음 · 갈래 고름)은 안 읽음. */
|
||||
const DRAFT_VERSION = 3;
|
||||
const DRAFT_VERSION = 4;
|
||||
|
||||
/** 한 걸음 = 지점 + 노선(되돌리기 · 캐시 · 고침 판정). */
|
||||
/** 한 걸음 = 지점(+ 이름 · 차례 같음 · 빈 값 = 「지점 N」) + 노선(되돌리기 · 캐시 · 고침 판정). */
|
||||
interface Snap {
|
||||
network: PlanNetwork;
|
||||
points: Vertex[];
|
||||
pointNames: string[];
|
||||
}
|
||||
|
||||
interface Draft extends Snap {
|
||||
@@ -99,15 +100,17 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
const projectId = currentProjectId();
|
||||
let editable = false;
|
||||
let points: Vertex[] = []; // 지점(긋기에 붙는 점 · 591-2)
|
||||
let pointNames: string[] = []; // 지점 이름(596 · 597-2)
|
||||
let epsg = 0;
|
||||
let yearStart = new Date().getFullYear(); // 새 선 처음 해
|
||||
let network: PlanNetwork = emptyNetwork();
|
||||
let savedJson = JSON.stringify({ network, points }); // 못 읽은 채 떠남 = 고침 없음
|
||||
let savedJson = JSON.stringify({ network, points, pointNames }); // 못 읽은 채 떠남 = 고침 없음
|
||||
let undoStack: Snap[] = [];
|
||||
let redoStack: Snap[] = [];
|
||||
let surface: PlanSurface | null = null;
|
||||
let have: [number, number, number, number] | null = null;
|
||||
let viewCore: Vertex[] = []; // 지도 보기 가운데 상자 두 귀(넓으면 빈 것)
|
||||
let viewMid: Vertex | null = null; // 지도 보기 가운데(지점 [추가] 자리)
|
||||
let viewTimer = 0;
|
||||
let lastTried = ""; // 같은 받기를 거듭하지 않음
|
||||
let ready = false; // 들어올 때 받기 판단이 끝남(그 앞 보기 바뀜은 안 받음)
|
||||
@@ -150,9 +153,12 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
const marks = createPlanPoints({
|
||||
points: () => points,
|
||||
network: () => network,
|
||||
names: () => pointNames,
|
||||
epsg: () => epsg,
|
||||
draw,
|
||||
commit: (nextPoints, next) => step({ network: next, points: nextPoints }),
|
||||
commit: (nextPoints, nextNames, next) =>
|
||||
step({ network: next, points: nextPoints, pointNames: nextNames }),
|
||||
center: () => viewMid,
|
||||
show: (nextPoints, next) => {
|
||||
[points, network] = [nextPoints, next];
|
||||
map.redraw();
|
||||
@@ -172,6 +178,7 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
].map(([x, y]) => screen.toMetric(...screen.unrotate(x, y)));
|
||||
const xs = corners.map((c) => c[0]);
|
||||
const ys = corners.map((c) => c[1]);
|
||||
viewMid = w ? screen.toMetric(...screen.unrotate(w / 2, h / 2)) : null;
|
||||
const box: Vertex[] = [
|
||||
[Math.min(...xs), Math.min(...ys)],
|
||||
[Math.max(...xs), Math.max(...ys)],
|
||||
@@ -246,7 +253,7 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
root.querySelector(".ui-workflow-layout")?.classList.add("d03-plan-layout");
|
||||
|
||||
const allVertices = (): Vertex[] => network.lines.flatMap((line) => line.vertices);
|
||||
const snap = (): Snap => ({ network, points });
|
||||
const snap = (): Snap => ({ network, points, pointNames });
|
||||
const dirty = (): boolean => JSON.stringify(snap()) !== savedJson;
|
||||
const keepDraft = (): void =>
|
||||
dirty()
|
||||
@@ -257,21 +264,25 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
function step(next: Snap): void {
|
||||
undoStack = [...undoStack.slice(1 - UNDO_MAX), snap()];
|
||||
redoStack = [];
|
||||
[network, points] = [normalizePieces(next.network, yearStart), next.points];
|
||||
[network, points, pointNames] = [
|
||||
normalizePieces(next.network, yearStart),
|
||||
next.points,
|
||||
next.pointNames,
|
||||
];
|
||||
keepDraft();
|
||||
refresh();
|
||||
void ensureCovered();
|
||||
}
|
||||
|
||||
function commit(next: PlanNetwork): void {
|
||||
step({ network: next, points });
|
||||
step({ network: next, points, pointNames });
|
||||
}
|
||||
|
||||
function undo(): void {
|
||||
const last = undoStack.pop();
|
||||
if (!last) return;
|
||||
redoStack.push(snap());
|
||||
({ network, points } = last);
|
||||
({ network, points, pointNames } = last);
|
||||
keepDraft();
|
||||
refresh();
|
||||
}
|
||||
@@ -280,7 +291,7 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
const next = redoStack.pop();
|
||||
if (!next) return;
|
||||
undoStack.push(snap());
|
||||
({ network, points } = next);
|
||||
({ network, points, pointNames } = next);
|
||||
keepDraft();
|
||||
refresh();
|
||||
}
|
||||
@@ -422,6 +433,7 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
? fromServer(server.lines, server.marks, server.pieces, yearStart)
|
||||
: emptyNetwork();
|
||||
points = view.base.points.map((p): Vertex => [p.x, p.y]);
|
||||
pointNames = view.base.points.map(() => ""); // 594-1 이름 칸이 들어오면 `p.name ?? ""`
|
||||
if (view.base.epsg) epsg = view.base.epsg;
|
||||
savedJson = JSON.stringify(snap());
|
||||
}
|
||||
@@ -553,7 +565,7 @@ export async function renderD03PlanAnalysis(root: HTMLElement): Promise<void> {
|
||||
takeServer(view);
|
||||
const draft = readState<Draft>("d03-plan", projectId);
|
||||
if (draft?.version === DRAFT_VERSION && draft.network && Array.isArray(draft.points))
|
||||
({ network, points } = draft);
|
||||
({ network, points, pointNames } = draft);
|
||||
const tm = tmParams(epsg);
|
||||
const siteXy = site && tm ? lonLatToTm(tm, site.lon, site.lat) : null;
|
||||
const around: Vertex[] = siteXy
|
||||
|
||||
@@ -27,11 +27,15 @@ const PIN_HEAD_PX = 18;
|
||||
|
||||
export interface PlanPointsParams {
|
||||
points: () => Vertex[];
|
||||
/** 지점 이름(차례 = `points` · 빈 값 = 「지점 N」). */
|
||||
names: () => string[];
|
||||
network: () => PlanNetwork;
|
||||
epsg: () => number;
|
||||
draw: PlanDraw;
|
||||
/** 한 걸음 — 지점 · 노선 함께. */
|
||||
commit: (points: Vertex[], network: PlanNetwork) => void;
|
||||
/** 한 걸음 — 지점 · 이름 · 노선 함께. */
|
||||
commit: (points: Vertex[], names: string[], network: PlanNetwork) => void;
|
||||
/** 지도 보기 가운데(작업 좌표 · 못 잼 = null) — [추가] 자리. */
|
||||
center: () => Vertex | null;
|
||||
/** 끌기 중 — 화면만. */
|
||||
show: (points: Vertex[], network: PlanNetwork) => void;
|
||||
/** 쉴 때(긋기 · 재기 아님)만 핀을 끎. */
|
||||
@@ -86,6 +90,7 @@ export function createPlanPoints(params: PlanPointsParams): PlanPoints {
|
||||
function remove(i: number): void {
|
||||
params.commit(
|
||||
params.points().filter((_, k) => k !== i),
|
||||
params.names().filter((_, k) => k !== i),
|
||||
params.network(),
|
||||
);
|
||||
}
|
||||
@@ -100,7 +105,7 @@ export function createPlanPoints(params: PlanPointsParams): PlanPoints {
|
||||
.filter((item) => item.gap <= SNAP_PX)
|
||||
.sort((a, b) => a.gap - b.gap)[0];
|
||||
const at = node?.point ?? map.toMetric(px, py);
|
||||
params.commit([...params.points(), [at[0], at[1]]], params.network());
|
||||
params.commit([...params.points(), [at[0], at[1]]], [...params.names(), ""], params.network());
|
||||
}
|
||||
|
||||
function openMenu(px: number, py: number, map: ScreenMap): boolean {
|
||||
@@ -154,7 +159,7 @@ export function createPlanPoints(params: PlanPointsParams): PlanPoints {
|
||||
drag = null;
|
||||
if (!done?.last) return;
|
||||
params.show(done.points, done.network);
|
||||
params.commit(...done.last);
|
||||
params.commit(done.last[0], params.names(), done.last[1]);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user