C3D-MHMAP · Map surveyed SSMH to as-built A-numbers (read-only) done
Transform block MH A-number labels to world coords and pair each surveyed manhole to its nearest A-number
C# payload
// Read-only: map each surveyed SSMH to the nearest MH A-number from the fitted PDF block.
// Transforms every 'MH A##' label in the block into world coords via the block reference's
// transform, then pairs each surveyed manhole circle to its closest A-number.
var bt = (BlockTable)Tx.GetObject(Db.BlockTableId, OpenMode.ForRead);
var ms = (BlockTableRecord)Tx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
BlockReference bref = null;
foreach (ObjectId id in ms) {
var o = Tx.GetObject(id, OpenMode.ForRead);
if (o is BlockReference br) {
var d = (BlockTableRecord)Tx.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
if (d.Name.Contains("As Built") || d.Name.Contains("DEV3896")) { bref = br; break; }
}
}
if (bref == null) { Log("PDF block not found."); return; }
var xf = bref.BlockTransform;
var def = (BlockTableRecord)Tx.GetObject(bref.DynamicBlockTableRecord, OpenMode.ForRead);
// A-number labels -> world coords
var anum = new List<(string name, Point2d w)>();
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+$")) {
var p = new Point3d(mt.Location.X, mt.Location.Y, 0).TransformBy(xf);
anum.Add((s.Replace(" ", ""), new Point2d(p.X, p.Y)));
}
}
}
Log($"A-number labels in block: {anum.Count}");
foreach (var a in anum) Log($" {a.name} @({a.w.X:F2},{a.w.Y:F2})");
// surveyed SSMH points
var ssmh = new List<(uint num, string code, Point2d p)>();
foreach (ObjectId id in CivilDoc.CogoPoints) {
var cp = (Autodesk.Civil.DatabaseServices.CogoPoint)Tx.GetObject(id, OpenMode.ForRead);
var c = (cp.RawDescription ?? "").Trim();
if (c.ToUpperInvariant().Contains("SSMH"))
ssmh.Add((cp.PointNumber, c, new Point2d(cp.Easting, cp.Northing)));
}
Log("--- surveyed SSMH -> nearest A-number ---");
foreach (var s in ssmh.OrderBy(x => x.num)) {
string best = "none"; double bd = double.MaxValue;
foreach (var a in anum) { double d = s.p.GetDistanceTo(a.w); if (d < bd) { bd = d; best = a.name; } }
Log($" SSMH {s.num,-5} '{s.code,-22}' -> {best,-8} ({bd:F1} ft)");
}
// existing SEWER_MANHOLE_TEXT labels we'd be renaming
Log("--- current SEWER_MANHOLE_TEXT ---");
foreach (ObjectId id in ms) {
var o = Tx.GetObject(id, OpenMode.ForRead);
if (o is DBText t && t.Layer == "SEWER_MANHOLE_TEXT")
Log($" \"{t.TextString}\" @({t.Position.X:F2},{t.Position.Y:F2})");
}
Result
Log
A-number labels in block: 8 MHA8 @(2296818.13,1280099.71) MHA4 @(2297202.12,1279737.89) MHA2 @(2296981.61,1279581.51) MHA10 @(2296648.41,1280028.79) MHA12 @(2296635.34,1280003.69) MHA16 @(2296394.88,1279930.76) MHA14 @(2296525.55,1279931.91) MHA9 @(2296739.43,1280011.43) --- surveyed SSMH -> nearest A-number --- SSMH 101 'SSMH MD 21.95 ' -> MHA8 (88.5 ft) SSMH 102 'SSMH MD 13.96 WATER ' -> MHA8 (247.8 ft) SSMH 806 'SSMH MD 10.3 ' -> MHA8 (9.8 ft) SSMH 809 'SSMH INV 12.65 ' -> MHA9 (28.7 ft) SSMH 810 'SSMH INV 10.28 ' -> MHA10 (46.0 ft) SSMH 812 'SSMH ' -> MHA10 (46.9 ft) SSMH 814 'SSMH INV 12.22 ' -> MHA14 (24.4 ft) SSMH 816 'SSMH ' -> MHA16 (27.2 ft) SSMH 1095 'SSMH INV 9.45 ' -> MHA10 (43.8 ft) SSMH 1111 'SSMH ' -> MHA10 (29.5 ft) --- current SEWER_MANHOLE_TEXT --- "SSMH 1106" @(2296383.89,1279958.45) "R746.11 IN/A" @(2296383.89,1279952.45) "SSMH 1105" @(2296515.06,1279956.56) "R733.76 I721.54" @(2296515.06,1279950.56) "SSMH 1103" @(2296608.89,1280051.15) "R727.45 IN/A" @(2296608.89,1280045.15) "SSMH 1111" @(2296656.15,1280063.09) "R727.68 IN/A" @(2296656.15,1280057.09) "SSMH 1095" @(2296689.40,1280057.25) "R727.56 I718.11" @(2296689.40,1280051.25) "SSMH 1094" @(2296695.10,1280050.90) "R727.71 I717.43" @(2296695.10,1280044.90) "SSMH 1099" @(2296718.14,1280030.06) "R726.39 I713.74" @(2296718.14,1280024.06) "SSMH 100" @(2296831.27,1280101.07) "R722.67 I712.37" @(2296831.27,1280095.07) "SSMH 101" @(2296880.74,1280036.32) "SSMH MD 21.95" @(2296880.74,1280030.32) "SSMH 102" @(2296984.39,1279915.29) "SSMH MD 13.96 WATER" @(2296984.39,1279909.29)
Notes
What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.
No notes yet.