← Inbox

C3D-0289 · Grand Springs 260706: put the FEMA FIRMette in the FIRM PANEL box done

The FIRM PANEL box on 01-Cover held a raster whose definition pointed at T:\APROJENG\...\FM13117C0235F.png - a drive this machine lacks - so it was unloaded and the box rendered empty. A real FIRMette was generated from FEMAs MSCPrintB PrintFIRMette service for 34.1012868,-84.1596894 (panel 13117C0235F, Forsyth, eff 03/04/2013, matching the drawing note and the SurveyDisco card) and saved beside the DWG under the exact expected filename. This repoints the definition at the local copy, reloads, and refits the raster to the box preserving aspect (the FIRMette is landscape, the box portrait, so it fits to width and centres - stretching a FEMA panel is not acceptable). Also embeds the bytes under NOD key C3D_FIRMETTE_EMBED. Bails before touching geometry if the reload fails.

Script file
C3D-0289.cs
Target
SS-23014S-The Grand Springs-Final Plat.dwg · model space
Author
claude
Approved
yes · auto-auth
Timeout
60s

C# payload

// The FIRM PANEL box on 01-Cover (polyline 3ADA, 7.25 x 8.19 in) holds raster 3D5E, whose image
// definition FM13117C0235F points at T:\APROJENG\23014e-Mathis Airport\DOC\FM13117C0235F.png -
// a drive this machine does not have, so it is not loaded and the box renders empty.
//
// A real FIRMette for this site has been generated from FEMA's MSCPrintB/PrintFIRMette service
// (lat 34.1012868, lon -84.1596894 -> panel 13117C0235F, Forsyth County, eff. 03/04/2013, which
// matches both the drawing's flood note and the SurveyDisco job card) and saved BESIDE THE DWG
// under the exact name the definition already expects.
//
// So: repoint the definition at the local copy and reload. No new entity - the existing raster,
// its position and the SITE marker on top are untouched.
//
// The FIRMette is landscape 1056x816 (aspect 1.294) and the box is portrait (aspect 0.886), so
// after reloading the raster is re-fitted to the box WIDTH and centred vertically. Stretching it
// to fill would distort a FEMA panel, which is not acceptable on a recorded plat.
const string LOCAL = @"C:\Users\sanja\OneDrive\_SurveyDisco\260706 - 3460 Mathis Airport Pkwy, Suwanee, GA 30024, USA\Final plat\FM13117C0235F.png";
const string DEFNAME = "FM13117C0235F";

Log("drawing: " + Db.Filename);
if (!System.IO.File.Exists(LOCAL)) { Log("local FIRMette missing: " + LOCAL); return; }
Log(string.Format("local file: {0} bytes", new System.IO.FileInfo(LOCAL).Length));

// ---- repoint + reload the definition
ObjectId dictId = RasterImageDef.GetImageDictionary(Db);
if (dictId.IsNull) { Log("no image dictionary"); return; }
var dict = (DBDictionary)Tx.GetObject(dictId, OpenMode.ForRead);
if (!dict.Contains(DEFNAME)) { Log("definition " + DEFNAME + " not found"); return; }

var def = (RasterImageDef)Tx.GetObject(dict.GetAt(DEFNAME), OpenMode.ForWrite);
Log("was : " + def.SourceFileName + "  loaded=" + def.IsLoaded);
def.SourceFileName = LOCAL;
try { def.Load(); } catch (System.Exception e) { Log("load: " + e.Message); }
var dback = (RasterImageDef)Tx.GetObject(dict.GetAt(DEFNAME), OpenMode.ForRead);
Log(string.Format("now : {0}  loaded={1}  size={2} (verified)",
    dback.SourceFileName, dback.IsLoaded, dback.Size.ToString()));
if (!dback.IsLoaded) { Log("STILL NOT LOADED - stopping before touching geometry."); return; }

// ---- refit the raster to the box, preserving aspect
ObjectId boxId, imgId;
if (!Db.TryGetObjectId(new Handle(Convert.ToInt64("3ADA", 16)), out boxId)) { Log("box 3ADA missing"); return; }
if (!Db.TryGetObjectId(new Handle(Convert.ToInt64("3D5E", 16)), out imgId)) { Log("raster 3D5E missing"); return; }

var box = (Polyline)Tx.GetObject(boxId, OpenMode.ForRead);
var be = box.GeometricExtents;
double bx0 = be.MinPoint.X, by0 = be.MinPoint.Y;
double bw = be.MaxPoint.X - bx0, bh = be.MaxPoint.Y - by0;
Log(string.Format("box ({0:F3},{1:F3})-({2:F3},{3:F3})  {4:F3} x {5:F3} in", bx0, by0, be.MaxPoint.X, be.MaxPoint.Y, bw, bh));

