C3D-PDFMH · Find manhole symbols in PDF block (read-only) done
Locate circle symbols near MH A-number labels for accurate transform control
C# payload
// Read-only: find CIRCLES in the PDF block near the 'MH A14'/'MH A16' labels. Manhole SYMBOLS
// (not their text labels) are the correct control for computing the transform.
var bt = (BlockTable)Tx.GetObject(Db.BlockTableId, OpenMode.ForRead);
BlockTableRecord def = null;
foreach (ObjectId id in bt) {
var b = (BlockTableRecord)Tx.GetObject(id, OpenMode.ForRead);
if (b.Name.Contains("As Built") || b.Name.Contains("DEV3896")) { def = b; break; }
}
if (def == null) { Log("block def not found"); return; }
var labels = new List<(string txt, Point2d p)>();
var circles = new List<(Point2d c, double r)>();
foreach (ObjectId id in def) {
var o = Tx.GetObject(id, OpenMode.ForRead);
if (o is MText mt) {
var s = (mt.Contents ?? "").Trim().ToUpperInvariant();
if (System.Text.RegularExpressions.Regex.IsMatch(s, @"^MH\s*A\d+$"))
labels.Add((mt.Contents.Trim(), new Point2d(mt.Location.X, mt.Location.Y)));
} else if (o is Circle c) circles.Add((new Point2d(c.Center.X, c.Center.Y), c.Radius));
}
Log($"MH labels: {labels.Count} circles in block: {circles.Count}");
// typical manhole symbol radius: report the radius distribution
var byR = new Dictionary<string,int>();
foreach (var c in circles) { var k = c.r.ToString("F3"); byR[k] = byR.TryGetValue(k, out var n) ? n+1 : 1; }
Log("circle radii (block units):");
foreach (var kv in byR.OrderByDescending(x => x.Value).Take(12)) Log($" r={kv.Key}: x{kv.Value}");
Log("--- nearest circle to each MH label ---");
foreach (var l in labels.OrderBy(x => x.txt)) {
double bd = double.MaxValue; Point2d best = new Point2d(); double br = 0;
foreach (var c in circles) { double d = l.p.GetDistanceTo(c.c); if (d < bd) { bd = d; best = c.c; br = c.r; } }
Log($" {l.txt,-8} label@({l.p.X:F3},{l.p.Y:F3}) -> circle@({best.X:F4},{best.Y:F4}) r={br:F4} dist={bd:F4}");
}
Result
Log
MH labels: 8 circles in block: 108 circle radii (block units): r=0.007: x18 r=0.043: x12 r=0.013: x10 r=0.018: x10 r=0.026: x9 r=0.014: x9 r=0.072: x7 r=0.002: x5 r=0.011: x5 r=0.005: x3 r=0.028: x3 r=0.024: x3 --- nearest circle to each MH label --- MH A10 label@(3488945.751,-1062981.381) -> circle@(3488945.8131,-1062981.2964) r=0.0720 dist=0.1049 MH A12 label@(3488946.091,-1062981.568) -> circle@(3488946.2684,-1062981.2538) r=0.0281 dist=0.3610 MH A14 label@(3488947.040,-1062983.096) -> circle@(3488946.7660,-1062983.2881) r=0.0434 dist=0.3347 MH A16 label@(3488947.014,-1062984.887) -> circle@(3488946.6984,-1062985.0852) r=0.0434 dist=0.3728 MH A2 label@(3488951.987,-1062976.957) -> circle@(3488952.2466,-1062976.3027) r=0.0434 dist=0.7037 MH A4 label@(3488949.914,-1062973.885) -> circle@(3488950.1346,-1062974.2480) r=0.0434 dist=0.4248 MH A8 label@(3488944.833,-1062979.033) -> circle@(3488945.0878,-1062979.4343) r=0.0434 dist=0.4756 MH A9 label@(3488946.018,-1062980.139) -> circle@(3488945.8556,-1062980.4048) r=0.0434 dist=0.3113
Notes
What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.
No notes yet.