SPipe 데모 v2 (2026-10-30) 서버 배포본
- SPipe_server_2026-10-30.zip 내용을 풀어서 등록 (압축 파일은 올리지 않음) - README에 데모 v2 서버 업데이트 순서 추가, 저장소에 없는 문서 목차 정리 - 패치내역을 docs/로 이동, _worklog.md 추가 - 임시 파일(backend/temp.*)과 API 키가 든 파일은 제외
This commit is contained in:
commit
21ebb16fb7
181 files changed
+57207
No files matched your search
+266
@@ -0,0 +1,266 @@
|
||||
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;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
}
|
||||
Reference in new issue
Block a user