drawing_tools.table package#
Submodules#
drawing_tools.table.core module#
Table detection algorithm for detect tables in technical drawings.
This module provides methods to detect and extract table structures from technical drawings.
- class drawing_tools.table.core.TableLine(edge: Edge | None = None, start: Point2D | None = None, end: Point2D | None = None, tolerance: float = 0.5, span_ranges: list[tuple[float, float]] | None = None, name: str = '')#
Bases:
DessiaObjectRepresents a line segment for table detection, either from an Edge or virtual.
This class wraps line segments that are used in table structure detection, providing convenient properties for analyzing table grid patterns. Lines can be either extracted from Edge objects or created as virtual lines to complete table boundaries.
- __init__(edge: Edge | None = None, start: Point2D | None = None, end: Point2D | None = None, tolerance: float = 0.5, span_ranges: list[tuple[float, float]] | None = None, name: str = '')#
Initialize either from an Edge or from explicit coordinates.
- Parameters:
edge – Optional Edge object to extract line from
start – Start point (required if edge is None)
end – End point (required if edge is None)
tolerance – Tolerance for line classification (vertical/horizontal detection)
span_ranges – Optional custom span ranges (for merged lines with gaps)
- Raises:
ValueError – If edge is invalid or if start/end are missing when edge is None
- classmethod from_edge(edge: Edge, tolerance: float = 0.001) TableLine#
Create TableLine from an Edge object.
- Parameters:
edge – Edge containing a line segment
tolerance – Tolerance for line classification
- Returns:
TableLine instance
- classmethod virtual(start: Point2D, end: Point2D, tolerance: float = 0.001) TableLine#
Create a virtual TableLine without an associated Edge.
Virtual lines are used to complete table boundaries when detecting table structures that may have incomplete borders.
- Parameters:
start – Start point of the line
end – End point of the line
tolerance – Tolerance for line classification
- Returns:
TableLine instance marked as virtual
- property start: Point2D#
Get the start point of the line segment.
- property end: Point2D#
Get the end point of the line segment.
- property line_coordinate: float#
Get the coordinate value where this line is positioned.
For vertical lines, returns the x-coordinate. For horizontal lines, returns the y-coordinate.
- Returns:
The average coordinate along the line’s perpendicular axis
- property is_virtual: bool#
Check if this is a virtual line (no associated Edge).
Virtual lines are created to complete table boundaries and don’t correspond to actual geometry in the drawing.
- Returns:
True if this line has no associated Edge object
- merge_with(other: TableLine) TableLine#
Merge this line with another parallel line.
- Parameters:
other – Another TableLine that should be parallel to this one
- Returns:
New TableLine representing the merged result
- Raises:
ValueError – If lines are not parallel or compatible
- property gap_positions: list[tuple[float, float]]#
Get the positions of gaps in this line.
- Returns:
List of (start, end) positions where gaps exist
- property coverage_ratio: float#
Calculate the ratio of covered length to total possible length.
Useful for determining if a line is mostly continuous or has significant gaps.
- is_on_range(coord: float, tolerance: float = 0.0) bool#
Check if a coordinate falls on any span of this line.
- Parameters:
coord – y-coordinate for vertical lines, x-coordinate for horizontal
tolerance – Tolerance to extend span boundaries (handles floating-point imprecision)
- Returns:
True if the coordinate is within any span range
- class drawing_tools.table.core.TableCell(row_id: int, col_id: int, start: Point2D, end: Point2D, row_range: tuple[int, int], col_range: tuple[int, int], content: list[Entity] | None = None, name: str = '')#
Bases:
DessiaObjectRepresents a logical cell in a detected table with content.
TableCell represents the logical/semantic cells of a table, which may span multiple grid positions when merged. Each TableCell contains the actual content (text, annotations) and represents how the table appears to users.
- Example:
If a table cell spans positions (0,0) to (0,2) in the grid: - get_table_cell_at(0, 0), get_table_cell_at(0, 1), get_table_cell_at(0, 2) all return the same TableCell - This TableCell has row_range=(0,0), col_range=(0,2) and contains all content
- __init__(row_id: int, col_id: int, start: Point2D, end: Point2D, row_range: tuple[int, int], col_range: tuple[int, int], content: list[Entity] | None = None, name: str = '')#
Initialize a TableCell.
- Parameters:
row_id – Row index of the first grid position this cell occupies
col_id – Column index of the first grid position this cell occupies
start – Bottom-left corner point of the cell
end – Top-right corner point of the cell
row_range – Tuple of (start_row, end_row) indicating the cell’s row span
col_range – Tuple of (start_col, end_col) indicating the cell’s column span
content – Optional list of Entity objects (text, annotations) contained in this cell
name – Optional name for the cell
- property center: Point2D#
Get the center point of the cell.
- property bounding_rectangle: BoundingRectangle#
Convert cell to a BoundingRectangle.
- contains_entity(entity: Entity) bool#
Check if an entity belongs to this cell.
An entity belongs to a cell if its bounding rectangle center is inside the cell’s bounding rectangle.
- Parameters:
entity – The entity to check
- Returns:
True if the entity belongs to this cell
- add_content(entity: Entity) None#
Add an entity to this cell’s content.
- Parameters:
entity – The entity to add to the cell
- get_text_content(ordered: bool = True, line_tolerance: float = 2.0) list[str]#
Extract text content from all entities in this cell.
- Parameters:
ordered – If True, orders content in reading order (top-to-bottom, left-to-right)
line_tolerance – Tolerance for grouping items on the same line (in drawing units)
- Returns:
List of text strings from text-searchable entities
- get_ordered_content(line_tolerance: float = 2.0) list[Entity]#
Get cell content ordered in reading order (top-to-bottom, left-to-right).
Groups entities by line (similar Y coordinate) then sorts each line left-to-right.
- Parameters:
line_tolerance – Tolerance for grouping items on the same line
- Returns:
List of entities ordered for reading
- get_combined_text(ordered: bool = True, separator: str = ' ', line_tolerance: float = 2.0) str#
Get all text content combined into a single string.
- Parameters:
ordered – If True, orders content in reading order
separator – Separator between text elements
line_tolerance – Tolerance for grouping items on the same line
- Returns:
Combined text string
- contains_text(text: str, case_sensitive: bool = False, ordered: bool = True) bool#
Check if this cell contains the given text.
Searches through the cell’s combined text content and returns True if the specified text is found as a substring.
- Parameters:
text – The text to search for (e.g., “SAFETY CLASS”)
case_sensitive – If True, the search is case-sensitive (default: False)
ordered – If True, orders content in reading order before searching
- Returns:
True if the cell contains the text, False otherwise
- class drawing_tools.table.core.GridCell(row: int, col: int, start: Point2D, end: Point2D, merge_origin_position: tuple[int, int] | None = None, name: str = '')#
Bases:
DessiaObjectRepresents a single position in the virtual grid structure.
GridCell represents a cell at a unique position in the table’s underlying grid structure. Each grid position has its own GridCell, even if it’s part of a merged logical cell. GridCell provides geometric information but does not contain content directly.
- Example:
If a TableCell spans positions (0,0) to (0,2) in the grid: - get_grid_cell_at(0, 0) returns GridCell at (0,0) with merge_origin_position=None - get_grid_cell_at(0, 1) returns GridCell at (0,1) with merge_origin_position=(0,0) - get_grid_cell_at(0, 2) returns GridCell at (0,2) with merge_origin_position=(0,0) - All three positions reference the same TableCell via get_table_cell_at()
- __init__(row: int, col: int, start: Point2D, end: Point2D, merge_origin_position: tuple[int, int] | None = None, name: str = '')#
Initialize a GridCell.
- Parameters:
row – Row index in the virtual grid (0-based)
col – Column index in the virtual grid (0-based)
start – Bottom-left corner point of this grid cell
end – Top-right corner point of this grid cell
merge_origin_position – (row, col) tuple of the first grid position if this cell is part of a merged TableCell. None if this is the first position of a logical cell.
name – Optional name for the grid cell
- property center: Point2D#
Get the center point of the grid cell.
- class drawing_tools.table.core.TableGrid(x_positions: list[float], y_positions: list[float], name: str = '')#
Bases:
DessiaObjectRepresents the virtual grid structure of a table.
- __init__(x_positions: list[float], y_positions: list[float], name: str = '') None#
Initialize the table grid.
- Parameters:
x_positions – List of x-coordinates for vertical lines
y_positions – List of y-coordinates for horizontal lines
- classmethod from_table_lines(v_lines: list[TableLine], h_lines: list[TableLine]) TableGrid#
Create a grid from a set of horizontal and vertical lines.
- plot_data_primitives(show_indices: bool = True, extra_primitives: list[PlotDataObject] | None = None) list[PlotDataObject]#
Generate plot data primitives for the virtual grid.
- Parameters:
extra_primitives – Optional plot data primitives to be integrated in the table plot
show_indices – Whether to show row/col indices
- Returns:
List of plot data primitives
- plot_data(show_indices: bool = True, extra_primitives: list[PlotDataObject] | None = None) None#
Generate plot data visualization for the virtual grid.
- Parameters:
extra_primitives – Optional plot data primitives to be integrated in the table plot
show_indices – Whether to show row/col indices
- Returns:
List of plot data primitives
- class drawing_tools.table.core.TableStructure(lines: list[TableLine], bounds: BoundingRectangle, tolerance: float = 0.001, name: str = '')#
Bases:
DessiaObjectRepresents the reverse-engineered structure of a table.
Contains organized lines, grid information, and methods to detect cells within the structure. Serves as the structural foundation for creating a DetectedTable.
- __init__(lines: list[TableLine], bounds: BoundingRectangle, tolerance: float = 0.001, name: str = '')#
Initialize by extracting structure from lines.
- Parameters:
lines – Collection of TableLine objects
bounds – Bounding rectangle of the structure
tolerance – Tolerance for line processing
- detect_cells(min_cell_size: float = 2.0, annotations: list[Entity] | None = None) list[TableCell]#
Detect TableCell objects by analyzing the grid structure and optionally populate with annotations.
- Parameters:
min_cell_size – Minimum dimension for a valid cell
annotations – Optional list of annotations to associate with cells
- Returns:
List of detected TableCell objects with their content
drawing_tools.table.detection module#
Table detection algorithms and structure analysis.
- drawing_tools.table.detection.is_symbol_with_rectangle_frame(symbol_entity: Entity) bool#
Check if a Symbol entity has a rectangular frame with a valid bounding rectangle.
- Parameters:
symbol_entity – A Symbol entity to test.
- Returns:
True if the symbol has a frame with
entity_type == "RECTANGLE"and a valid bounding rectangle.
- class drawing_tools.table.detection.CandidatePreparationConfig(line_segment_tolerance: float = 0.5, connectivity_filter: ConnectivityFilterConfig = <factory>)#
Bases:
objectConfiguration for candidate edge preparation (Phase 1).
- connectivity_filter: ConnectivityFilterConfig#
- __init__(line_segment_tolerance: float = 0.5, connectivity_filter: ConnectivityFilterConfig = <factory>) None#
- class drawing_tools.table.detection.TableGenerationConfig(tolerance: float = 0.5, min_table_size: float = 10.0, min_cell_size: float = 2.0, min_edges_for_table: int = 4, min_lines_in_component: int = 4, intersection_tolerance: float = 0.5, min_lines_for_extent: int = 2)#
Bases:
objectConfiguration for table structure detection (Phase 2).
- class drawing_tools.table.detection.TableSelectionConfig(min_content_ratio: float = 0.3, max_sheet_coverage_ratio: float = 0.8, min_nb_cells: int = 2, validate_has_cells: bool = True, validate_sheet_coverage: bool = True, validate_content_ratio: bool = True)#
Bases:
objectConfiguration for table validation and selection (Phase 3).
- class drawing_tools.table.detection.DetectedTable(structure: TableStructure, cells: list[TableCell], source: str = '', name: str = '')#
Bases:
DessiaObjectRepresents a detected table with its cells.
- __init__(structure: TableStructure, cells: list[TableCell], source: str = '', name: str = '')#
Initialize a DetectedTable.
- Parameters:
structure – The table structure containing lines and grid
cells – List of TableCell objects that make up the table
source – Origin of the table (e.g. candidate set name, “annotation”)
name – Optional name for the table
- property bounding_rectangle: BoundingRectangle#
Get the table’s BoundingRectangle.
- get_table_cell_at(row_index: int, column_index: int) TableCell | None#
Get the TableCell object at a specific grid position.
- get_grid_cell_at(row_index: int, column_index: int) GridCell | None#
Get the GridCell object at a specific grid position.
- find_table_cells_with_text(text: str, case_sensitive: bool = False) list[TableCell]#
Find all cells containing the given text.
Searches through all cells in the table and returns all cells that contain the specified text.
- Parameters:
text – The text to search for (e.g., “SAFETY CLASS”)
case_sensitive – If True, the search is case-sensitive (default: False)
- Returns:
List of TableCell objects containing the text
- plot_data_primitives(extra_primitives: list[PlotDataObject] | None = None, color_legend: bool = True, opacity: float = 0.4, detailed: bool = False) list[PlotDataObject]#
Get the plot data representation for the detected table.
- Parameters:
extra_primitives – Optional plot data primitives to be integrated in the table plot
color_legend – If activated, table cells will be differentiated in the plot by their merge status.
opacity – The opacity of the table regions.
detailed – If activated, add cells information texts.
- plot_data(extra_primitives: list[PlotDataObject] | None = None, color_legend: bool = True, detailed: bool = False, opacity: float = 0.4) None#
Visualize the final detected table with cells.
- Parameters:
extra_primitives – Optional plot data primitives to be integrated in the table plot.
color_legend – If activated, table cells will be differentiated in the plot by their merge status.
detailed – If activated, table cells will be differentiated in the plot by their merge status.
opacity – The opacity of the table regions.
- class drawing_tools.table.detection.TableGenerator(config: TableGenerationConfig | None = None)#
Bases:
DessiaObjectDetects tables in technical drawings by analyzing line segments.
Integrates connection analysis and orchestrates the detection process.
- __init__(config: TableGenerationConfig | None = None)#
Initialize the TableGenerator.
- Parameters:
config – Configuration for table generation
- structures: list[TableStructure]#
- detect_tables_from_edges(edges: list[Edge], annotations: list[Entity] | None = None, source: str = '') list[DetectedTable]#
Detect tables from a list of edge geometries and optionally populate with annotations.
- Parameters:
edges – List of edges that may form tables
annotations – Optional list of annotations to associate with table cells
source – Source identifier to tag on each detected table (e.g. “background_geometries”)
- Returns:
List of detected tables with populated content
- capture_generation_data(source: str, detected_tables: list[DetectedTable]) TableGenerationSetData#
Snapshot the current generator state into a
TableGenerationSetData.- Parameters:
source – Source identifier for this candidate set.
detected_tables – Tables detected from the current candidate set.
- Returns:
A data snapshot of the generation phase for this candidate set.
- class drawing_tools.table.detection.SheetTableDetector(sheet: Sheet, candidate_preparation_config: CandidatePreparationConfig | None = None, table_generation_config: TableGenerationConfig | None = None, table_selection_config: TableSelectionConfig | None = None, store_detection_data: bool = False)#
Bases:
DessiaObjectDetects and extracts table structures from technical drawing sheets.
- __init__(sheet: Sheet, candidate_preparation_config: CandidatePreparationConfig | None = None, table_generation_config: TableGenerationConfig | None = None, table_selection_config: TableSelectionConfig | None = None, store_detection_data: bool = False)#
Initialize the detector with a sheet.
- Parameters:
sheet – The sheet containing tables.
candidate_preparation_config – Configuration for candidate edge preparation (Phase 1)
table_generation_config – Configuration for table structure detection (Phase 2)
table_selection_config – Configuration for table validation and selection (Phase 3)
store_detection_data – If True, store all intermediate pipeline data for visualization/debugging. Access via
detection_dataproperty after detection.
- property tables: dict[int, list[Table | DetectedTable]]#
All detected tables (computed once on first access).
- Returns:
Dictionary mapping view index to list of detected tables.
- property detection_data: TableDetectionData#
Access stored detection data. Only available when
store_detection_data=True.
- get_title_block_annotations() list[Entity]#
Extract annotations that belong to the title block area.
- get_title_block_table() DetectedTable | None#
Detect the table that represents the title block in the drawing.
- detect_title_block() TitleBlock | None#
Detect the title block and extract structured information.
- detect_view_tables(view: View, is_background: bool = False, _view_index: int | None = None) list[Table | DetectedTable]#
Detect tables in a specific view.
This method finds tables in the view through three independent branches: 1. tables_from_tables — existing Table annotation instances 2. tables_from_notes — Symbol entities (TypeNote) with a rectangular frame 3. tables_from_geometries — edge-based detection from view geometries
- Parameters:
view – The view to search for tables in
is_background – Whether this is the background view (affects detection strategy)
_view_index – Optional view index for storing intermediate data
- Returns:
List of detected table objects (mix of Table annotations and DetectedTable instances)
- detect_tables_in_background_view() list[Table | DetectedTable]#
Detect tables specifically in the background view.
This is a convenience method that calls detect_view_tables with the background view and appropriate settings for background view processing.
- Returns:
List of detected table objects in the background view
- detect_all_tables() dict[int, list[Table | DetectedTable]]#
Detect all tables in the drawing across all views.
This method processes each view to find tables in three ways: 1. Direct inclusion of existing Table instances from annotations 2. For regular views: Detection from view geometries and annotations 3. For all views: Detection within CompositeEntity objects
The background view is treated specially - only CompositeEntity objects and existing Table instances are processed since tables there are typically pre-structured.
Tables are validated to ensure they have sufficient content before being included.
- Returns:
Dictionary mapping view index to list of validated detected tables
drawing_tools.table.title_block module#
Title block extraction from detected tables.
- class drawing_tools.table.title_block.TitleBlockExtractor(detected_table: DetectedTable, line_tolerance: float = 2.0)#
Bases:
objectExtracts title block information from a DetectedTable.
Uses pattern matching and keyword search to identify fields.
- MIN_TITLE_LENGTH = 5#
- __init__(detected_table: DetectedTable, line_tolerance: float = 2.0)#
Initialize the extractor with a detected table.
- Parameters:
detected_table – The table containing title block information
line_tolerance – Tolerance for grouping text items on the same line
- extract(debug: bool = False) TitleBlock#
Extract title block information from the table.
- Parameters:
debug – If True, print debug information about content ordering
- Returns:
TitleBlock instance with extracted information
drawing_tools.table.utils module#
Utility functions for table detection and text processing.
This module provides sophisticated filtering of line segments based on their spatial density and connectivity patterns, useful for isolating structured elements like tables from scattered individual lines.
- class drawing_tools.table.utils.ConnectivityFilterConfig(threshold_ratio: float = 0.2, use_elliptical: bool = True, std_deviation_factor: float = 1.2, debug_visualization: bool = False, output_path: str = 'connectivity_filter_debug.html')#
Bases:
objectConfiguration for connectivity density filtering.
- Parameters:
threshold_ratio – Base ratio for threshold calculation (0.2 = 20%)
use_elliptical – Use elliptical neighborhoods (True) or rectangular (False)
std_deviation_factor – Multiplier for standard deviation in threshold calculation. Higher values lower the min_neighbors threshold, making the filter more permissive. Formula: min_neighbors = max(1, int(avg - factor * std))
debug_visualization – Enable debug visualization output
output_path – Path for debug visualization file
- class drawing_tools.table.utils.ConnectivityDensityFilter(drawing_width: float, drawing_height: float, config: ConnectivityFilterConfig | None = None)#
Bases:
objectAdvanced connectivity density filter for isolating connected line structures.
This filter analyzes spatial relationships between lines and removes isolated or sparsely connected lines, keeping only densely connected clusters that likely represent structured elements like table grids.
Features: - Adaptive thresholds based on drawing aspect ratio - Elliptical or rectangular neighborhood analysis - Statistical filtering using standard deviation - Comprehensive debug visualization capabilities
- MIN_LINES_FOR_PROCESSING = 3#
- MIN_LINES_FOR_TABLE = 4#
- __init__(drawing_width: float, drawing_height: float, config: ConnectivityFilterConfig | None = None)#
Initialize the connectivity density filter.
- Parameters:
drawing_width – Width of the drawing for threshold calculation
drawing_height – Height of the drawing for threshold calculation
config – Configuration object with filtering parameters
- filter(lines: list[Edge], store_debug_info: bool = False) list[Edge]#
Apply connectivity density filtering to the provided lines.
- Parameters:
lines – List of line edges to filter
store_debug_info – If True, store debug info without generating visualization. Access via
debug_infoproperty after calling this method.
- Returns:
Filtered list of lines with sufficient connectivity density
Module contents#
Table extraction from dessia_drawing package.
- class drawing_tools.table.SheetTableDetector(sheet: Sheet, candidate_preparation_config: CandidatePreparationConfig | None = None, table_generation_config: TableGenerationConfig | None = None, table_selection_config: TableSelectionConfig | None = None, store_detection_data: bool = False)#
Bases:
DessiaObjectDetects and extracts table structures from technical drawing sheets.
- __init__(sheet: Sheet, candidate_preparation_config: CandidatePreparationConfig | None = None, table_generation_config: TableGenerationConfig | None = None, table_selection_config: TableSelectionConfig | None = None, store_detection_data: bool = False)#
Initialize the detector with a sheet.
- Parameters:
sheet – The sheet containing tables.
candidate_preparation_config – Configuration for candidate edge preparation (Phase 1)
table_generation_config – Configuration for table structure detection (Phase 2)
table_selection_config – Configuration for table validation and selection (Phase 3)
store_detection_data – If True, store all intermediate pipeline data for visualization/debugging. Access via
detection_dataproperty after detection.
- property tables: dict[int, list[Table | DetectedTable]]#
All detected tables (computed once on first access).
- Returns:
Dictionary mapping view index to list of detected tables.
- property detection_data: TableDetectionData#
Access stored detection data. Only available when
store_detection_data=True.
- get_title_block_annotations() list[Entity]#
Extract annotations that belong to the title block area.
- get_title_block_table() DetectedTable | None#
Detect the table that represents the title block in the drawing.
- detect_title_block() TitleBlock | None#
Detect the title block and extract structured information.
- detect_view_tables(view: View, is_background: bool = False, _view_index: int | None = None) list[Table | DetectedTable]#
Detect tables in a specific view.
This method finds tables in the view through three independent branches: 1. tables_from_tables — existing Table annotation instances 2. tables_from_notes — Symbol entities (TypeNote) with a rectangular frame 3. tables_from_geometries — edge-based detection from view geometries
- Parameters:
view – The view to search for tables in
is_background – Whether this is the background view (affects detection strategy)
_view_index – Optional view index for storing intermediate data
- Returns:
List of detected table objects (mix of Table annotations and DetectedTable instances)
- detect_tables_in_background_view() list[Table | DetectedTable]#
Detect tables specifically in the background view.
This is a convenience method that calls detect_view_tables with the background view and appropriate settings for background view processing.
- Returns:
List of detected table objects in the background view
- detect_all_tables() dict[int, list[Table | DetectedTable]]#
Detect all tables in the drawing across all views.
This method processes each view to find tables in three ways: 1. Direct inclusion of existing Table instances from annotations 2. For regular views: Detection from view geometries and annotations 3. For all views: Detection within CompositeEntity objects
The background view is treated specially - only CompositeEntity objects and existing Table instances are processed since tables there are typically pre-structured.
Tables are validated to ensure they have sufficient content before being included.
- Returns:
Dictionary mapping view index to list of validated detected tables