ExportExcel 정리, height정렬 attRef 분리
This commit is contained in:
397
Models/DwgDataExtractor.cs
Normal file
397
Models/DwgDataExtractor.cs
Normal file
@@ -0,0 +1,397 @@
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// DWG <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ<C6BC><C6BC> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
internal class DwgDataExtractor
|
||||
{
|
||||
private readonly FieldMapper fieldMapper;
|
||||
|
||||
public DwgDataExtractor(FieldMapper fieldMapper)
|
||||
{
|
||||
this.fieldMapper = fieldMapper ?? throw new ArgumentNullException(nameof(fieldMapper));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DWG <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> ExcelRowData <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><>ȯ
|
||||
/// </summary>
|
||||
public DwgExtractionResult ExtractFromDwgFile(string filePath, IProgress<double>? progress = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var result = new DwgExtractionResult();
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Debug.WriteLine($"? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>: {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<ObjectId>().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("? <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD>ҵǾ<D2B5><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
|
||||
progress?.Report(0);
|
||||
return result;
|
||||
}
|
||||
catch (Teigha.Runtime.Exception ex)
|
||||
{
|
||||
progress?.Report(0);
|
||||
Debug.WriteLine($"? DWG <20><><EFBFBD><EFBFBD> ó<><C3B3> <20><> Teigha <20><><EFBFBD><EFBFBD> <20><EFBFBD>: {ex.Message}");
|
||||
return result;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
progress?.Report(0);
|
||||
Debug.WriteLine($"? <20>Ϲ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>: {ex.Message}");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DWG <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ<C6BC><C6BC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> Height <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Բ<EFBFBD> <20><>ȯ<EFBFBD>մϴ<D5B4>.
|
||||
/// </summary>
|
||||
public List<TextEntityInfo> ExtractTextEntitiesWithHeight(string filePath)
|
||||
{
|
||||
var attRefEntities = new List<TextEntityInfo>();
|
||||
var otherTextEntities = new List<TextEntityInfo>();
|
||||
|
||||
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 ó<><C3B3>
|
||||
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 ó<><C3B3>
|
||||
else if (ent is DBText dbText)
|
||||
{
|
||||
otherTextEntities.Add(new TextEntityInfo
|
||||
{
|
||||
Height = dbText.Height,
|
||||
Type = "DBText",
|
||||
Layer = layerName,
|
||||
Tag = "",
|
||||
Text = dbText.TextString
|
||||
});
|
||||
}
|
||||
// MText ó<><C3B3>
|
||||
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($"? <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> ({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 <20><><EFBFBD><EFBFBD>
|
||||
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);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
AddMappingData(fileName, attDef.Tag, attDef.TextString, result);
|
||||
}
|
||||
// BlockReference <20><> <20><> <20><><EFBFBD><EFBFBD> AttributeReference <20><><EFBFBD><EFBFBD>
|
||||
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);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
var aiLabel = fieldMapper.ExpresswayToAilabel(attRef.Tag);
|
||||
if (aiLabel != null)
|
||||
{
|
||||
AddMappingData(fileName, attRef.Tag, attRef.TextString, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// DBText <20><>ƼƼ <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> <20><>Ʈ)
|
||||
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 <20><>ƼƼ <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> <20><>Ʈ)
|
||||
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 <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: {ex.Message}");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DWG <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public class DwgExtractionResult
|
||||
{
|
||||
public List<TitleBlockRowData> TitleBlockRows { get; set; } = new List<TitleBlockRowData>();
|
||||
public List<TextEntityRowData> TextEntityRows { get; set; } = new List<TextEntityRowData>();
|
||||
public Dictionary<string, Dictionary<string, (string, string, string, string)>> FileToMapkeyToLabelTagValuePdf { get; set; }
|
||||
= new Dictionary<string, Dictionary<string, (string, string, string, string)>>();
|
||||
|
||||
public void AddMappingData(string fileName, string mapKey, string aiLabel, string dwgTag, string dwgValue, string pdfValue)
|
||||
{
|
||||
if (!FileToMapkeyToLabelTagValuePdf.ContainsKey(fileName))
|
||||
{
|
||||
FileToMapkeyToLabelTagValuePdf[fileName] = new Dictionary<string, (string, string, string, string)>();
|
||||
}
|
||||
|
||||
FileToMapkeyToLabelTagValuePdf[fileName][mapKey] = (aiLabel, dwgTag, dwgValue, pdfValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Title Block <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
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; } = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Text Entity <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
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; } = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
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; } = "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user