Merge remote-tracking branch 'origin/dev' into sub_laptop_3
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""347-1 흐름 방향 · 도엽 좌표 저장 — 저장본을 읽어도 결과 같음 · 두 번째는 짓지 않음.
|
||||
|
||||
- 격자 원점 = 좌표 정수 m(셀 모서리 0,0) — 노선이 바뀌어도 같은 자리 셀은 같은 자리.
|
||||
- 방향장 저장본: 입력 지문(도엽 지문 · 남긴 등고 단 · 셀) 같고 범위가 덮으면 읽기만 · 최근 2벌.
|
||||
- 방향장 저장본: 입력 지문(도엽 지문 · 등고 단 · 셀) 같고 범위가 덮으면 읽기만 · 최근 2벌.
|
||||
- 도엽 좌표 저장본: 원본 자국 · 좌표계가 같으면 다시 안 바꿈.
|
||||
실측(검증_sub3 · 차이 0칸 · 108 → 10.8 s 붐빔 · 340 기준 약 6 s)은 bench_342_watershed.py.
|
||||
"""
|
||||
@@ -46,13 +46,12 @@ def test_grid_origin_is_integer_metre():
|
||||
assert spec.x_min == 10.0 and spec.y_max == -3.0
|
||||
|
||||
|
||||
def test_input_key_follows_contours_and_floor():
|
||||
def test_input_key_follows_contours():
|
||||
contours = _contours()
|
||||
base = descent_input_key("도엽-1", contours, None, 1.0)
|
||||
assert base == descent_input_key("도엽-1", contours, None, 1.0)
|
||||
assert base != descent_input_key("도엽-2", contours, None, 1.0) # 도엽 · 좌표계 바뀜
|
||||
assert base != descent_input_key("도엽-1", contours, 200.0, 1.0) # 남긴 등고 단 바뀜
|
||||
assert base == descent_input_key("도엽-1", contours, 100.5, 1.0) # 단 집합 그대로(전부 남음)
|
||||
base = descent_input_key("도엽-1", contours, 1.0)
|
||||
assert base == descent_input_key("도엽-1", contours, 1.0)
|
||||
assert base != descent_input_key("도엽-2", contours, 1.0) # 도엽 · 좌표계 바뀜
|
||||
assert base != descent_input_key("도엽-1", contours[:-1], 1.0) # 등고 단 바뀜
|
||||
|
||||
|
||||
def _run(store, monkeypatch, counter):
|
||||
@@ -88,7 +87,7 @@ def test_store_gives_same_result_and_reads_second_time(tmp_path, monkeypatch):
|
||||
assert np.array_equal(analysis.descent.receiver, plain.descent.receiver)
|
||||
saved = list(tmp_path.glob("descent_*.npz"))
|
||||
assert 1 <= len(saved) <= 2
|
||||
key = descent_input_key("도엽-1", _contours(), None, 1.0)
|
||||
key = descent_input_key("도엽-1", _contours(), 1.0)
|
||||
assert next(iter_saved_descents(tmp_path, key)).spec.n_rows >= plain.spec.n_rows
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
"""520-6 배수유역 확장 한 번 셈 · 노선 무관 방향장 저장본.
|
||||
|
||||
- 한 번 셈(큰 방향장 전체 판정 → 도로로 오는 셀 + 띠 ∪ 1차 영역으로 자름) = 회차 확장과 도로로
|
||||
오는 셀 · 도로 셀 귀속이 셀마다 같음(합성 등고선 · 능선까지 비탈).
|
||||
- 방향장 열쇠 · 짓기가 노선 최저점 하한과 무관 — 하한이 달라도 저장본 하나를 읽기만.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from shapely.geometry import LineString
|
||||
|
||||
from B04_PreProcess import B04_PreProcess_Engine_Watershed_Expand as expand
|
||||
from B04_PreProcess.B04_PreProcess_Engine_Watershed_Flow import trace_flow
|
||||
from B04_PreProcess.B04_PreProcess_Engine_Watershed_Grid import GridSpec
|
||||
|
||||
|
||||
def _ridge_contours():
|
||||
"""도로 북쪽 비탈 — y = −60 능선까지 오르고 그 밖 · 도로 남쪽은 내려감(곧은 등고선)."""
|
||||
features = []
|
||||
for y in range(-250, 0, 5):
|
||||
level = 290.0 - abs(y + 60.0)
|
||||
features.append(
|
||||
{
|
||||
"geometry": {"type": "LineString", "coordinates": [[0.0, y], [300.0, y]]},
|
||||
"properties": {"elevation": level},
|
||||
}
|
||||
)
|
||||
return features
|
||||
|
||||
|
||||
def _case():
|
||||
spec = GridSpec(x_min=110.0, y_max=-130.0, cell_m=1.0, n_rows=40, n_cols=80)
|
||||
domain = np.zeros((40, 80), bool)
|
||||
domain[5:35, 5:75] = True
|
||||
route = LineString([(120.0, -150.0), (180.0, -150.0)])
|
||||
return spec, domain, route
|
||||
|
||||
|
||||
def _run(monkeypatch, once, floor=None, store=None):
|
||||
monkeypatch.setattr(expand, "DESCENT_SPARE_M", 60.0)
|
||||
if not once:
|
||||
monkeypatch.setattr(expand, "_expand_once", lambda *args: None)
|
||||
spec, domain, route = _case()
|
||||
return expand.expand_by_red_boundary(
|
||||
spec, domain, _ridge_contours(), route, [], floor, band_m=10.0, descent_store=store
|
||||
)
|
||||
|
||||
|
||||
def _world(analysis):
|
||||
"""도로로 오는 셀 → {(x, y): 도로 셀 누가거리}."""
|
||||
spec = analysis.spec
|
||||
routing = trace_flow(analysis.terrain, analysis.road)
|
||||
red = analysis.flow.reaches_road & analysis.flow.analyzed
|
||||
chainage = analysis.road.chainage
|
||||
out = {}
|
||||
for index in np.flatnonzero(red):
|
||||
slot = routing.road_slot[index]
|
||||
x = spec.x_min + (index % spec.n_cols) * spec.cell_m
|
||||
y = spec.y_max - (index // spec.n_cols) * spec.cell_m
|
||||
out[(round(x, 3), round(y, 3))] = None if slot < 0 else round(float(chainage[slot]), 3)
|
||||
return out
|
||||
|
||||
|
||||
def test_once_matches_round_expansion(monkeypatch):
|
||||
rounds = _run(monkeypatch, once=False)
|
||||
monkeypatch.undo()
|
||||
once = _run(monkeypatch, once=True)
|
||||
assert rounds.rounds >= 2 and rounds.closed # 회차 확장이 실제로 여러 번 넓힘
|
||||
assert once.closed and once.rounds == 1 and once.added_cells > 0
|
||||
old, new = _world(rounds.analysis), _world(once.analysis)
|
||||
assert len(old) > 3_000
|
||||
assert old == new
|
||||
|
||||
|
||||
def test_descent_key_and_build_ignore_floor(tmp_path, monkeypatch):
|
||||
built = []
|
||||
real = expand.build_contour_descent
|
||||
|
||||
def counting(*args, **kwargs):
|
||||
built.append(args[2:] + tuple(kwargs.values()))
|
||||
return real(*args, **kwargs)
|
||||
|
||||
monkeypatch.setattr(expand, "build_contour_descent", counting)
|
||||
store = (tmp_path, "도엽-1")
|
||||
low = _run(monkeypatch, once=True, floor=None, store=store)
|
||||
high = _run(monkeypatch, once=True, floor=230.0, store=store)
|
||||
assert len(built) == 1 and built[0] == () # 하한 없이 한 번만 지음 · 두 번째는 읽기만
|
||||
assert len(list(tmp_path.glob("descent_*.npz"))) == 1
|
||||
assert _world(low.analysis) == _world(high.analysis)
|
||||
Reference in New Issue
Block a user