Merge remote-tracking branch 'origin/sub_laptop_7' into main_laptop_1
This commit is contained in:
@@ -130,7 +130,7 @@ export function paintNetwork(
|
||||
network.lines.forEach((line, index) => {
|
||||
if (line.vertices.length < 2) return;
|
||||
const color = index === active ? colors.active : routeColor(index);
|
||||
const width = line.branch ? 2.5 : 3;
|
||||
const width = 3;
|
||||
const path = (vertices: ReadonlyArray<Vertex>): void => {
|
||||
context.beginPath();
|
||||
vertices.forEach((v, i) => {
|
||||
|
||||
@@ -73,6 +73,7 @@ import {
|
||||
import { layerCounts, legendRows, type Prepared } from "./D03_PlanAnalysis_UI_LayerLegend";
|
||||
import { createCanvasLayers } from "./D03_PlanAnalysis_UI_LayerPaint";
|
||||
import { createGlBase, GL_FONT, type GlImage } from "./D03_PlanAnalysis_UI_MapGl";
|
||||
import { createSatLightRow, readSatLight } from "./D03_PlanAnalysis_UI_SatLight";
|
||||
import {
|
||||
openSlopeBands,
|
||||
paintSlope,
|
||||
@@ -208,11 +209,19 @@ export function createPlanLayers(opts: {
|
||||
for (const def of LAYERS) gl.setVisible(def.key, on[def.key]);
|
||||
gl.setData("hillshade", hillshade && (on.satellite ? hillshade.shade : hillshade.plain));
|
||||
const rows = meta ? legendRows(on, data) : [];
|
||||
legend.replaceChildren(...rows.map((row) => createLegend(row)));
|
||||
const light = meta && glOn && on.satellite; // 옛 캔버스 = 위성 없음
|
||||
legend.replaceChildren(...rows.map((row) => createLegend(row)), ...(light ? [lightRow] : []));
|
||||
if (meta && on.slope && data.slope) legend.firstElementChild?.append(gear);
|
||||
legend.hidden = !rows.length;
|
||||
legend.hidden = !rows.length && !light;
|
||||
}
|
||||
|
||||
/** 위성 밝기(요구 475) — 위성 켠 동안 범례 맨 아래 한 줄 · 바로 반영. */
|
||||
gl.setSatelliteLight(readSatLight());
|
||||
const lightRow = createSatLightRow(readSatLight(), (level) => {
|
||||
gl.setSatelliteLight(level);
|
||||
map.redrawBase();
|
||||
});
|
||||
|
||||
/** 급경사 범위(603) — 바꾸면 범례 바로 · 그림은 다시 칠함(늦은 칠하기는 버림). */
|
||||
let slopeBands = readSlopeBands();
|
||||
let slopeTurn = 0;
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
import { themeColor } from "@ui/ui_template_palette";
|
||||
import type { GeoJsonCollection } from "../B04_PreProcess/B04_PreProcess_UI_MapRender";
|
||||
import type { PlanLayerKey } from "./D03_PlanAnalysis_UI_LayerDefs";
|
||||
import { SAT_LIGHT_DEFAULT } from "./D03_PlanAnalysis_UI_SatLight";
|
||||
|
||||
export { GL_FONT, type GlImage };
|
||||
|
||||
@@ -38,6 +39,8 @@ export interface GlBase {
|
||||
setVisible: (key: PlanLayerKey, on: boolean) => void;
|
||||
/** 등고선 주곡선 간격(m) — 캔버스와 같은 「화면 안 가닥 수」 규칙. */
|
||||
setContourStep: (step: number) => void;
|
||||
/** 위성 밝기 상한(0~1) — 바로 반영 · 지도를 다시 세워도 유지. */
|
||||
setSatelliteLight: (level: number) => void;
|
||||
/** 켬 = 지도를 `parent` 맨 앞에 만듦(참 = 섬 · 거짓 = WebGL 못 씀) · null = 버림. */
|
||||
enable: (parent: HTMLElement | null) => boolean;
|
||||
map: () => MapLibreMap | null;
|
||||
@@ -122,22 +125,27 @@ function fillEdge(
|
||||
}
|
||||
|
||||
/** 겹 차례(아래 → 위)와 꼴 — 캔버스 `D03_PlanAnalysis_UI_Layers` 의 색 · 굵기 · 투명도 · 차례 그대로. */
|
||||
function layerSpecs(step: number): GlSpec[] {
|
||||
function layerSpecs(step: number, light: number): GlSpec[] {
|
||||
const contour = themeColor("--draw-map-contour", "#ffd68c");
|
||||
const place = themeColor("--draw-map-place", "#f8fafc");
|
||||
const landslideZone = themeColor("--draw-map-landslide-zone", "#e11d48");
|
||||
const raster = (key: GlSource | "satellite", opacity: number): GlSpec =>
|
||||
const raster = (
|
||||
key: GlSource | "satellite",
|
||||
opacity: number,
|
||||
extra: Record<string, number> = {},
|
||||
): GlSpec =>
|
||||
({
|
||||
key,
|
||||
id: key,
|
||||
type: "raster",
|
||||
source: key,
|
||||
paint: { "raster-opacity": opacity, "raster-fade-duration": 0 },
|
||||
paint: { "raster-opacity": opacity, "raster-fade-duration": 0, ...extra },
|
||||
}) as GlSpec;
|
||||
const lineKind = (key: "faults" | "lineaments" | "zeroOrder", width: number, pattern: number[]) =>
|
||||
haloLine(key, key, themeColor(LINE_COLOR[key], "#f43f5e"), width, pattern);
|
||||
return [
|
||||
raster("satellite", 1),
|
||||
// 위성 = 조금 어둡고 연하게(요구 475 · 노선 선 대비) — 밝기 상한은 사용자 조절
|
||||
raster("satellite", 1, { "raster-brightness-max": light, "raster-saturation": SAT_SATURATION }),
|
||||
raster("hillshade", 1), // 위성 위 = 「곱하기」와 같은 검은 그늘 그림(받는 쪽이 바꿈)
|
||||
raster("slope", 0.55),
|
||||
raster("landslide", 0.6),
|
||||
@@ -313,10 +321,14 @@ const THEME_NAMES = [
|
||||
"--draw-map-parcel",
|
||||
] as const;
|
||||
|
||||
/** 위성 채도(−1~1) — 조금 연하게. */
|
||||
const SAT_SATURATION = -0.3;
|
||||
|
||||
export function createGlBase(projectId: string, onFail: (why: string) => void): GlBase {
|
||||
let step = 5;
|
||||
let light = SAT_LIGHT_DEFAULT;
|
||||
const base = createGlMap<PlanLayerKey>({
|
||||
specs: () => layerSpecs(step),
|
||||
specs: () => layerSpecs(step, light),
|
||||
fixed: { satellite: satelliteTileSource(projectId) },
|
||||
themeNames: THEME_NAMES,
|
||||
className: "d03-plan__gl",
|
||||
@@ -330,5 +342,11 @@ export function createGlBase(projectId: string, onFail: (why: string) => void):
|
||||
const map = base.map();
|
||||
if (map?.getLayer("contour-minor")) map.setFilter("contour-minor", minorFilter(step));
|
||||
},
|
||||
setSatelliteLight(next) {
|
||||
light = next;
|
||||
const map = base.map();
|
||||
if (map?.getLayer("satellite"))
|
||||
map.setPaintProperty("satellite", "raster-brightness-max", next);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* =============================================================================
|
||||
* D03_PlanAnalysis_UI_SatLight.ts
|
||||
* D03 위성 바탕 밝기(요구 475) — 노선 선 대비를 위해 위성을 조금 어둡게 · 사용자가 범례에서 조절.
|
||||
* 값 = 밝기 상한(0.4~1) · 계정 화면 취향으로 기억. 칠하기 = `D03_PlanAnalysis_UI_MapGl` `setSatelliteLight`.
|
||||
* ========================================================================== */
|
||||
|
||||
import { createSlider } from "@ui/ui_template_input";
|
||||
import { readByKey, writeByKey } from "../A00_Common/b_page_state";
|
||||
|
||||
const PREF_KEY = "aislo:pref:d03.satellite-light";
|
||||
export const SAT_LIGHT_MIN = 0.4;
|
||||
export const SAT_LIGHT_MAX = 1;
|
||||
export const SAT_LIGHT_DEFAULT = 0.8;
|
||||
|
||||
/** 기억한 밝기 — 없거나 깨지면 처음 값. */
|
||||
export function readSatLight(): number {
|
||||
const value = Number(readByKey(PREF_KEY));
|
||||
return readByKey(PREF_KEY) !== null && value >= SAT_LIGHT_MIN && value <= SAT_LIGHT_MAX
|
||||
? value
|
||||
: SAT_LIGHT_DEFAULT;
|
||||
}
|
||||
|
||||
/** 범례 「위성 밝기」 칸 — 움직이면 바로 `onChange` · 기억. */
|
||||
export function createSatLightRow(value: number, onChange: (value: number) => void): HTMLElement {
|
||||
const { root, input } = createSlider({
|
||||
label: "위성 밝기",
|
||||
min: SAT_LIGHT_MIN,
|
||||
max: SAT_LIGHT_MAX,
|
||||
step: 0.05,
|
||||
value,
|
||||
format: (v) => `${Math.round(v * 100)} %`,
|
||||
onInput: (v) => {
|
||||
writeByKey(PREF_KEY, String(v));
|
||||
onChange(v);
|
||||
},
|
||||
});
|
||||
input.dataset.role = "satellite-light";
|
||||
return root;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
"""606-1 위성 바탕 밝기 지킴 — D03 위성 칠에 밝기 상한 · 채도 · 사용자 조절 칸 · 갈래 굵기 3 (B04 · B05 위성은 그대로).
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_606_1_sat_light.py -q
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
read = lambda rel: (ROOT / rel).read_text(encoding="utf-8") # noqa: E731
|
||||
|
||||
MAPGL = read("D03_PlanAnalysis/D03_PlanAnalysis_UI_MapGl.ts")
|
||||
LIGHT = read("D03_PlanAnalysis/D03_PlanAnalysis_UI_SatLight.ts")
|
||||
LAYERS = read("D03_PlanAnalysis/D03_PlanAnalysis_UI_Layers.ts")
|
||||
|
||||
|
||||
def test_위성_칠에_밝기_채도():
|
||||
assert re.search(r'raster\("satellite", 1, \{[^}]*"raster-brightness-max": light', MAPGL)
|
||||
assert '"raster-saturation": SAT_SATURATION' in MAPGL
|
||||
|
||||
|
||||
def test_밝기_처음값은_어둡게_범위_안():
|
||||
m = {k: float(v) for k, v in re.findall(r"SAT_LIGHT_(MIN|MAX|DEFAULT) = ([\d.]+)", LIGHT)}
|
||||
assert m["MIN"] < m["DEFAULT"] < m["MAX"] == 1
|
||||
|
||||
|
||||
def test_조절_칸은_GL_위성_켠_때만_기억():
|
||||
assert "createSatLightRow(" in LAYERS
|
||||
assert "glOn && on.satellite" in LAYERS
|
||||
assert "aislo:pref:d03.satellite-light" in LIGHT
|
||||
|
||||
|
||||
def test_갈래_굵기_3():
|
||||
paint = read("D03_PlanAnalysis/D03_PlanAnalysis_UI_DrawPaint.ts")
|
||||
assert "const width = 3;" in paint
|
||||
assert "branch ? 2.5" not in paint
|
||||
|
||||
|
||||
def test_공용_GL_바탕은_안_바뀜():
|
||||
assert "brightness" not in read("ui_template/ui_template_gl_map.ts")
|
||||
Reference in New Issue
Block a user