shuishen
2 days ago 91e2fe47a57cd39b612d54177b548e4ec3432783
apps/workbench-console/src/api/artifacts.ts
@@ -2,6 +2,10 @@
export interface DetectionImage { file: string; annotated_file: string; width: number; height: number; detections: Detection[]; }
export interface DetectionRun { detection_count: number; processed_images: number; elapsed_seconds: number; device: string; model: string; confidence: number; input_dir: string; notes: string[]; created_at?: string; }
export interface DetectionCase { id: string; label: string; note: string; artifactRoot: string; inputRoot: string; createdAt: string; run: DetectionRun; images: DetectionImage[]; }
export interface SemanticImage { file: string; width: number; height: number; mask_file: string; overlay_file: string; raster_file: string; vector_file: string; class_pixel_counts: Record<string, number>; georeferenced: boolean; vectorizer: string; elapsed_seconds: number; }
export interface SemanticRun { capability: string; classification: string; task_id?: string; task_name?: string; created_at?: string; geoai_version: string; method: string; model: string; device: string; thresholds: Record<string, number>; input_count: number; processed_images: number; elapsed_seconds: number; images: SemanticImage[]; classes: Array<{ id: number; key: string; label: string; color: number[] }>; limitations: string[]; input_dir?: string; raw_input_dir?: string; }
export interface SemanticCase { id: string; label: string; note: string; artifactRoot: string; inputRoot: string; rawInputRoot: string; createdAt: string; run: SemanticRun; }
export interface SemanticTask { id: string; name: string; status: string; selectable: boolean; input_sensor: string[]; classes: string[]; project_use?: string; required_evidence?: string[]; prohibited_claim?: string; }
export interface TrajectoryEvent { event_id: string; event_type: string; track_ids: string[]; start_time: string; end_time: string; duration_seconds: number; }
export interface TrajectoryCaseRun { case_id: string; input_count: number; track_count: number; event_count: number; dropped_duplicate_observations: number; elapsed_seconds: number; device: string; input: string; thresholds: Record<string, number>; created_at?: string; }
export interface TrajectorySummary { track_id: string; entity_type: string; point_count: string; distance_m: string; average_speed_mps: string; behavior_labels: string; }
@@ -9,6 +13,7 @@
interface CaseDefinition { id: string; label: string; note: string; artifactRoot: string; createdAt: string; }
interface TrajectoryDefinition extends CaseDefinition { showSpatialContext: boolean; showFlyableZones: boolean; }
interface DetectionDefinition extends CaseDefinition { inputRoot: string; }
interface SemanticDefinition extends CaseDefinition { inputRoot: string; rawInputRoot: string; }
export interface UploadFilePayload { name: string; content: string; }
export const artifactUrl = (path: string) => `/${path.replace(/\\/g, "/").split("/").map(encodeURIComponent).join("/")}`;
@@ -40,7 +45,18 @@
  return Object.fromEntries(cases.map((item) => [item.id, item]));
}
export async function loadSemanticArtifacts(): Promise<Record<string, SemanticCase>> {
  const { runs } = await getJson<{ runs: SemanticDefinition[] }>("api/semantic-mapping/runs");
  const cases = await Promise.all(runs.map(async (definition) => ({ ...definition, run: await getJson<SemanticRun>(`${definition.artifactRoot}/run_metadata.json`) } satisfies SemanticCase)));
  return Object.fromEntries(cases.map((item) => [item.id, item]));
}
export async function loadSemanticTasks(): Promise<SemanticTask[]> {
  return (await getJson<{ tasks: SemanticTask[] }>("api/semantic-mapping/tasks")).tasks;
}
async function postRun<T>(path: string, body: object): Promise<T> { return responseJson<T>(await fetch(artifactUrl(path), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) })); }
export async function createTrajectoryRun(files: { flight: UploadFilePayload; route: UploadFilePayload; restricted: UploadFilePayload; flyable?: UploadFilePayload }) { return postRun<{ run: TrajectoryDefinition }>("api/trajectory/runs", { files }); }
export async function createDetectionRun(images: UploadFilePayload[]) { return postRun<{ run: DetectionDefinition }>("api/object-detection/runs", { images }); }
export async function createSemanticRun(images: UploadFilePayload[], taskId: string) { return postRun<{ run: SemanticDefinition }>("api/semantic-mapping/runs", { images, taskId }); }
export function readFileAsPayload(file: File): Promise<UploadFilePayload> { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onerror = () => reject(new Error(`无法读取 ${file.name}`)); reader.onload = () => { const value = String(reader.result ?? ""); resolve({ name: file.name, content: value.slice(value.indexOf(",") + 1) }); }; reader.readAsDataURL(file); }); }