Skill detail
drawing-analyzer
Analyzes construction drawings for dimensions, takeoffs, and design review.
Inspect before use
Automated review checks relevance, not safety or endorsement. Read the source instructions before using this skill.
SKILL.md
The saved excerpt is a snapshot from review. The external source remains the complete and most current version.
---
name: "drawing-analyzer"
description: "Analyze construction drawings to extract dimensions, annotations, symbols, and metadata. Support quantity takeoff and design review automation."
homepage: "https://datadrivenconstruction.io"
metadata: {"openclaw": {"emoji": "📑", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}
---
# Drawing Analyzer for Construction
## Overview
Analyze construction drawings (PDF, DWG) to extract dimensions, annotations, symbols, title block data, and support automated quantity takeoff and design review.
## Business Case
Drawing analysis automation enables:
- **Faster Takeoffs**: Extract quantities from drawings
- **Quality Control**: Verify drawing completeness
- **Data Extraction**: Pull metadata for project systems
- **Design Review**: Automated checking against standards
## Technical Implementation
```python
from dataclasses import dataclass, field
from typing import List, Dict, Any, Optional, Tuple
import re
import pdfplumber
from pathlib import Path
@dataclass
class TitleBlockData:
project_name: str
project_number: str
sheet_number: str
sheet_title: str
discipline: str
scale: str
date: str
revision: str
drawn_by: str
checked_by: str
approved_by: str
@dataclass
class Dimension:
value: float
unit: str
dimension_type: str # linear, angular, radial
location: Tuple[float, float]
associated_text: str
@dataclass
class Annotation:
text: str
annotation_type: str # note, callout, tag, keynote
location: Tuple[float, float]
references: List[str]
@dataclass
class Symbol:
symbol_type: str # door, window, equipment, etc.
tag: str
location: Tuple[float, float]
properties: Dict[str, Any]
@dataclass
class DrawingAnalysisResult:
file_name: str
title_block: Optional[TitleBlockData]
dimensions: List[Dimension]
annotations: List[Annotation]
symbols: List[Symbol]
scale_factor: float
drawing_area: Tuple[float, float]
quality_issues: List[str]
class DrawingAnalyzer:
"""Analyze construction drawings for data extraction."""
# Common dimension patterns
DIMENSION_PATTERNS = [
r"(\d+'-\s*\d+(?:\s*\d+/\d+)?\"?)", # Feet-inches: 10'-6", 10' - 6 1/2"
r"(\d+(?:\.\d+)?)\s*(?:mm|cm|m|ft|in)", # Metric/imperial with unit
r"(\d+'-\d+\")", # Compact feet-inches
r"(\d+)\s*(?:SF|LF|CY|EA)", # Quantity dimensions
]
# Common annotation patterns
ANNOTATION_PATTERNS = {
'keynote': r'^\d{1,2}[A-Z]?$', # 1A, 12, 5B
'room_tag': r'^(?:RM|ROOM)\s*\d+',
'door_tag': r'^[A-Z]?\d{2,3}[A-Z]?$',
'grid_line': r'^[A-Z]$|^\d+$',
'elevation': r'^(?:EL|ELEV)\.?\s*\d+',
'detail_ref': r'^\d+/[A-Z]\d+',
}
# Scale patterns
SCALE_PATTERNS = [
r"SCALE:\s*(\d+(?:/\d+)?)\s*[\"']\s*=\s*(\d+)\s*['\-]", # 1/4" = 1'-0"
r"(\d+):(\d+)", # 1:100
r"NTS|NOT TO SCALE",
]
def __init__(self):
self.results: Dict[str, DrawingAnalysisResult] = {}
def analyze_pdf_drawing(self, pdf_path: str) -> DrawingAnalysisResult:
"""Analyze a PDF drawing."""
path = Path(pdf_path)
all_text = ""
dimensions = []
annotations = []
symbols = []
quality_issues = []
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
# Extract text
text = page.extract_text() or ""
all_text += text + "\n"
# Extract dimensions
page_dims = self._extract_dimensions(text)
dimensions.extend(page_dims)
# Extract annotations
page_annots = self._extract_annotations(text)
annotations.extend(page_annots)
# Extract from tables (often contain schedules)
tables = page.extract_tables()
Read the full source on GitHub (opens external page)