Investigate an unknown DXF
Someone hands you site-plan.dxf. No context, no legend, no idea what’s inside. This tutorial walks the four-tool workflow that turns an opaque drawing into answers, using only the pure-ezdxf tier — no FreeCAD needed.
The workflow: survey → annotate → measure → render. Each step narrows the next one.
Step 1: Survey the layers
Section titled “Step 1: Survey the layers”Never guess layer patterns blind. Real civil drawings scatter linework across hundreds of layers, including bound-xref names like XREF-PLAN$0$C-PROP-LINE that no pattern you’d invent from scratch will match. Start with the inventory:
{ "tool": "survey_dxf_layers", "operation": { "file_path": "/data/site-plan.dxf", "operation": "survey", "parameters": { "top": 20 } }}A response looks like:
{ "success": true, "layers_total": 941, "layers_with_geometry": 388, "layers": [ { "layer": "C-TOPO-MINR", "entities": 14210, "types": { "LWPOLYLINE": 14180, "LINE": 30 } }, { "layer": "C-PROP-LINE", "entities": 58, "types": { "LWPOLYLINE": 58 } }, { "layer": "XREF-PLAN$0$C-PROP-BNDY", "entities": 41, "types": { "LINE": 38, "ARC": 3 } } ]}Two things to notice: the busiest layer is usually topography noise, and the layers you care about (property lines, road edges) may hide behind bound-xref prefixes. The contains parameter filters by substring when you already know what you’re hunting:
{ "parameters": { "contains": "PROP" } }Step 2: Harvest the annotations
Section titled “Step 2: Harvest the annotations”Now read what the drawing says about itself. Lot labels, callouts, and notes live in five different places (modelspace, paperspace, block definitions, attribute values, and MTEXT embedded in multileaders), and extract_annotations walks all of them:
{ "tool": "extract_annotations", "operation": { "file_path": "/data/site-plan.dxf", "operation": "annotate", "parameters": { "pattern": "LOT\\s+\\d+" } }}{ "success": true, "annotations_found": 74, "annotations": [ { "text": "LOT 12\n2.31 AC", "layer": "C-ANNO-LABL", "container": "modelspace", "insert": { "x": 154032.7, "y": 88210.4 } } ]}The pattern regex is matched against both the raw text and a whitespace-normalized single-line form, so LOT\s+\d+ matches multi-line labels too. Drop the pattern entirely to see everything, but on large files set expectations: thousands of strings come back.
Also worth a call here: list_sheets, which enumerates paperspace layouts with paper sizes and title-block text — the fastest way to learn “sheet C4 is the grading plan” without rendering anything.
Step 3: Measure by layer
Section titled “Step 3: Measure by layer”With the right layer names in hand, ask quantity questions:
{ "tool": "measure_by_layer", "operation": { "file_path": "/data/site-plan.dxf", "operation": "measure", "parameters": { "layer_pattern": "C-ROAD*" } }}{ "success": true, "units": "feet", "rollups": [ { "layer": "C-ROAD-EDGE", "total_length": 28412.6, "closed_area_sqft": 0.0, "closed_area_acres": 0.0, "dangling_segments": 12 } ]}Zero closed area with nonzero length is normal for open linework like centerlines — the dangling_segments count explains why nothing enclosed. When you do want enclosed area from boundary layers, this tool uses the same noding-and-polygonization pipeline as extract_parcels, so the two reconcile. See Why parcels need polygonization for what’s happening underneath.
Step 4: Render what you found
Section titled “Step 4: Render what you found”Numbers are good; a picture confirms them. Render just the layers you identified:
{ "tool": "render_svg", "operation": { "file_path": "/data/site-plan.dxf", "operation": "render", "parameters": { "layer_pattern": "C-PROP*", "output_name": "property-lines" } }}The SVG lands in the server’s output directory, and the response reports path, size, and element count. Frozen layers that match your pattern are force-rendered — naming a pattern means you want to see it. A pattern that matches nothing returns an error with similar layer names as a hint, never a silently empty file.
Prefer narrow patterns: rendering a full sheet of a large civil file can take ~10 seconds and produce multi-megabyte SVGs.
The loop in practice
Section titled “The loop in practice”An agent working a real file cycles these tools: survey to find candidate layers, render to sanity-check what a layer actually contains, annotate to attach names to geometry, measure to produce the numbers someone asked for. Each response is designed to feed the next call — the survey’s layer names are the render’s patterns, the render’s misses come back with suggestions.
Next: Extract parcels from plat linework, where the boundary layers you just found become closed polygons with acreage.