Files
manual_wpf/Models/NoteExtractionTester.cs
2025-08-12 14:33:18 +09:00

177 lines
8.1 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
namespace DwgExtractorManual.Models
{
/// <summary>
/// Note 박스 텍스트와 테이블 추출 기능을 테스트하는 클래스
/// </summary>
public class NoteExtractionTester
{
/// <summary>
/// DWG 파일에서 Note 데이터를 추출하고 CSV로 저장하는 전체 테스트
/// </summary>
public static void TestNoteExtractionAndCsvExport(string dwgFilePath, string outputDirectory)
{
try
{
Debug.WriteLine("=== Note 추출 및 CSV 내보내기 테스트 시작 ===");
// 출력 디렉토리가 없으면 생성
if (!Directory.Exists(outputDirectory))
{
Directory.CreateDirectory(outputDirectory);
Debug.WriteLine($"출력 디렉토리 생성: {outputDirectory}");
}
// 1. Teigha 서비스 초기화
Debug.WriteLine("1. Teigha 서비스 초기화 중...");
TeighaServicesManager.Instance.AcquireServices();
// 2. DwgDataExtractor 인스턴스 생성
Debug.WriteLine("2. DwgDataExtractor 인스턴스 생성...");
var mappingData = new MappingTableData();
var fieldMapper = new FieldMapper(mappingData);
var extractor = new DwgDataExtractor(fieldMapper);
// 3. Note 데이터 추출
Debug.WriteLine($"3. DWG 파일에서 Note 추출 중: {Path.GetFileName(dwgFilePath)}");
var noteEntities = extractor.ExtractNotesFromDrawing(dwgFilePath);
Debug.WriteLine($" 추출된 Note 엔터티 수: {noteEntities.NoteEntities.Count}");
// 4. Note 데이터 분석
AnalyzeNoteData(noteEntities.NoteEntities);
// 5. CSV 내보내기
Debug.WriteLine("5. CSV 파일 생성 중...");
var csvWriter = new CsvDataWriter();
var baseFileName = Path.GetFileNameWithoutExtension(dwgFilePath);
// 5-1. Note 박스 텍스트만 CSV로 저장
var noteTextCsvPath = Path.Combine(outputDirectory, $"{baseFileName}_note_texts.csv");
csvWriter.WriteNoteBoxTextToCsv(noteEntities.NoteEntities, noteTextCsvPath);
Debug.WriteLine($" Note 텍스트 CSV 저장: {noteTextCsvPath}");
// 5-2. Note 테이블 데이터만 CSV로 저장
var noteTableCsvPath = Path.Combine(outputDirectory, $"{baseFileName}_note_tables.csv");
csvWriter.WriteNoteTablesToCsv(noteEntities.NoteEntities, noteTableCsvPath);
Debug.WriteLine($" Note 테이블 CSV 저장: {noteTableCsvPath}");
// 5-3. 통합 CSV 저장
var combinedCsvPath = Path.Combine(outputDirectory, $"{baseFileName}_note_combined.csv");
csvWriter.WriteNoteDataToCombinedCsv(noteEntities.NoteEntities, combinedCsvPath);
Debug.WriteLine($" 통합 CSV 저장: {combinedCsvPath}");
// 5-4. 개별 테이블 CSV 저장
var individualTablesDir = Path.Combine(outputDirectory, $"{baseFileName}_individual_tables");
csvWriter.WriteIndividualNoteTablesCsv(noteEntities.NoteEntities, individualTablesDir);
Debug.WriteLine($" 개별 테이블 CSV 저장: {individualTablesDir}");
// 5-5. 통계 정보 CSV 저장
var statisticsCsvPath = Path.Combine(outputDirectory, $"{baseFileName}_note_statistics.csv");
csvWriter.WriteNoteStatisticsToCsv(noteEntities.NoteEntities, statisticsCsvPath);
Debug.WriteLine($" 통계 정보 CSV 저장: {statisticsCsvPath}");
Debug.WriteLine("=== Note 추출 및 CSV 내보내기 테스트 완료 ===");
Debug.WriteLine($"모든 결과 파일이 저장되었습니다: {outputDirectory}");
}
catch (Exception ex)
{
Debug.WriteLine($"❌ 테스트 중 오류 발생: {ex.Message}");
Debug.WriteLine($"스택 트레이스: {ex.StackTrace}");
throw;
}
finally
{
// Teigha 서비스 정리
try
{
TeighaServicesManager.Instance.ForceDisposeServices();
Debug.WriteLine("Teigha 서비스 정리 완료");
}
catch (Exception ex)
{
Debug.WriteLine($"Teigha 서비스 정리 중 오류: {ex.Message}");
}
}
}
/// <summary>
/// 추출된 Note 데이터를 분석하여 로그로 출력
/// </summary>
private static void AnalyzeNoteData(List<NoteEntityInfo> noteEntities)
{
Debug.WriteLine("=== Note 데이터 분석 ===");
var noteHeaders = noteEntities.Where(ne => ne.Type == "Note").ToList();
var noteContents = noteEntities.Where(ne => ne.Type == "NoteContent").ToList();
var notesWithTables = noteEntities.Where(ne => ne.Type == "Note" && !string.IsNullOrEmpty(ne.TableCsv)).ToList();
Debug.WriteLine($"전체 Note 헤더 수: {noteHeaders.Count}");
Debug.WriteLine($"전체 Note 콘텐츠 수: {noteContents.Count}");
Debug.WriteLine($"테이블이 있는 Note 수: {notesWithTables.Count}");
// 각 Note 분석
foreach (var note in noteHeaders)
{
Debug.WriteLine($"");
Debug.WriteLine($"Note: '{note.Text}' at ({note.X:F1}, {note.Y:F1})");
if (!string.IsNullOrEmpty(note.TableCsv))
{
var tableLines = note.TableCsv.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
Debug.WriteLine($" 테이블 데이터: {tableLines.Length}행");
// 테이블 내용 일부 출력
for (int i = 0; i < Math.Min(3, tableLines.Length); i++)
{
var line = tableLines[i];
if (line.Length > 50) line = line.Substring(0, 50) + "...";
Debug.WriteLine($" 행 {i + 1}: {line}");
}
if (tableLines.Length > 3)
{
Debug.WriteLine($" ... 및 {tableLines.Length - 3}개 행 더");
}
}
// 이 Note와 연관된 NoteContent들
var relatedContents = noteContents.Where(nc =>
Math.Abs(nc.Y - note.Y) < 50 && // Y 좌표가 비슷한 범위 (Note 아래)
nc.Y < note.Y) // Note보다 아래쪽
.OrderBy(nc => nc.SortOrder)
.ToList();
if (relatedContents.Count > 0)
{
Debug.WriteLine($" 관련 콘텐츠: {relatedContents.Count}개");
foreach (var content in relatedContents.Take(3))
{
Debug.WriteLine($" '{content.Text}' at ({content.X:F1}, {content.Y:F1})");
}
if (relatedContents.Count > 3)
{
Debug.WriteLine($" ... 및 {relatedContents.Count - 3}개 더");
}
}
}
// 레이어별 분포
Debug.WriteLine("");
Debug.WriteLine("레이어별 분포:");
var layerGroups = noteEntities.GroupBy(ne => ne.Layer).OrderByDescending(g => g.Count());
foreach (var layerGroup in layerGroups)
{
Debug.WriteLine($" {layerGroup.Key}: {layerGroup.Count()}개");
}
Debug.WriteLine("=== Note 데이터 분석 완료 ===");
}
}
}