- 겹 표(map_layer_list) = 그룹1 22 줄 표 차례 · title = 호버제목 · group(수계망도 · 도로 · 토지·건물 · 제한·재해) · pages · 숨김 표 걷음 · 도로300m 한 줄(「도로」 묶음 · 기능 남김) - 겹 줄(map_layer_bar) = 단독 넷 | 묶음 넷(여럿 고르기 메뉴 · 켠 수 배지 · 안 닫힘) | 그래픽 카드 · sync 가 단추 · 메뉴 줄 막힘 · 글을 맞춤(why = 페이지 까닭) - 도구 표(map_toolbar) = 그룹2 17 줄 title · mapToolGroups 가 글을 표로 맞춤 · 기본 단추 생성 · 지형 칩 막힘 「수치지형도/라이다 — 까닭」 - 띠 = 한 자료 · 겹 둘(GL fillEdge 거름 · 옛 캔버스 · 범례 줄 따로) · B05 띠 받기(D03 과 같은 서버 길 · bandCollection 공용) - D03 = 겹 줄 · 도구줄 한 행(createMapToolRow) · 222px 기댐 · 줄바꿈 CSS 걷음 · 측점 · 기울기 호버 덮어쓰기 걷음 · LAS 올리기 호버 걷음 - B05 = 세로 두 줄 → 한 행 · 호버 덮어쓰기 걷음(도구줄 · 1m 등고선 · 3D · 추천) · 겹 막힘 querySelector 덮어쓰기 → 공용 sync · 임도(업로드) 보임 + 「받은 임도 자료 없음」 막힘 · 스냅 간격 날 select → 고르기 메뉴(하나) - 켬끔 기억 열쇠 · 측점 · 기울기 처음 값 · 그래픽 카드 취향 열쇠 둘 그대로 - 낡은 시험 고침(568_1 · 622_2 · 624_2 · 624_3 · 553_4 · 625_draw · b05_routeedit_initial · 626_3 · 390_4 · 346_2 · 353_1 · 581_2 · 584_1 · 584_3) — 표 꼴 row() · 호버 글 = 표 · 한 행 · 고르기 메뉴로 바뀐 글을 잡음 · 새 지킴 634_2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
3.4 KiB
TypeScript
77 lines
3.4 KiB
TypeScript
/* =============================================================================
|
||
* map_layer_data.ts
|
||
* 공용 지도 겹 자료 도움(PLAN 569-2 · 581 · 586-2 · 624-3) — D03 예정노선 · B05 평면이 같이 씀(D03 `UI_LayerDefs` 에서 옮김).
|
||
* 도로 소로 · 미분류 구분 · 물 면 도엽 이름 · 넓이 글 · 그림 읽기 · GL 자료(지물 색 붙이기 · 그림 귀퉁이 · 음영 그늘 그림).
|
||
* ========================================================================== */
|
||
|
||
import type { GlImage } from "@ui/ui_template_gl_map";
|
||
import { themeColor } from "@ui/ui_template_palette";
|
||
import type { GeoJsonCollection, PlanBand, PlanRaster } from "./map_layer_api";
|
||
|
||
/** 도로 중 소로 · 미분류 구분(옛 임도 짐작 · 겹 걷음 · 페이지 자료 셈만 씀). */
|
||
export const FOREST_ROAD_KINDS = new Set(["소로", "미분류"]);
|
||
/** 물 면 = 도엽 수계(E) 면 셋. */
|
||
export const WATER_KEYS = ["실폭하천", "수계면E003", "수계면E005"];
|
||
|
||
export const hectare = (m2: number): string => `${(m2 / 10000).toFixed(1)} ha`;
|
||
|
||
export const loadImage = (src: string): Promise<HTMLImageElement> =>
|
||
new Promise((done, fail) => {
|
||
const image = new Image();
|
||
image.onload = () => done(image);
|
||
image.onerror = () => fail(new Error("그림을 읽지 못했습니다"));
|
||
image.src = src;
|
||
});
|
||
|
||
/** GL 자료 — 지물마다 그릴 색(`_color`) · 덧 속성을 붙인 사본. */
|
||
export function glTagged(
|
||
collection: GeoJsonCollection,
|
||
color: (props: Record<string, unknown>) => string,
|
||
extra: Record<string, unknown> = {},
|
||
): GeoJsonCollection {
|
||
return {
|
||
...collection,
|
||
features: (collection.features ?? []).map((feature) => ({
|
||
...feature,
|
||
properties: { ...feature.properties, ...extra, _color: color(feature.properties ?? {}) },
|
||
})),
|
||
};
|
||
}
|
||
|
||
/** 띠 GL 자료(581-1 · 634-2) — 도로 300 m 먼저 · 계류 100 m 위 · `_band` = 겹 가름(계류 = `bands` · 도로 = `roadBands`). */
|
||
export function bandCollection(info: { stream: PlanBand; road: PlanBand }): GeoJsonCollection {
|
||
const band = (name: "stream" | "road", fallback: string): GeoJsonCollection =>
|
||
glTagged(info[name].collection, () => themeColor(`--draw-map-band-${name}`, fallback), {
|
||
_band: name,
|
||
});
|
||
return {
|
||
features: [
|
||
...(band("road", "#facc15").features ?? []),
|
||
...(band("stream", "#22d3ee").features ?? []),
|
||
],
|
||
};
|
||
}
|
||
|
||
/** GL 그림 자리 — 서버 경위도 귀퉁이(왼쪽 아래부터 돎) → 왼쪽 위부터 · 없으면 null. */
|
||
export function glImage(raster: PlanRaster, url = raster.image): GlImage | null {
|
||
const box = raster.box;
|
||
return box?.length === 4 ? { url, corners: [box[3], box[2], box[1], box[0]] } : null;
|
||
}
|
||
|
||
/** 음영 그늘 그림 — 위성 위 「곱하기 0.75」와 같은 검은 반투명(밝기 g → 투명도 0.75 · (1 − g)). */
|
||
export function shadeImage(image: HTMLImageElement): string {
|
||
const canvas = document.createElement("canvas");
|
||
canvas.width = image.naturalWidth;
|
||
canvas.height = image.naturalHeight;
|
||
const context = canvas.getContext("2d")!;
|
||
context.drawImage(image, 0, 0);
|
||
const pixels = context.getImageData(0, 0, canvas.width, canvas.height);
|
||
const px = pixels.data;
|
||
for (let i = 0; i < px.length; i += 4) {
|
||
px[i + 3] = Math.round(0.75 * (255 - px[i]) * (px[i + 3] / 255));
|
||
px[i] = px[i + 1] = px[i + 2] = 0;
|
||
}
|
||
context.putImageData(pixels, 0, 0);
|
||
return canvas.toDataURL("image/png");
|
||
}
|