extract .dxf data using ezdxf to add to a pandas dataframe

Question:

The end goal is to extract the text contained on a specific layer, inside of a named view, from the model space. I have the layer restriction (the text in yellow for visual), but I can’t seem to figure out the syntax (if possible) to limit the query to either items inside one of the named views, or within a bounding box that I define to match the named view (orange box). The text being queried is single text. It is (and will always be) an exploded table. Each text item has a unique .insert value.

enter image description here

enter image description here

Ultimately this above mentioned query loop would be put inside a loop to iterate over all named views (bounding box) inside of the model space. Each of the iterations creating a unique list containing the query results. The list would then be input into a pandas dataframe for further manipulations.

import ezdxf

filepath = "C:/MBS_JOBS-16/8741-22/8741-22_(DTL).dxf"
doc = ezdxf.readfile(filepath)
msp = doc.modelspace()

ls = []
for e in msp.query('TEXT MTEXT[layer=="text"]'):
    ls.append(e.dxf.text)

print(ls)
Asked By: Rand0mdude

||

Answers:

The ezdxf package does not have a feature for selecting entities based on location and size, but a bounding box based implementation is relatively easy.

It is important to know that bounding boxes of text based entities (TEXT, MTEXT) are inaccurate because matplotlib (used by ezdxf to render text) renders TTF fonts differently than AutoCAD.

I created an example DXF file with 6 views, called "v1", "v2", …:
view-example

The following code prints the the content of view "v1": ["Text1a", "Text1b"]

import ezdxf
from ezdxf.math import BoundingBox, Vec2
from ezdxf import bbox


def get_view_box(view):
    center = Vec2(view.dxf.center)
    size = Vec2(view.dxf.width, view.dxf.height)
    bottom_left = center - (size / 2)
    top_right = center + (size / 2)
    return BoundingBox([bottom_left, top_right])


doc = ezdxf.readfile("views.dxf")
msp = doc.modelspace()

view = doc.views.get("v1")
view_box = get_view_box(view)

for e in msp.query("TEXT MTEXT"):
    text_box = bbox.extents([e])  # expects a list of entities!
    if view_box.contains(text_box):
        print(e.dxf.text)

Answered By: mozman
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.