- D03_Api 겹 받기 → map_layer_api.ts(D03_Api 가 다시 내놓음) - UI_SlopeBands · logic SlopeBands · UI_SatLight → map_slope_bands · logic/map_slope_bands · map_sat_light - 범례 줄 legendRows → map_legend.ts(받은 자료 꼴 LegendData · D03 LayerLegend 가 다시 내놓음) - glImage · glTagged · shadeImage · loadImage · WATER_KEYS · FOREST_ROAD_KINDS · hectare → map_layer_data.ts - 시험 경로 고침 — test_603(TS 자리) · test_606_1(밝기 파일) · test_584_3(범례 글 = 공용 파일도 읽음) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
/* =============================================================================
|
|
* D03_PlanAnalysis_UI_LayerDefs.ts
|
|
* D03 바탕 겹 옛 캔버스 도움(PLAN 569-2 · 581-1 · 581-2 · 584-1 · 584-3 · 586-2 · 624-2 · 624-3) — 면 겹 채우기 · 선 긋기 · 그림 겹 놓기.
|
|
* 임도 짐작 구분 · 물 면 · 그림 읽기 · GL 자료 = 공용 `A00_Common/map/map_layer_data`(624-3 · 다시 내놓음).
|
|
* 겹 목록 · 처음 값 · 켬끔 취향 · 선 겹 꼴 · 보호구역 색 = 공용 `A00_Common/map/map_layer_list`(624-2).
|
|
* 부르는 곳 = `D03_PlanAnalysis_UI_Layers.ts`(받기 · 그리기 차례 · 범례).
|
|
* ========================================================================== */
|
|
|
|
import type { MapLayerKey } from "../A00_Common/map/map_layer_list";
|
|
import {
|
|
drawPreparedLayer,
|
|
normalizedToScreen,
|
|
type PreparedLayer,
|
|
type ViewState,
|
|
} from "../B04_PreProcess/B04_PreProcess_UI_MapRender";
|
|
import type { PlanRaster } from "./D03_PlanAnalysis_Api";
|
|
import type { ScreenMap } from "./D03_PlanAnalysis_UI_Map";
|
|
|
|
/** 겹 목록 · 페이지 표 = 공용 `map_layer_list`(624-2) — 옛 이름으로 다시 내놓음(캔버스 · 조각 · 임도망 목록이 읽음). */
|
|
export type PlanLayerKey = MapLayerKey;
|
|
export {
|
|
FOREST_ROAD_KINDS,
|
|
WATER_KEYS,
|
|
glImage,
|
|
glTagged,
|
|
hectare,
|
|
loadImage,
|
|
shadeImage,
|
|
} from "../A00_Common/map/map_layer_data";
|
|
export {
|
|
LINE_KEYS,
|
|
LINE_LAYERS,
|
|
ZONE_COLORS,
|
|
type RoadPick,
|
|
} from "../A00_Common/map/map_layer_list";
|
|
|
|
/** 면 겹 채움 — 지물마다 한 길(evenodd = 구멍) · 화면 밖 지물 거름(돌린 지도 귀퉁이까지 여유). */
|
|
export function fillLayer(
|
|
context: CanvasRenderingContext2D,
|
|
layer: PreparedLayer,
|
|
view: ViewState,
|
|
fill: string,
|
|
alpha: number,
|
|
edge?: { color: string; width: number; dash?: number[] },
|
|
): void {
|
|
const [ox, oy] = normalizedToScreen(view, 0, 0);
|
|
const [ex, ey] = normalizedToScreen(view, 1, 1);
|
|
const ax = ex - ox;
|
|
const ay = ey - oy;
|
|
const pad = Math.max(view.width, view.height) / 2;
|
|
context.fillStyle = fill;
|
|
if (edge) {
|
|
context.strokeStyle = edge.color;
|
|
context.lineWidth = edge.width;
|
|
context.setLineDash(edge.dash ?? []);
|
|
}
|
|
for (const feature of layer.features) {
|
|
if (
|
|
feature.maxX * ax + ox < -pad ||
|
|
feature.minX * ax + ox > view.width + pad ||
|
|
feature.maxY * ay + oy < -pad ||
|
|
feature.minY * ay + oy > view.height + pad
|
|
)
|
|
continue;
|
|
context.beginPath();
|
|
for (const { coords } of feature.parts) {
|
|
context.moveTo(coords[0] * ax + ox, coords[1] * ay + oy);
|
|
for (let i = 2; i < coords.length; i += 2)
|
|
context.lineTo(coords[i] * ax + ox, coords[i + 1] * ay + oy);
|
|
context.closePath();
|
|
}
|
|
context.globalAlpha = alpha;
|
|
context.fill("evenodd");
|
|
if (edge) {
|
|
context.globalAlpha = 0.9;
|
|
context.stroke();
|
|
}
|
|
}
|
|
context.setLineDash([]);
|
|
}
|
|
|
|
/** 선 겹 긋기(점 솎음 `dot` · `everyM` = 등고 간격 거름). */
|
|
export function stroke(
|
|
context: CanvasRenderingContext2D,
|
|
map: ScreenMap,
|
|
layer: PreparedLayer,
|
|
color: string,
|
|
width: number,
|
|
everyM?: number,
|
|
): void {
|
|
context.strokeStyle = color;
|
|
context.lineWidth = width;
|
|
drawPreparedLayer(context, layer, map.view, "dot", everyM);
|
|
}
|
|
|
|
/** 그림 겹(작업 좌표계 m 상자 · 위 = 북). */
|
|
export function drawRaster(
|
|
context: CanvasRenderingContext2D,
|
|
map: ScreenMap,
|
|
raster: { raster: PlanRaster; image: HTMLImageElement },
|
|
): void {
|
|
// 세 귀퉁이로 놓음 — TM 격자는 경위도 바탕에 대해 수렴각만큼 돌아 있음(586-0)
|
|
const [x0, y0, x1, y1] = raster.raster.box_m;
|
|
const [left, top] = map.toScreen([x0, y1]);
|
|
const [right, rightY] = map.toScreen([x1, y1]);
|
|
const [bottomX, bottom] = map.toScreen([x0, y0]);
|
|
const { naturalWidth: w, naturalHeight: h } = raster.image;
|
|
context.transform(
|
|
(right - left) / w,
|
|
(rightY - top) / w,
|
|
(bottomX - left) / h,
|
|
(bottom - top) / h,
|
|
left,
|
|
top,
|
|
);
|
|
context.drawImage(raster.image, 0, 0);
|
|
}
|