Skill 詳細

bim-qto

Generates BIM quantity takeoffs for construction cost estimation.

一致度直接一致建設 向けにレビュー済み
出典datadrivenconstruction/ddc_skills_for_ai_agents_in_construction外部ソース
報告インストール数118人気度の参考値

使用前に確認

自動レビューは関連性のみを確認し、安全性や推奨を保証しません。使用前に出典の説明を読んでください。

保存された出典プレビュー

SKILL.md

これはレビュー時に保存された抜粋です。完全で最新の内容は外部ソースを確認してください。

---
name: "bim-qto"
description: "Extract quantities from BIM/CAD data for cost estimation. Group by type, level, zone. Generate QTO reports."
homepage: "https://datadrivenconstruction.io"
metadata: {"openclaw": {"emoji": "⚡", "os": ["win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}
---
# BIM Quantity Takeoff

## Overview
Quantity Takeoff (QTO) extracts measurable quantities from BIM models. This skill processes BIM exports to generate grouped quantity reports for cost estimation.

## Python Implementation

```python
import pandas as pd
import numpy as np
from typing import Dict, Any, List, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum


class QTOUnit(Enum):
    """Quantity takeoff measurement units."""
    COUNT = "ea"
    LENGTH = "m"
    AREA = "m2"
    VOLUME = "m3"
    WEIGHT = "kg"
    LINEAR_FOOT = "lf"
    SQUARE_FOOT = "sf"
    CUBIC_YARD = "cy"


@dataclass
class QTOItem:
    """Single QTO line item."""
    category: str
    type_name: str
    description: str
    quantity: float
    unit: str
    level: Optional[str] = None
    material: Optional[str] = None
    element_count: int = 0


@dataclass
class QTOReport:
    """Complete QTO report."""
    project_name: str
    items: List[QTOItem]
    total_elements: int
    categories: int
    generated_date: str


class BIMQuantityTakeoff:
    """Extract quantities from BIM data."""

    # Column mappings for different BIM exports
    COLUMN_MAPPINGS = {
        'type': ['Type Name', 'TypeName', 'type_name', 'Family and Type', 'IfcType'],
        'category': ['Category', 'category', 'IfcClass', 'Element Category'],
        'level': ['Level', 'level', 'Building Storey', 'BuildingStorey', 'Floor'],
        'volume': ['Volume', 'volume', 'Volume (m³)', 'Qty_Volume'],
        'area': ['Area', 'area', 'Surface Area', 'Area (m²)', 'Qty_Area'],
        'length': ['Length', 'length', 'Length (m)', 'Qty_Length'],
        'count': ['Count', 'count', 'Quantity', 'ElementCount'],
        'material': ['Material', 'material', 'Structural Material', 'MaterialName']
    }

    def __init__(self, df: pd.DataFrame):
        """Initialize with BIM data DataFrame."""
        self.df = df
        self.column_map = self._detect_columns()

    def _detect_columns(self) -> Dict[str, str]:
        """Detect which columns exist in data."""
        mapping = {}

        for standard, variants in self.COLUMN_MAPPINGS.items():
            for variant in variants:
                if variant in self.df.columns:
                    mapping[standard] = variant
                    break

        return mapping

    def get_column(self, standard_name: str) -> Optional[str]:
        """Get actual column name from standard name."""
        return self.column_map.get(standard_name)

    def group_by_type(self, sum_column: str = 'volume') -> pd.DataFrame:
        """Group quantities by type name."""

        type_col = self.get_column('type')
        qty_col = self.get_column(sum_column)

        if type_col is None:
            raise ValueError("Type column not found")

        if qty_col is None:
            # Fall back to count
            result = self.df.groupby(type_col).size().reset_index(name='count')
        else:
            result = self.df.groupby(type_col).agg({
                qty_col: 'sum'
            }).reset_index()
            result['count'] = self.df.groupby(type_col).size().values

        result.columns = ['Type', 'Quantity', 'Count'] if len(result.columns) == 3 else ['Type', 'Count']
        return result.sort_values('Count', ascending=False)

    def group_by_category(self, sum_column: str = 'volume') -> pd.DataFrame:
        """Group quantities by category."""

        cat_col = self.get_column('category')
        qty_col = self.get_column(sum_column)

        if cat_col is None:
            raise ValueError("Category column not found")

        agg_dict = {}
        if qty_col:
            agg_dict[qty_col
GitHub で全文を読む (外部ページ)
関連情報

関連する仕事