diff --git a/Models/DwgDataExtractor.cs b/Models/DwgDataExtractor.cs
index a8a42b9..2492fbb 100644
--- a/Models/DwgDataExtractor.cs
+++ b/Models/DwgDataExtractor.cs
@@ -507,30 +507,40 @@ namespace DwgExtractorManual.Models
}
///
- /// Note 우측아래에 있는 박스를 찾습니다 (교차선 기반 알고리즘).
- /// Note position에서 height*2 만큼 아래로 수평선을 그어서 교차하는 Line/Polyline을 찾습니다.
+ /// Note 텍스트 아래에 있는 콘텐츠 박스를 찾습니다.
+ /// Note의 정렬점을 기준으로 안정적인 검색 라인을 사용합니다.
///
private (Point3d minPoint, Point3d maxPoint)? FindNoteBox(
Transaction tran, DBText noteText, List polylineIds, List lineIds, HashSet<(Point3d minPoint, Point3d maxPoint)> usedBoxes)
{
var notePos = noteText.Position;
var noteHeight = noteText.Height;
+
+ double stableX;
+ if (noteText.HorizontalMode == TextHorizontalMode.TextLeft)
+ {
+ stableX = noteText.Position.X;
+ }
+ else
+ {
+ stableX = noteText.AlignmentPoint.X;
+ }
- // Note position에서 height * 2 만큼 아래로 수평선 정의
+ // 검색 라인 정의: 안정적인 X좌표를 기준으로 하되, 약간의 오차를 허용하는 너비
double searchY = notePos.Y - (noteHeight * 2);
- var searchLineStart = new Point3d(notePos.X - noteHeight * 10, searchY, 0);
- var searchLineEnd = new Point3d(notePos.X + noteHeight * 50, searchY, 0);
+ double searchWidth = noteHeight * 15;
+ var searchLineStart = new Point3d(stableX - noteHeight * 2, searchY, 0);
+ var searchLineEnd = new Point3d(stableX + searchWidth, searchY, 0);
- Debug.WriteLine($"[DEBUG] 교차 검색선: ({searchLineStart.X}, {searchLineStart.Y}) to ({searchLineEnd.X}, {searchLineEnd.Y})");
+ Debug.WriteLine($"[DEBUG] 안정화된 검색 라인: ({searchLineStart.X:F2}, {searchLineStart.Y:F2}) to ({searchLineEnd.X:F2}, {searchLineEnd.Y:F2}) for NOTE at ({notePos.X:F2}, {notePos.Y:F2}) with stableX={stableX:F2}");
- // 1. Polyline과 교차하는지 확인
+ // 1. Polyline과 교차 확인
foreach (var polylineId in polylineIds)
{
using (var polyline = tran.GetObject(polylineId, OpenMode.ForRead) as Polyline)
{
if (polyline == null) continue;
- // 교차점이 있는지 확인
if (DoesLineIntersectPolyline(searchLineStart, searchLineEnd, polyline))
{
var box = GetPolylineBounds(polyline);
@@ -539,18 +549,12 @@ namespace DwgExtractorManual.Models
Debug.WriteLine($"[DEBUG] 교차하는 Polyline 박스 발견: {box.Value.minPoint} to {box.Value.maxPoint}");
return box;
}
- else if (box.HasValue && usedBoxes.Contains(box.Value))
- {
- Debug.WriteLine($"[DEBUG] 박스가 이미 사용됨: {box.Value.minPoint} to {box.Value.maxPoint}");
- }
}
}
}
- // 2. Line들과 교차하여 닫힌 사각형 찾기
+ // 2. Line들과 교차하여 사각형 찾기
var intersectingLines = FindIntersectingLines(tran, lineIds, searchLineStart, searchLineEnd);
- Debug.WriteLine($"[DEBUG] 교차하는 Line 수: {intersectingLines.Count}");
-
foreach (var startLineId in intersectingLines)
{
var rectangle = TraceRectangleFromLine(tran, lineIds, startLineId, notePos, noteHeight);
@@ -559,10 +563,6 @@ namespace DwgExtractorManual.Models
Debug.WriteLine($"[DEBUG] 교차하는 Line 사각형 발견: {rectangle.Value.minPoint} to {rectangle.Value.maxPoint}");
return rectangle;
}
- else if (rectangle.HasValue && usedBoxes.Contains(rectangle.Value))
- {
- Debug.WriteLine($"[DEBUG] Line 사각형이 이미 사용됨: {rectangle.Value.minPoint} to {rectangle.Value.maxPoint}");
- }
}
return null;
@@ -707,13 +707,13 @@ namespace DwgExtractorManual.Models
}
///
- /// Line에서 시작하여 반시계방향으로 사각형을 추적합니다.
+ /// Line에서 시작하여 반시계방향으로 사각형을 추적합니다. (갭 허용)
///
private (Point3d minPoint, Point3d maxPoint)? TraceRectangleFromLine(Transaction tran, List lineIds, ObjectId startLineId, Point3d notePos, double noteHeight)
{
try
{
- const double tolerance = 2.0; // 좌표 오차 허용 범위
+ double tolerance = noteHeight * 2.0; // 갭 허용 오차를 Note 높이에 비례하여 설정
var visitedLines = new HashSet();
var rectanglePoints = new List();
@@ -727,47 +727,44 @@ namespace DwgExtractorManual.Models
rectanglePoints.Add(nextPoint);
visitedLines.Add(startLineId);
- Debug.WriteLine($"[DEBUG] 사각형 추적 시작: ({currentPoint.X}, {currentPoint.Y}) -> ({nextPoint.X}, {nextPoint.Y})");
+ Debug.WriteLine($"[DEBUG] 사각형 추적 시작 (갭 허용): ({currentPoint.X:F2}, {currentPoint.Y:F2}) -> ({nextPoint.X:F2}, {nextPoint.Y:F2})");
- // 최대 4개의 Line으로 사각형 완성 시도
- for (int step = 0; step < 3; step++) // 시작 Line 제외하고 3개 더 찾기
+ for (int step = 0; step < 5; step++) // 최대 5번의 연결 시도
{
- var nextLineId = FindNextConnectedLine(tran, lineIds, nextPoint, visitedLines, tolerance);
- if (nextLineId == ObjectId.Null) break;
+ var findResult = FindNextConnectedLine(tran, lineIds, nextPoint, visitedLines, tolerance);
+ if (findResult == null) break;
+
+ var nextLineId = findResult.Value.lineId;
+ var connectionType = findResult.Value.connectionType;
using (var nextLine = tran.GetObject(nextLineId, OpenMode.ForRead) as Line)
{
if (nextLine == null) break;
- // 현재 점과 가까운 쪽을 시작점으로 설정
- Point3d lineStart, lineEnd;
- if (nextPoint.DistanceTo(nextLine.StartPoint) < nextPoint.DistanceTo(nextLine.EndPoint))
+ Point3d newNextPoint;
+ if (connectionType == "Start")
{
- lineStart = nextLine.StartPoint;
- lineEnd = nextLine.EndPoint;
+ newNextPoint = nextLine.EndPoint;
}
else
{
- lineStart = nextLine.EndPoint;
- lineEnd = nextLine.StartPoint;
+ newNextPoint = nextLine.StartPoint;
}
- rectanglePoints.Add(lineEnd);
+ rectanglePoints.Add(newNextPoint);
visitedLines.Add(nextLineId);
- nextPoint = lineEnd;
+ nextPoint = newNextPoint;
- Debug.WriteLine($"[DEBUG] 다음 Line 추가: ({lineStart.X}, {lineStart.Y}) -> ({lineEnd.X}, {lineEnd.Y})");
+ Debug.WriteLine($"[DEBUG] 다음 Line 추가 (갭 허용): {nextLine.StartPoint} -> {nextLine.EndPoint}");
- // 시작점으로 돌아왔는지 확인 (사각형 완성)
if (nextPoint.DistanceTo(currentPoint) < tolerance)
{
- Debug.WriteLine("[DEBUG] 사각형 완성됨");
+ Debug.WriteLine("[DEBUG] 사각형 완성됨 (갭 허용)");
break;
}
}
}
- // 4개 이상의 점이 있고 닫힌 형태인지 확인
if (rectanglePoints.Count >= 4)
{
var bounds = CalculateBounds(rectanglePoints);
@@ -782,16 +779,20 @@ namespace DwgExtractorManual.Models
}
catch (System.Exception ex)
{
- Debug.WriteLine($"[DEBUG] 사각형 추적 중 오류: {ex.Message}");
+ Debug.WriteLine($"[DEBUG] 사각형 추적 중 오류 (갭 허용): {ex.Message}");
return null;
}
}
///
- /// 현재 점에서 연결된 다음 Line을 찾습니다.
+ /// 현재 점에서 가장 가까운 연결된 다음 Line을 찾습니다. (갭 허용)
///
- private ObjectId FindNextConnectedLine(Transaction tran, List lineIds, Point3d currentPoint, HashSet visitedLines, double tolerance)
+ private (ObjectId lineId, string connectionType)? FindNextConnectedLine(Transaction tran, List lineIds, Point3d currentPoint, HashSet visitedLines, double tolerance)
{
+ ObjectId? bestMatchId = null;
+ string? bestConnectionType = null;
+ double minDistance = tolerance;
+
foreach (var lineId in lineIds)
{
if (visitedLines.Contains(lineId)) continue;
@@ -800,16 +801,30 @@ namespace DwgExtractorManual.Models
{
if (line == null) continue;
- // 현재 점과 연결되어 있는지 확인
- if (currentPoint.DistanceTo(line.StartPoint) < tolerance ||
- currentPoint.DistanceTo(line.EndPoint) < tolerance)
+ double distToStart = currentPoint.DistanceTo(line.StartPoint);
+ if (distToStart < minDistance)
{
- return lineId;
+ minDistance = distToStart;
+ bestMatchId = lineId;
+ bestConnectionType = "Start";
+ }
+
+ double distToEnd = currentPoint.DistanceTo(line.EndPoint);
+ if (distToEnd < minDistance)
+ {
+ minDistance = distToEnd;
+ bestMatchId = lineId;
+ bestConnectionType = "End";
}
}
}
- return ObjectId.Null;
+ if (bestMatchId.HasValue)
+ {
+ return (bestMatchId.Value, bestConnectionType);
+ }
+
+ return null;
}
///