using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; using Teigha.DatabaseServices; using Teigha.Runtime; namespace DwgExtractorManual.Models { /// /// DWG ÆÄÀÏ¿¡¼­ ÅØ½ºÆ® ¿£Æ¼Æ¼¸¦ ÃßÃâÇϴ Ŭ·¡½º /// internal class DwgDataExtractor { private readonly FieldMapper fieldMapper; public DwgDataExtractor(FieldMapper fieldMapper) { this.fieldMapper = fieldMapper ?? throw new ArgumentNullException(nameof(fieldMapper)); } /// /// DWG ÆÄÀÏ¿¡¼­ µ¥ÀÌÅ͸¦ ÃßÃâÇÏ¿© ExcelRowData ¸®½ºÆ®·Î ¹Ýȯ /// public DwgExtractionResult ExtractFromDwgFile(string filePath, IProgress? progress = null, CancellationToken cancellationToken = default) { var result = new DwgExtractionResult(); if (!File.Exists(filePath)) { Debug.WriteLine($"? ÆÄÀÏÀÌ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù: {filePath}"); return result; } try { progress?.Report(0); cancellationToken.ThrowIfCancellationRequested(); using (var database = new Database(false, true)) { database.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null); progress?.Report(10); using (var tran = database.TransactionManager.StartTransaction()) { var bt = tran.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable; using (var btr = tran.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord) { int totalEntities = btr.Cast().Count(); int processedCount = 0; var fileName = Path.GetFileNameWithoutExtension(database.Filename); if (string.IsNullOrEmpty(fileName)) { fileName = "Unknown_File"; } foreach (ObjectId entId in btr) { cancellationToken.ThrowIfCancellationRequested(); using (var ent = tran.GetObject(entId, OpenMode.ForRead) as Entity) { string layerName = GetLayerName(ent.LayerId, tran, database); ProcessEntity(ent, tran, database, layerName, fileName, result); } processedCount++; double currentProgress = 10.0 + (double)processedCount / totalEntities * 80.0; progress?.Report(Math.Min(currentProgress, 90.0)); } } tran.Commit(); } } progress?.Report(100); return result; } catch (OperationCanceledException) { Debug.WriteLine("? ÀÛ¾÷ÀÌ Ãë¼ÒµÇ¾ú½À´Ï´Ù."); progress?.Report(0); return result; } catch (Teigha.Runtime.Exception ex) { progress?.Report(0); Debug.WriteLine($"? DWG ÆÄÀÏ Ã³¸® Áß Teigha ¿À·ù ¹ß»ý: {ex.Message}"); return result; } catch (System.Exception ex) { progress?.Report(0); Debug.WriteLine($"? ÀÏ¹Ý ¿À·ù ¹ß»ý: {ex.Message}"); return result; } } /// /// DWG ÆÄÀÏ¿¡¼­ ÅØ½ºÆ® ¿£Æ¼Æ¼µéÀ» ÃßÃâÇÏ¿© Height Á¤º¸¿Í ÇÔ²² ¹ÝȯÇÕ´Ï´Ù. /// public List ExtractTextEntitiesWithHeight(string filePath) { var attRefEntities = new List(); var otherTextEntities = new List(); try { using (var database = new Database(false, true)) { database.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null); using (var tran = database.TransactionManager.StartTransaction()) { var bt = tran.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable; using (var btr = tran.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord) { foreach (ObjectId entId in btr) { using (var ent = tran.GetObject(entId, OpenMode.ForRead) as Entity) { string layerName = GetLayerName(ent.LayerId, tran, database); // AttributeReference ó¸® if (ent is BlockReference blr) { foreach (ObjectId attId in blr.AttributeCollection) { using (var attRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference) { if (attRef != null) { var textString = attRef.TextString == null ? "" : attRef.TextString; attRefEntities.Add(new TextEntityInfo { Height = attRef.Height, Type = "AttRef", Layer = layerName, Tag = attRef.Tag, Text = textString, }); } } } } // DBText ó¸® else if (ent is DBText dbText) { otherTextEntities.Add(new TextEntityInfo { Height = dbText.Height, Type = "DBText", Layer = layerName, Tag = "", Text = dbText.TextString }); } // MText ó¸® else if (ent is MText mText) { otherTextEntities.Add(new TextEntityInfo { Height = mText.Height, Type = "MText", Layer = layerName, Tag = "", Text = mText.Contents }); } } } } tran.Commit(); } } } catch (System.Exception ex) { Debug.WriteLine($"? ÅØ½ºÆ® ¿£Æ¼Æ¼ ÃßÃâ Áß ¿À·ù ({Path.GetFileName(filePath)}): {ex.Message}"); } var sortedAttRefEntities = attRefEntities.OrderByDescending(e => e.Height).ToList(); var sortedOtherTextEntities = otherTextEntities.OrderByDescending(e => e.Height).ToList(); sortedAttRefEntities.AddRange(sortedOtherTextEntities); return sortedAttRefEntities; } private void ProcessEntity(Entity ent, Transaction tran, Database database, string layerName, string fileName, DwgExtractionResult result) { // AttributeDefinition ÃßÃâ if (ent is AttributeDefinition attDef) { var titleBlockRow = new TitleBlockRowData { Type = attDef.GetType().Name, Name = attDef.BlockName, Tag = attDef.Tag, Prompt = attDef.Prompt, Value = attDef.TextString, Path = database.Filename, FileName = Path.GetFileName(database.Filename) }; result.TitleBlockRows.Add(titleBlockRow); // ¸ÅÇÎ µ¥ÀÌÅÍ ÀúÀå AddMappingData(fileName, attDef.Tag, attDef.TextString, result); } // BlockReference ¹× ±× ¾ÈÀÇ AttributeReference ÃßÃâ else if (ent is BlockReference blr) { foreach (ObjectId attId in blr.AttributeCollection) { using (var attRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference) { if (attRef != null && attRef.TextString.Trim() != "") { var titleBlockRow = new TitleBlockRowData { Type = attRef.GetType().Name, Name = blr.Name, Tag = attRef.Tag, Prompt = GetPromptFromAttributeReference(tran, blr, attRef.Tag), Value = attRef.TextString, Path = database.Filename, FileName = Path.GetFileName(database.Filename) }; result.TitleBlockRows.Add(titleBlockRow); // ¸ÅÇÎ µ¥ÀÌÅÍ ÀúÀå var aiLabel = fieldMapper.ExpresswayToAilabel(attRef.Tag); if (aiLabel != null) { AddMappingData(fileName, attRef.Tag, attRef.TextString, result); } } } } } // DBText ¿£Æ¼Æ¼ ÃßÃâ (º°µµ ½ÃÆ®) else if (ent is DBText dbText) { var textEntityRow = new TextEntityRowData { Type = "DBText", Layer = layerName, Text = dbText.TextString, Path = database.Filename, FileName = Path.GetFileName(database.Filename) }; result.TextEntityRows.Add(textEntityRow); } // MText ¿£Æ¼Æ¼ ÃßÃâ (º°µµ ½ÃÆ®) else if (ent is MText mText) { var textEntityRow = new TextEntityRowData { Type = "MText", Layer = layerName, Text = mText.Contents, Path = database.Filename, FileName = Path.GetFileName(database.Filename) }; result.TextEntityRows.Add(textEntityRow); } } private void AddMappingData(string fileName, string tag, string attValue, DwgExtractionResult result) { var aiLabel = fieldMapper.ExpresswayToAilabel(tag); var mapKey = fieldMapper.AilabelToDocAiKey(aiLabel); if (!string.IsNullOrEmpty(aiLabel)) { var finalMapKey = mapKey ?? aiLabel; result.AddMappingData(fileName, finalMapKey, aiLabel, tag, attValue, ""); } else { var finalMapKey = mapKey ?? tag; if (!string.IsNullOrEmpty(finalMapKey)) { result.AddMappingData(fileName, finalMapKey, tag, tag, attValue, ""); } } } private string? GetPromptFromAttributeReference(Transaction tr, BlockReference blockref, string tag) { string? prompt = null; BlockTableRecord? blockDef = tr.GetObject(blockref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord; if (blockDef == null) return null; foreach (ObjectId objId in blockDef) { AttributeDefinition? attDef = tr.GetObject(objId, OpenMode.ForRead) as AttributeDefinition; if (attDef != null) { if (attDef.Tag.Equals(tag, System.StringComparison.OrdinalIgnoreCase)) { prompt = attDef.Prompt; break; } } } return prompt; } private string GetLayerName(ObjectId layerId, Transaction transaction, Database database) { try { using (var layerTableRecord = transaction.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord) { return layerTableRecord?.Name ?? ""; } } catch (System.Exception ex) { Debug.WriteLine($"Layer À̸§ °¡Á®¿À±â ¿À·ù: {ex.Message}"); return ""; } } } /// /// DWG ÃßÃâ °á°ú¸¦ ´ã´Â Ŭ·¡½º /// public class DwgExtractionResult { public List TitleBlockRows { get; set; } = new List(); public List TextEntityRows { get; set; } = new List(); public Dictionary> FileToMapkeyToLabelTagValuePdf { get; set; } = new Dictionary>(); public void AddMappingData(string fileName, string mapKey, string aiLabel, string dwgTag, string dwgValue, string pdfValue) { if (!FileToMapkeyToLabelTagValuePdf.ContainsKey(fileName)) { FileToMapkeyToLabelTagValuePdf[fileName] = new Dictionary(); } FileToMapkeyToLabelTagValuePdf[fileName][mapKey] = (aiLabel, dwgTag, dwgValue, pdfValue); } } /// /// Title Block Çà µ¥ÀÌÅÍ /// public class TitleBlockRowData { public string Type { get; set; } = ""; public string Name { get; set; } = ""; public string Tag { get; set; } = ""; public string Prompt { get; set; } = ""; public string Value { get; set; } = ""; public string Path { get; set; } = ""; public string FileName { get; set; } = ""; } /// /// Text Entity Çà µ¥ÀÌÅÍ /// public class TextEntityRowData { public string Type { get; set; } = ""; public string Layer { get; set; } = ""; public string Text { get; set; } = ""; public string Path { get; set; } = ""; public string FileName { get; set; } = ""; } /// /// ÅØ½ºÆ® ¿£Æ¼Æ¼ Á¤º¸¸¦ ´ã´Â Ŭ·¡½º /// public class TextEntityInfo { public double Height { get; set; } public string Type { get; set; } = ""; public string Layer { get; set; } = ""; public string Tag { get; set; } = ""; public string Text { get; set; } = ""; } }