Merge remote-tracking branch 'origin/sub_laptop_7' into sub_laptop_1
This commit is contained in:
@@ -5,12 +5,12 @@
|
||||
새 노선에서 `STRUCTURE_ROUTE_DRIFT_MAX_M` 넘게 멀면 「노선에서 멀어짐」 표시만(버리지 않음).
|
||||
|
||||
- `fill_structure_coordinates` — 저장 때 노선 위 기준 자리로 x · y 채움(자리가 그대로면 옛 좌표
|
||||
지킴) · 옛 자료는 읽을 때 없는 것만 채움.
|
||||
지킴 · 보낸 좌표가 그 누가거리를 낳으면 살림 · 410) · 옛 자료는 읽을 때 없는 것만 채움.
|
||||
- `follow_structures` — 좌표 → 새 노선 누가거리 · 구간 끝은 같은 만큼 밂 · 노선과의 거리.
|
||||
|
||||
짝 = TS `common_util/common_util_route_follow.ts` `followStructures`(구조물) · `projectPipePoints`
|
||||
(관 — 파이썬 본체 = `common_util_drainage_pipes.project_pipe_points`) · 거울 시험 =
|
||||
`resources/tester/test_344_2_route_pairs.py`.
|
||||
(관 — 파이썬 본체 = `common_util_drainage_pipes.project_pipe_points`) · `placeOnLine`(좌표 낡음
|
||||
판정) · 거울 시험 = `resources/tester/test_344_2_route_pairs.py` · `test_410_follow_xy.py`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -20,6 +20,7 @@ from typing import Any, Iterable, Sequence
|
||||
from shapely.geometry import LineString, Point
|
||||
|
||||
from common_util.common_util_structure_station import (
|
||||
SAME_STATION_M,
|
||||
route_general_stations,
|
||||
snap_existing_station,
|
||||
snap_structure_station,
|
||||
@@ -41,6 +42,20 @@ def _positions(item: Any) -> tuple[Any, ...]:
|
||||
return tuple(getattr(item, key, None) for key in _POSITION_KEYS)
|
||||
|
||||
|
||||
def _holds_station(item: Any, line: LineString) -> bool:
|
||||
"""좌표가 그 기준 측점을 낳는가 — 같은 노선 따라감이 누가거리를 안 옮김(TS `holdsStation`)."""
|
||||
at = float(line.project(Point(float(item.x), float(item.y))))
|
||||
length = float(line.length)
|
||||
target = (
|
||||
snap_existing_station(at, route_general_stations(length))
|
||||
if getattr(item, "placement", None) == "site"
|
||||
else snap_structure_station(at, [length])
|
||||
)
|
||||
anchor = float(item.chainage_m)
|
||||
shift = target - anchor
|
||||
return abs(min(max(anchor + shift, 0.0), length) - anchor) <= SAME_STATION_M
|
||||
|
||||
|
||||
def fill_structure_coordinates(
|
||||
items: Iterable[Any],
|
||||
xy: Sequence[Sequence[float]],
|
||||
@@ -51,7 +66,9 @@ def fill_structure_coordinates(
|
||||
"""구조물 x · y 를 노선 위 기준 자리(`chainage_m`)로 채운다(제자리) · 채운 수.
|
||||
|
||||
`previous` = 저장 전 정본 {structure_id: 항목} — 자리(누가거리 셋)가 그대로면 옛 좌표를 지킨다
|
||||
(노선이 바뀌어 멀어진 땅 자리를 다음 저장이 노선 위로 덮지 않게). `only_missing` = 읽을 때.
|
||||
(노선이 바뀌어 멀어진 땅 자리를 다음 저장이 노선 위로 덮지 않게). 보낸 좌표가 그 누가거리를
|
||||
낳으면(지금 노선 따라감 = 제자리) 그 좌표를 살린다(410 · 옮긴 자리 · 따라간 땅 자리) — 낡은
|
||||
좌표(누가거리만 옮김)는 노선 위로. TS 짝 = `placeOnLine`. `only_missing` = 읽을 때.
|
||||
"""
|
||||
line = _line(xy)
|
||||
if line is None:
|
||||
@@ -68,6 +85,8 @@ def fill_structure_coordinates(
|
||||
if old is not None and _positions(old) == _positions(item) and old.x is not None:
|
||||
item.x, item.y = old.x, old.y
|
||||
continue
|
||||
if has_xy and _holds_station(item, line):
|
||||
continue
|
||||
point = line.interpolate(float(anchor))
|
||||
item.x, item.y = round(float(point.x), 4), round(float(point.y), 4)
|
||||
filled += 1
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
* - `followStructures` ↔ 파이썬 `common_util_route_follow.follow_structures`(+ 0 ~ 연장 자름 ·
|
||||
* 노선과 거리 · `STRUCTURE_ROUTE_DRIFT_MAX_M` 넘으면 「노선에서 멀어짐」 · 버리지 않음).
|
||||
* - `projectOnPolyline` = shapely `LineString.project`(가장 가까운 첫 선분) · `distance`.
|
||||
* - `placeOnLine` · `rebasePipeDraft` 는 TS 만 — 좌표 없는 세션 관 초안(정본 PUT 꼴)을 따라가기 전 자리로 ·
|
||||
* 노선을 저장한 [저장]이 서버가 따라 옮긴 관 위에 초안을 얹음(349-0u).
|
||||
* - `placeOnLine` 좌표 낡음 판정 ↔ 파이썬 `fill_structure_coordinates`(좌표가 그 누가거리를 낳으면 살림 ·
|
||||
* 아니면 누가거리의 노선 위 자리 · 410) · 거울 시험 = resources/tester/test_410_follow_xy.py.
|
||||
* - `placeOnLine` 의 좌표 없는 관 · `rebasePipeDraft` 는 TS 만 — 좌표 없는 세션 관 초안(정본 PUT 꼴)을 따라가기
|
||||
* 전 자리로 · 노선을 저장한 [저장]이 서버가 따라 옮긴 관 위에 초안을 얹음(349-0u).
|
||||
* 거울 시험 = resources/tester/test_344_2_route_pairs.py.
|
||||
* ========================================================================== */
|
||||
|
||||
@@ -53,18 +55,35 @@ export function projectOnPolyline(
|
||||
return best && walked > 0 ? { ...best, length_m: walked } : null;
|
||||
}
|
||||
|
||||
/** 좌표 없는 관 · 구조물(세션 초안 = 정본 PUT 꼴 · 좌표 뺌)에 자리를 붙인 사본 — 같은 id · 같은 누가거리인
|
||||
* `saved`(정본 · 좌표 있음)가 있으면 그 좌표(안 옮긴 것 = 서버 따라감과 같은 자리) · 없으면 그 누가거리의
|
||||
* `line` 위 자리(연장 밖은 끝 선분 위로 자름). 좌표가 있거나 누가거리가 없으면 그대로(같은 객체). */
|
||||
/** 좌표가 그 누가거리를 낳는가 — `line` 에서 따라감(같은 선 = 제자리)이 누가거리를 안 옮김(410 · 파이썬
|
||||
* `fill_structure_coordinates` 같은 규칙). 아니면 좌표가 낡음(마커 · 방향키 · 폼으로 누가거리만 옮김). */
|
||||
const holdsStation = (
|
||||
item: FollowingStructure,
|
||||
line: ReadonlyArray<XY>,
|
||||
intervalM: number | null,
|
||||
): boolean => {
|
||||
const [moved] = followStructures([item], line, Infinity, intervalM);
|
||||
return (
|
||||
moved.drift_m === null || Math.abs(moved.item.chainage_m! - item.chainage_m!) <= SAME_STATION_M
|
||||
);
|
||||
};
|
||||
|
||||
/** 관 · 구조물에 자리를 붙인 사본 — 좌표가 그 누가거리를 낳으면 그대로(같은 객체 · 410) · 좌표 없음(세션 관
|
||||
* 초안 = 정본 PUT 꼴 · 좌표 뺌)이면 같은 id · 같은 누가거리인 `saved`(정본 · 앞 따라감 · 좌표 있음)의 좌표(안
|
||||
* 옮긴 것 = 서버 따라감과 같은 자리) · 그 밖(옮김 · 좌표 낡음)은 그 누가거리의 `line` 위 자리(연장 밖은 끝 선분
|
||||
* 위로 자름 = 옮긴 자리가 새 기준). 누가거리가 없으면 그대로. `intervalM` = site 맞춤 간격(`followStructures`). */
|
||||
export function placeOnLine<S extends FollowingStructure & { id?: string | null }>(
|
||||
items: ReadonlyArray<S>,
|
||||
line: ReadonlyArray<XY>,
|
||||
saved: ReadonlyArray<FollowingStructure & { id?: string | null }> = [],
|
||||
intervalM: number | null = null,
|
||||
): S[] {
|
||||
const byId = new Map(saved.map((item) => [item.id, item]));
|
||||
return items.map((item) => {
|
||||
if ((item.x != null && item.y != null) || item.chainage_m == null) return item;
|
||||
const was = item.id ? byId.get(item.id) : undefined;
|
||||
if (item.chainage_m == null) return item;
|
||||
const placed = item.x != null && item.y != null;
|
||||
if (placed && holdsStation(item, line, intervalM)) return item;
|
||||
const was = !placed && item.id ? byId.get(item.id) : undefined;
|
||||
if (
|
||||
was?.x != null &&
|
||||
was.y != null &&
|
||||
@@ -196,11 +215,13 @@ export const placedOnLine = (
|
||||
list: unknown,
|
||||
line: ReadonlyArray<[number, number]>,
|
||||
saved: FollowingStructure[],
|
||||
intervalM: number | null = null,
|
||||
): unknown =>
|
||||
Array.isArray(list)
|
||||
? placeOnLine(
|
||||
list as FollowingStructure[],
|
||||
line.map(([x, y]) => ({ x, y })),
|
||||
saved,
|
||||
intervalM,
|
||||
)
|
||||
: list;
|
||||
|
||||
Reference in New Issue
Block a user