Files
SPipe/src/types.ts
T
SPipe EngineeringandClaude Opus 5.5 e3f386addf 도면 출력 추가: 수리 종단면도, 관망도(색인도·부분도·수압표), 범례·색상 선택, DXF(AutoCAD 2018)
- 데모 v2 이후 개발 PC의 변경을 옮김 (이 저장소의 이름 변경·README 정리는 유지)
- 서버 기본 DEM, DEM 등고선, 속성 테이블 범위 선택, WNTR 교차 검증 시험 포함
- 새 라이브러리: ezdxf(Python), maplibre-contour(npm)
- 변경 내역: docs/SPipe_패치내역_도면출력_2026-11-06.txt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 15:03:21 +09:00

276 lines
7.3 KiB
TypeScript

import type { FeatureCollection } from 'geojson';
export interface NodeTimeSeries {
demand: number[];
head: number[];
pressure: number[];
quality: number[];
}
export interface LinkTimeSeries {
flow: number[];
velocity: number[];
headloss: number[];
quality: number[];
energy?: number[];
efficiency?: number[];
}
export interface NodeResult {
id: string;
type: number;
coordinates: { x: number; y: number } | null;
demand: number;
head: number;
pressure: number;
quality?: number;
timeSeries?: NodeTimeSeries;
}
export interface LinkResult {
id: string;
type: number;
fromNode: string;
toNode: string;
vertices: { x: number; y: number }[];
flow: number;
velocity: number;
headloss: number;
quality?: number;
energy?: number;
efficiency?: number;
totalKwh?: number;
peakKw?: number;
avgKw?: number;
utilization?: number;
timeSeries?: LinkTimeSeries;
}
export interface SimulationResult {
engine: { runtime: "native" | "wasm"; version: "2.3.5" };
timeSeconds: number;
timeSteps?: number[];
units: { flow: string; pressure: string };
nodes: Record<string, NodeResult>;
links: Record<string, LinkResult>;
reportText?: string;
qualityInfo?: QualityInfo;
energySummary?: PumpEnergySummary;
/** Warning codes (1-6) returned directly by EN_runH, independent of [REPORT] MESSAGES. */
engineWarnings?: { time: number; code: number }[];
/** [TIMES] REPORT START / REPORT TIMESTEP in seconds. timeSteps also holds
* intermediate event times (tank fills, controls); use reportingStepIndices
* for the periods EPANET itself reports. */
reportStart?: number;
reportStep?: number;
}
export interface PumpEnergyResult {
id: string;
fromNode: string;
toNode: string;
totalKwh: number;
peakKw: number;
avgKw: number;
avgEfficiency: number;
utilization: number;
}
export interface PumpEnergySummary {
pumps: Record<string, PumpEnergyResult>;
totalKwh: number;
peakKw: number;
}
export interface QualityInfo {
qualType: number;
typeName: 'NONE' | 'CHEMICAL' | 'AGE' | 'TRACE';
chemName: string;
chemUnits: string;
traceNode?: string;
status: 'none' | 'success' | 'failed';
errorMessage?: string;
}
export type ComparisonVariable = 'demand' | 'head' | 'pressure' | 'flow' | 'velocity' | 'headloss' | 'quality';
export interface ToleranceConfig {
absTol: number;
relTol: number;
}
export interface ToleranceViolation {
variable: ComparisonVariable;
id: string;
time: number;
diff: number;
tolerance: number;
}
export interface ComparisonResult {
passed: boolean;
maxDiffs: Record<ComparisonVariable, number>;
maxRelativeDiffs: Record<ComparisonVariable, number>;
maxSignificantRelativeDiffs: Record<ComparisonVariable, number>;
nearZeroCounts: Record<ComparisonVariable, number>;
toleranceViolations: ToleranceViolation[];
missingIds: string[];
}
export type SelectionTarget =
| { type: 'node'; id: string }
| { type: 'link'; id: string }
| {
type: 'gis-feature';
layerId: string;
featureId: string | number;
properties: Record<string, unknown>;
geometryType?: string;
}
| null;
export interface MultiSelectionState {
nodes: Set<string>;
links: Set<string>;
gisFeatures: Array<{ layerId: string; featureId: string | number }>;
}
export type EditMode = 'select' | 'add-node' | 'add-pipe';
/** Text shown next to a node / at a link midpoint (calibration values, analysis results ...). */
export interface MapAnnotation {
type: 'node' | 'link';
id: string;
text: string;
color?: string;
}
/** DEM 등고선 on the map (maplibre-contour over the API's terrain tiles). */
export interface DemContours {
demId: string;
/** Minor contour interval (m); every 5th is a labelled major line. */
interval: number;
/** Highest useful tile zoom for this DEM's resolution. */
maxzoom: number;
}
/** 3D 보기: tilted map, optional DEM terrain and node columns. */
export interface View3D {
enabled: boolean;
/** DEM id for terrain (server terrain tiles); none = flat ground. */
demId?: string;
exaggeration: number;
/** Node columns: height from this display value (m). */
columns: 'none' | 'head' | 'pressure' | 'elevation';
columnScale: number;
}
/** Image draped on the map by its four corners (DEM shading, aerial photo, scanned drawing). */
export interface RasterOverlay {
id: string;
name: string;
url: string;
/** [lng, lat] of top-left, top-right, bottom-right, bottom-left. */
corners: [number, number][];
opacity: number;
visible: boolean;
}
/** Right dock tab. */
export type RightTab = 'inspector' | 'results' | 'verification' | 'analysis';
export type DisplayMode =
| 'pressure'
| 'flow'
| 'head'
| 'velocity'
| 'headloss'
| 'elevation'
| 'diff-pressure'
| 'diff-flow'
| 'quality';
export interface Scenario {
id: string;
name: string;
description?: string;
inpStr: string;
result: SimulationResult | null;
createdAt: string;
}
export type BasemapType =
| 'blank'
| 'osm'
| 'vworld'
| 'vworld-white'
| 'vworld-midnight'
| 'vworld-satellite'
| 'vworld-satellite-hybrid';
/* ---------------------------------------------------------------------------
User GIS Reference Layers
--------------------------------------------------------------------------- */
export interface UserGisLayer {
id: string;
name: string;
fileName: string;
featureCollection: FeatureCollection;
featureCount: number;
geomTypes: string[];
estimatedCrs: string;
visible: boolean;
opacity: number; // 0.0 ~ 1.0
color: string;
createdAt: string;
/** CRS the source coordinates were read as (EPSG code / proj4); lets the
* layer be reassigned when that guess was wrong. Absent = WGS84 / unknown. */
sourceCrs?: string;
}
/* ---------------------------------------------------------------------------
Layer Visibility State
--------------------------------------------------------------------------- */
export interface LayerVisibilityState {
// 관망 모델 요소별
nodes: boolean;
pipes: boolean;
pumps: boolean;
valves: boolean;
tanksReservoirs: boolean;
// 레이어별 투명도 (0.0 ~ 1.0)
networkOpacity: {
nodes: number;
pipes: number;
pumps: number;
valves: number;
tanksReservoirs: number;
};
// 결과 표시
results: {
visible: boolean;
opacity: number;
};
}
/* ---------------------------------------------------------------------------
Map Context Menu Event
--------------------------------------------------------------------------- */
export type ContextMenuTarget =
| { type: 'canvas'; lngLat: [number, number]; modelCoords: [number, number] }
| { type: 'node'; id: string; lngLat: [number, number]; modelCoords?: [number, number] }
| { type: 'link'; id: string; lngLat: [number, number] }
| {
type: 'gis-feature';
layerId: string;
featureId: string | number;
properties: Record<string, unknown>;
lngLat: [number, number];
};
export interface MapContextMenuEvent {
x: number;
y: number;
target: ContextMenuTarget;
}