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
Input→Process→Data→Export

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