Room & Space Export

Extract room schedules and spatial data from Revit models.

Workflow Overview

Input

Revit Model
with Rooms

Processing
Translate to SVF2
Extract Properties
Filter by Category
Revit Rooms
Room Data
Name
Number
Area
Level
Department
Export Formats
CSV Schedule
JSON Export
Database Import
InputProcessDataExport

CLI Approach

Step 1: Translate Model

URN=$(raps object urn my-bucket building.rvt --output plain)
raps translate start "$URN" --format svf2 --wait

Step 2: Extract All Properties

raps derivative properties "$URN" --output json > all-properties.json

Step 3: Filter Rooms

cat all-properties.json | jq '[.[] | select(.category == "Revit Rooms")]' > rooms.json

Step 4: Export to CSV

cat rooms.json | jq -r '
  ["Name", "Number", "Area", "Level", "Department"],
  (.[] | [
    .properties["Name"] // "",
    .properties["Number"] // "",
    .properties["Area"] // "",
    .properties["Level"] // "",
    .properties["Department"] // ""
  ]) | @csv
' > rooms.csv

Step 5: Generate Summary

echo "Room Summary"
echo "============"
echo "Total rooms: $(jq 'length' rooms.json)"
echo "Total area: $(jq '[.[].properties.Area | select(. != null) | tonumber] | add' rooms.json) sq ft"
echo ""
echo "By Level:"
jq -r 'group_by(.properties.Level) | .[] | "  \(.[0].properties.Level): \(length) rooms"' rooms.json
echo ""
echo "By Department:"
jq -r 'group_by(.properties.Department) | .[] | "  \(.[0].properties.Department // "Unassigned"): \(length) rooms"' rooms.json

CI/CD Pipeline

# .github/workflows/room-export.yml
name: Room Schedule Export

on:
  workflow_dispatch:
    inputs:
      bucket:
        description: 'Bucket name'
        required: true
      model:
        description: 'Model filename'
        required: true

jobs:
  export-rooms:
    runs-on: ubuntu-latest
    steps:
      - name: Install RAPS
        run: cargo install raps

      - name: Extract room data
        env:
          APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }}
          APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }}
        run: |
          URN=$(raps object urn "${{ inputs.bucket }}" "${{ inputs.model }}" --output plain)

          # Get all properties
          raps derivative properties "$URN" --output json > properties.json

          # Filter rooms
          jq '[.[] | select(.category == "Revit Rooms")]' properties.json > rooms.json

          # Create CSV
          jq -r '
            ["Name","Number","Area","Level","Department"],
            (.[] | [
              .properties["Name"],
              .properties["Number"],
              .properties["Area"],
              .properties["Level"],
              .properties["Department"]
            ]) | @csv
          ' rooms.json > rooms.csv

      - name: Generate summary report
        run: |
          echo "# Room Schedule Export" > summary.md
          echo "Model: ${{ inputs.model }}" >> summary.md
          echo "Date: $(date)" >> summary.md
          echo "" >> summary.md
          echo "## Statistics" >> summary.md
          echo "- Total Rooms: $(jq 'length' rooms.json)" >> summary.md
          echo "" >> summary.md
          echo "## By Level" >> summary.md
          jq -r 'group_by(.properties.Level) | .[] | "- \(.[0].properties.Level): \(length) rooms"' rooms.json >> summary.md
          echo "" >> summary.md
          echo "## By Department" >> summary.md
          jq -r 'group_by(.properties.Department) | .[] | "- \(.[0].properties.Department // "Unassigned"): \(length) rooms"' rooms.json >> summary.md

      - name: Upload exports
        uses: actions/upload-artifact@v4
        with:
          name: room-schedule
          path: |
            rooms.json
            rooms.csv
            summary.md

Pipeline Flow

Manual Trigger
bucket + model inputs
Extraction
Get URN
Get Properties
Filter Rooms
Export
rooms.json
rooms.csv
summary.md
Output
room-schedule.zip

MCP Integration

Export Room Schedule

User: "Get me a room schedule from the office building model with areas by department"
User
AI Assistant
RAPS MCP
APS Cloud
Export room schedule by department
aps_object_urn()
URN
aps_derivative_properties()
Get all properties
Properties JSON
Filter rooms, group by department
Room schedule table

AI Response:

Room Schedule for Office Building:

DepartmentRoomsTotal Area (sq ft)
Executive84,200
Engineering2412,800
Sales168,400
HR62,100
Common126,500

Total: 66 rooms, 34,000 sq ft

Find Specific Rooms

User: "Find all conference rooms larger than 500 sq ft"

AI Response:

Found 8 conference rooms over 500 sq ft:

NameNumberAreaLevel
Board Room3011,2003
Conference A2018002
Conference B2027502
Training Room1056501

Advanced Queries

Rooms by Level with Areas

cat rooms.json | jq '
  group_by(.properties.Level) |
  map({
    level: .[0].properties.Level,
    count: length,
    totalArea: ([.[].properties.Area | select(. != null) | tonumber] | add),
    rooms: [.[] | {name: .properties.Name, number: .properties.Number, area: .properties.Area}]
  })'

Find Unassigned Rooms

cat rooms.json | jq '[.[] | select(.properties.Department == null or .properties.Department == "")]'

Area Statistics

cat rooms.json | jq '
  {
    total: ([.[].properties.Area | select(. != null) | tonumber] | add),
    average: ([.[].properties.Area | select(. != null) | tonumber] | add / length),
    min: ([.[].properties.Area | select(. != null) | tonumber] | min),
    max: ([.[].properties.Area | select(. != null) | tonumber] | max)
  }'

Export for Space Management System

cat rooms.json | jq '[.[] | {
  id: .objectid,
  name: .properties.Name,
  number: .properties.Number,
  level: .properties.Level,
  department: .properties.Department,
  area_sqft: (.properties.Area | tonumber),
  area_sqm: ((.properties.Area | tonumber) * 0.0929)
}]' > space-management-import.json