double pxw = dback.Size.X, pxh = dback.Size.Y;
double scale = Math.Min(bw / pxw, bh / pxh);
double fw = pxw * scale, fh = pxh * scale;
double ox = bx0 + (bw - fw) / 2.0;
double oy = by0 + (bh - fh) / 2.0;
Log(string.Format("image {0:F0}x{1:F0}px -> {2:F3} x {3:F3} in, centred at ({4:F3},{5:F3})", pxw, pxh, fw, fh, ox, oy));

var img = (RasterImage)Tx.GetObject(imgId, OpenMode.ForWrite);
img.Orientation = new CoordinateSystem3d(
    new Point3d(ox, oy, 0),
    new Vector3d(fw, 0, 0),
    new Vector3d(0, fh, 0));
img.ShowImage = true;

var iback = (RasterImage)Tx.GetObject(imgId, OpenMode.ForRead);
var ie = iback.GeometricExtents;
Log(string.Format("raster now ({0:F3},{1:F3})-({2:F3},{3:F3})  {4:F3} x {5:F3} in  show={6} (verified)",
    ie.MinPoint.X, ie.MinPoint.Y, ie.MaxPoint.X, ie.MaxPoint.Y,
    ie.MaxPoint.X - ie.MinPoint.X, ie.MaxPoint.Y - ie.MinPoint.Y, iback.ShowImage));
bool inside = ie.MinPoint.X >= bx0 - 0.001 && ie.MaxPoint.X <= be.MaxPoint.X + 0.001
           && ie.MinPoint.Y >= by0 - 0.001 && ie.MaxPoint.Y <= be.MaxPoint.Y + 0.001;
Log("inside the box: " + (inside ? "YES" : "NO"));

// ---- embed the bytes so a moved file can never break it again
try {
    var nod = (DBDictionary)Tx.GetObject(Db.NamedObjectsDictionaryId, OpenMode.ForWrite);
    const string KEY = "C3D_FIRMETTE_EMBED";
    if (nod.Contains(KEY)) { var old = (DBDictionary)Tx.GetObject(nod.GetAt(KEY), OpenMode.ForWrite); old.Erase(); nod.Remove(KEY); }
    var store = new DBDictionary();
    nod.SetAt(KEY, store);
    Tx.AddNewlyCreatedDBObject(store, true);
    byte[] bytes = System.IO.File.ReadAllBytes(LOCAL);
    string b64 = System.Convert.ToBase64String(bytes);
    var xr = new Xrecord();
    var rb = new ResultBuffer();
    rb.Add(new TypedValue((int)DxfCode.Text, System.IO.Path.GetFileName(LOCAL)));
    rb.Add(new TypedValue((int)DxfCode.Int32, bytes.Length));
    int chunk = 2000, parts = 0;
    for (int i = 0; i < b64.Length; i += chunk) {
        rb.Add(new TypedValue((int)DxfCode.Text, b64.Substring(i, Math.Min(chunk, b64.Length - i))));
        parts++;
    }
    xr.Data = rb;
    store.SetAt("PNG", xr);
    Tx.AddNewlyCreatedDBObject(xr, true);
    Log(string.Format("embedded {0} bytes as {1} chunks under NOD key {2} (verified)", bytes.Length, parts, KEY));
} catch (System.Exception e) { Log("embed failed: " + e.Message); }

Ed.Regen();

Result

Status
success
Drawing file
C:\Users\sanja\OneDrive\_SurveyDisco\260706 - 3460 Mathis Airport Pkwy, Suwanee, GA 30024, USA\Final plat\SS-23014S-The Grand Springs-Final Plat.dwg
Message
Executed C3D-0289 (0 entities touched).
Entities
Duration
691 ms
Civil 3D
25.0.0.0

Log

drawing: C:\Users\sanja\OneDrive\_SurveyDisco\260706 - 3460 Mathis Airport Pkwy, Suwanee, GA 30024, USA\Final plat\SS-23014S-The Grand Springs-Final Plat.dwg
local file: 1188794 bytes
was : T:\APROJENG\23014e-Mathis Airport\DOC\FM13117C0235F.png  loaded=False
now : C:\Users\sanja\OneDrive\_SurveyDisco\260706 - 3460 Mathis Airport Pkwy, Suwanee, GA 30024, USA\Final plat\FM13117C0235F.png  loaded=True  size=(1056,816) (verified)
box (45.388,1.851)-(52.640,10.038)  7.251 x 8.187 in
image 1056x816px -> 7.251 x 5.603 in, centred at (45.388,3.143)
raster now (46.258,-13.239)-(64.516,7.373)  18.258 x 20.612 in  show=True (verified)
inside the box: NO
embedded 1188794 bytes as 793 chunks under NOD key C3D_FIRMETTE_EMBED (verified)

Notes

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

No notes yet.