← Inbox

C3D-MATCHLBL3 · Match bearings to A/B by insertion pt (read-only) done

Dense-sample tract boundaries; assign each bearing label by its INSERTION point (not extents); drop SS-0-FRAME paperspace labels.

Script file
C3D-MATCHLBL3.cs
Target
active document · model space
Author
claude
Approved
yes · claude (read-only)
Timeout
60s

C# payload

// READ-ONLY: robust label->tract matching.
// - Build dense sample-point sets along A boundary (Parcel, exploded incl. arcs sampled) and B (polyline).
// - For each candidate bearing label use its INSERTION point (MText.Location / DBText.Position /
//   label.LabelLocation), NOT GeometricExtents. Skip paperspace/frame labels (layer SS-0-FRAME).
// - Assign to nearest tract if within 60'; report handle, layer, type, tract, distance.
using System;
using System.Linq;
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;

var db = Db;
var ptsA = new List<Point2d>();
var ptsB = new List<Point2d>();

void SampleLine(List<Point2d> into, Point3d a, Point3d b, int n=20)
{ for(int i=0;i<=n;i++){ double t=i/(double)n; into.Add(new Point2d(a.X+(b.X-a.X)*t, a.Y+(b.Y-a.Y)*t)); } }
void SampleArc(List<Point2d> into, Arc ar, int n=24)
{ for(int i=0;i<=n;i++){ double ang=ar.StartAngle+(ar.TotalAngle)*(i/(double)n); into.Add(new Point2d(ar.Center.X+ar.Radius*Math.Cos(ang), ar.Center.Y+ar.Radius*Math.Sin(ang))); } }

using (var tr = db.TransactionManager.StartTransaction())
{
    var ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);

    // B polyline
    foreach (ObjectId id in ms)
    {
        var e = tr.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;
        if (e is Polyline pl && string.Equals(e.Layer,"SS-BOUNDARY TRACT B",StringComparison.OrdinalIgnoreCase))
        { int n=pl.NumberOfVertices; for(int i=0;i<n;i++){ SampleLine(ptsB, pl.GetPoint3dAt(i), pl.GetPoint3dAt((i+1)%n)); } }
    }
    // A parcel exploded (lines + arcs)
    var cdoc = CivilDocument.GetCivilDocument(db);
    foreach (ObjectId sid in cdoc.GetSiteIds())
    {
        var site=(Site)tr.GetObject(sid,OpenMode.ForRead);
        foreach (ObjectId pid in site.GetParcelIds())
        {
            var p=(Parcel)tr.GetObject(pid,OpenMode.ForRead);
            if(!string.Equals(p.Layer,"SS-BOUNDARY TRACT A",StringComparison.OrdinalIgnoreCase)) continue;
            var col=new DBObjectCollection();
            try{ p.Explode(col);}catch{}
            foreach(Autodesk.AutoCAD.DatabaseServices.DBObject o in col)
            {
                if(o is Line l) SampleLine(ptsA,l.StartPoint,l.EndPoint);
                else if(o is Arc ar) SampleArc(ptsA,ar);
                else if(o is Polyline pp){ int n=pp.NumberOfVertices; for(int i=0;i<n-1;i++) SampleLine(ptsA,pp.GetPoint3dAt(i),pp.GetPoint3dAt(i+1)); }
            }
        }
    }
    Log($"sampleA={ptsA.Count} sampleB={ptsB.Count}");

    double NearA(Point2d p)=> ptsA.Count>0?ptsA.Min(q=>p.GetDistanceTo(q)):9e9;
    double NearB(Point2d p)=> ptsB.Count>0?ptsB.Min(q=>p.GetDistanceTo(q)):9e9;

    int aN=0,bN=0,un=0;
    var aH=new List<string>(); var bH=new List<string>();
    foreach (ObjectId id in ms)
    {
        var e = tr.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;
        if(e==null) continue;
        if(string.Equals(e.Layer,"SS-0-FRAME",StringComparison.OrdinalIgnoreCase)) continue; // frame/paperspace
        string tn=e.GetType().Name;
        Point2d? loc=null;
        if(e is MText m){ var u=m.Text; if(!(u.Contains("°")||u.Contains("\""))) continue; loc=new Point2d(m.Location.X,m.Location.Y); }
        else if(e is DBText t){ var u=t.TextString; if(!(u.Contains("°")||u.Contains("\""))) continue; loc=new Point2d(t.Position.X,t.Position.Y); }
        else if(tn=="GeneralSegmentLabel" || tn=="NoteLabel"){
            try{ var lbl=(Label)e; loc=new Point2d(lbl.LabelLocation.X, lbl.LabelLocation.Y); }catch{ continue; }
        } else continue;
        var pt=loc.Value;
        double dA=NearA(pt), dB=NearB(pt);
        if(Math.Min(dA,dB)>60){ un++; continue; }
        if(dA<=dB){ aN++; aH.Add($"{tn}:{e.Handle}@{e.Layer}(d{dA:0})"); }
        else { bN++; bH.Add($"{tn}:{e.Handle}@{e.Layer}(d{dB:0})"); }
    }
    Log($"ASSIGNED A={aN} B={bN} none={un}");
    Log("A LABELS:"); foreach(var h in aH) Log($"   {h}");
    Log("B LABELS:"); foreach(var h in bH) Log($"   {h}");
    tr.Commit();
}

Result

Status
success
Drawing file
C:\Users\sanja\OneDrive\_SurveyDisco\260619 - 3625 Stonewall Tell Rd, Atlanta, GA 30349, USA\260619 - 3625 Stonewall Tell Rd.dwg
Message
Executed C3D-MATCHLBL3 (0 entities touched).
Entities
Duration
854 ms
Civil 3D
25.0.0.0

Log

sampleA=63 sampleB=168
ASSIGNED A=0 B=1 none=3
A LABELS:
B LABELS:
   GeneralSegmentLabel:20BA6@C-ANNO(d46)

Notes

What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.

No notes yet.