merge(D03 겹): dev 합침 — 581-1 겹 일곱 + 582 두 장 캔버스 + 579 · 580 그리기 나눔 양쪽 살림

- UI_Layers.ts: 582 바탕 캔버스(`base`) + 581-1 새 겹 일곱 · 겹 열둘 모두 `base: true` · 글 폭 기억 · drawRaster 둘 다
- UI_Style.css: 582 `.d03-plan__base` 블록 + 581-1 `--d03-layers-w` 글
- test_553_4: 580 DrawPaint 단언 + 581-1 createMapTools · LayerDefs 단언
- test_582: 바탕 겹 수 5 → 겹 모두(12) — 581-1 합침으로 낡은 수 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 14:55:18 +09:00
co-authored by Claude Opus 5.5
27 changed files with 2091 additions and 660 deletions
+24 -5
View File
@@ -9,7 +9,8 @@
* 처음 켬 = 위성 · 등고선 · 세류 · 고른 값 = 화면 취향(`aislo:pref:d03.layers`) 기억.
* 받기 = 켤 때만(한 번 받으면 다시 안 받음) · 지형을 안 받았으면 단추를 막음 · 받기 실패 = 그 겹만 꺼짐 + 알림.
* 그리기 차례(아래 → 위) = 위성(`scene.image`) → 음영기복 → 급경사 → 보호구역 → 띠 → 지적 → 물 면 →
* 건물 → 등고선 → 도로 → 임도 짐작 → 세류 → 지명 → 그은 선(모두 `layers` = 바탕 겹 · 582 두 장이면 아래 장).
* 건물 → 등고선 → 도로 → 임도 짐작 → 세류 → 지명 → 그은 선.
* 겹 모두 = 바탕 캔버스(`base` · 582) · 등고선 = 줌 단계 색인 · 글 폭 기억.
* 범례 = 켠 겹의 받은 범위 안 수 · 넓이(왼쪽 아래).
* ========================================================================== */
@@ -34,7 +35,10 @@ import {
type GeoJsonCollection,
type PreparedLayer,
} from "../B04_PreProcess/B04_PreProcess_UI_MapRender";
import { prepareLayer } from "../B04_PreProcess/logic/B04_PreProcess_UI_MapRender_Prepare";
import {
indexLayerLod,
prepareLayer,
} from "../B04_PreProcess/logic/B04_PreProcess_UI_MapRender_Prepare";
import {
fetchPlanBands,
fetchPlanCadastral,
@@ -240,7 +244,7 @@ export function createPlanLayers(opts: {
void ensure(key);
showSatellite();
sync();
map.redraw();
map.redrawBase();
}
function showSatellite(): void {
@@ -259,7 +263,7 @@ export function createPlanLayers(opts: {
if (meta !== at) return;
showSatellite();
sync();
map.redraw();
map.redrawBase();
})
.catch((error: unknown) => {
const text = error instanceof Error ? error.message : String(error);
@@ -306,7 +310,7 @@ export function createPlanLayers(opts: {
"route",
bbox.join(","),
);
data.contour = prepare(collection, ["등고수치"]);
data.contour = indexLayerLod(prepare(collection, ["등고수치"]));
} else if (key === "stream") {
const collection = await fetchCachedSheetLayer<GeoJsonCollection>(
projectId,
@@ -391,8 +395,11 @@ export function createPlanLayers(opts: {
context.drawImage(raster.image, left, top, right - left, bottom - top);
};
/** 등고 글 폭 기억(글꼴 하나 · 582). */
const labelWidths = new Map<string, number>();
const layers: PlanMapLayer[] = [
{
base: true,
draw: (context, map) => {
if (!on.hillshade || !data.hillshade) return;
// 위성 위 = 곱하기(밝은 곳은 그대로 · 그늘만 짙게) · 위성 없으면 그대로
@@ -404,6 +411,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.slope || !data.slope) return;
context.globalAlpha = 0.55;
@@ -411,6 +419,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.zones || !data.zones) return;
for (const [kind, layer] of data.zones.kinds) {
@@ -420,6 +429,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.bands || !data.bands) return;
const road = themeColor("--draw-map-band-road", "#facc15");
@@ -437,6 +447,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.cadastral || !data.cadastral) return;
context.globalAlpha = 0.8;
@@ -444,6 +455,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.water || !data.water) return;
const color = themeColor("--draw-map-water", "#0ea5e9");
@@ -451,6 +463,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.building || !data.building) return;
const color = themeColor("--draw-map-building", "#fb7185");
@@ -461,6 +474,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
const contour = on.contour && data.contour;
if (!contour) return;
@@ -480,10 +494,12 @@ export function createPlanLayers(opts: {
25,
map.uprightRad,
"rgba(0, 0, 0, 0.6)",
labelWidths,
);
},
},
{
base: true,
draw: (context, map) => {
if (!on.road || !data.road) return;
stroke(context, map, data.road.all, "rgba(0, 0, 0, 0.55)", 3.2);
@@ -491,6 +507,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.forestRoad || !data.road) return;
context.setLineDash([7, 4]);
@@ -500,6 +517,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.stream || !data.stream) return;
const color = themeColor("--draw-map-stream", "#38bdf8");
@@ -508,6 +526,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.place || !data.place || !meta) return;
const normalizer = createNormalizer(meta);