Skip to main content

Level of Detail (LOD) Classification Reference

Comprehensive guide to LOD2 and LOD3 building classification systems for architectural analysis and 3D modeling.


🎯 Overview​

Level of Detail (LOD) classification enables detailed building analysis from LiDAR point clouds. This library implements:

  • LOD2: Building-focused taxonomy (15 classes) - Roof structures and major elements
  • LOD3: Extended architectural taxonomy (30 classes) - Detailed facade elements
  • ASPRS Integration: Automatic mapping from ASPRS classes
  • ML-Ready: Optimized for deep learning applications

πŸ“ LOD Levels Explained​

LOD Hierarchy​

LevelDescriptionComplexityUse Cases
LOD02D footprintLowUrban planning, GIS
LOD1Extruded blocksLowCity-scale visualization
LOD2Roof structuresMediumSolar analysis, this library
LOD3Facade detailsHighHeritage documentation, this library
LOD4Interior spacesVery HighIndoor navigation

πŸ—οΈ LOD2 Classification (15 Classes)​

Overview​

LOD2 focuses on building structures with simplified architectural elements:

  • Target: Roof shapes, major building components
  • Classes: 15 classes (0-14)
  • Applications: Solar potential, urban modeling, roof type analysis
  • Point Density: Optimized for standard LiDAR (10-20 pts/mΒ²)

Class Taxonomy​

Structural Elements​

ClassNameCodeDescription
0wall0Wall surfaces (vertical)

Roof Types​

ClassNameCodeDescription
1roof_flat1Flat roofs (< 5Β° slope)
2roof_gable2Gable/pitched roofs
3roof_hip3Hip roofs (4+ slopes)

Roof Details​

ClassNameCodeDescription
4chimney4Chimney structures
5dormer5Dormer windows

Facade Elements​

ClassNameCodeDescription
6balcony6Balconies, terraces
7overhang7Roof overhangs, eaves

Foundation​

ClassNameCodeDescription
8foundation8Building base, foundation

Context (Non-Building)​

ClassNameCodeDescription
9ground9Ground surface
10vegetation_low10Low vegetation (< 2m)
11vegetation_high11High vegetation (trees)
12water12Water surfaces
13vehicle13Vehicles, mobile objects
14other14Unclassified/other

Configuration​

# config.yaml (V5) - LOD2 Mode
classification:
mode: lod2 # Enable LOD2 classification

# LOD2-specific parameters
lod2:
roof_slope_threshold: 5.0 # degrees (flat vs pitched)
wall_verticality: 0.85 # Vertical surface threshold
chimney_height_min: 1.0 # meters
dormer_protrusion: 0.5 # meters
balcony_protrusion: 0.8 # meters

# ASPRS β†’ LOD2 mapping
asprs_to_lod2:
enabled: true
auto_refine_buildings: true # Refine Class 6 β†’ wall/roof

Python API​

from ign_lidar.classes import LOD2_CLASSES, ASPRS_TO_LOD2
import numpy as np

# Convert ASPRS classes to LOD2
asprs_classes = las.classification
lod2_classes = np.array([ASPRS_TO_LOD2.get(c, 14) for c in asprs_classes])

# Get class statistics
for class_id, class_name in LOD2_CLASSES.items():
count = np.sum(lod2_classes == class_id)
if count > 0:
print(f"{class_name:20s}: {count:8d} points")

🎨 LOD3 Classification (30 Classes)​

Overview​

LOD3 provides detailed architectural classification including facade elements:

  • Target: Windows, doors, architectural details
  • Classes: 30 classes (0-29)
  • Applications: Heritage documentation, detailed 3D modeling, facade analysis
  • Point Density: Requires high-density LiDAR (20-50 pts/mΒ²)

Class Taxonomy​

Structural Elements (Walls)​

ClassNameCodeDescription
0wall_plain0Plain wall surface
1wall_with_windows1Wall with window openings
2wall_with_door2Wall with door openings

Roof Types (Detailed)​

ClassNameCodeDescription
3roof_flat3Flat roof (< 5Β°)
4roof_gable4Gable/pitched roof
5roof_hip5Hip roof (4 slopes)
6roof_mansard6Mansard roof (French style)
7roof_gambrel7Gambrel roof (barn style)

Roof Details​

ClassNameCodeDescription
8chimney8Chimney structures
9dormer_gable9Gable dormer windows
10dormer_shed10Shed dormer windows
11skylight11Roof skylights
12roof_edge12Roof edges, gutters

Openings​

ClassNameCodeDescription
13window13Window openings
14door14Door openings
15garage_door15Garage door openings

Facade Elements​

ClassNameCodeDescription
16balcony16Balconies, terraces
17balustrade17Railings, balustrades
18overhang18Roof overhangs
19pillar19Pillars, columns
20cornice20Cornices, moldings

Foundation​

ClassNameCodeDescription
21foundation21Building foundation
22basement_window22Basement windows

Context (Non-Building)​

ClassNameCodeDescription
23ground23Ground surface
24vegetation_low24Low vegetation
25vegetation_high25Trees, tall vegetation
26water26Water surfaces
27vehicle27Vehicles
28street_furniture28Street furniture
29other29Unclassified

Configuration​

# config.yaml (V5) - LOD3 Mode
classification:
mode: lod3 # Enable LOD3 classification

# LOD3-specific parameters
lod3:
# Roof classification
roof_slope_threshold: 5.0
mansard_slope_break: 30.0 # degrees
gambrel_slope_break: 45.0

# Wall classification
wall_verticality: 0.85
window_depth: 0.15 # meters (recess)
door_height_min: 1.8 # meters

# Facade elements
balcony_protrusion: 0.8 # meters
pillar_radius: 0.3 # meters
cornice_height: 0.2 # meters

# Detail detection
min_feature_size: 0.1 # meters
point_density_required: 20 # pts/mΒ²

Python API​

from ign_lidar.classes import LOD3_CLASSES, ASPRS_TO_LOD3

# Convert ASPRS to LOD3
lod3_classes = np.array([ASPRS_TO_LOD3.get(c, 29) for c in asprs_classes])

# Refine building points (Class 6) with geometric analysis
from ign_lidar.preprocessing.classification_refinement import refine_lod3_buildings

lod3_refined = refine_lod3_buildings(
points=points,
initial_classes=lod3_classes,
point_density=25.0, # pts/mΒ²
detect_windows=True,
detect_doors=True,
detect_balconies=True
)

πŸ”„ Class Mapping Tables​

ASPRS β†’ LOD2 Mapping​

ASPRS_TO_LOD2 = {
0: 14, # Never classified β†’ other
1: 14, # Unclassified β†’ other
2: 9, # Ground β†’ ground
3: 10, # Low Vegetation β†’ vegetation_low
4: 10, # Medium Vegetation β†’ vegetation_low
5: 11, # High Vegetation β†’ vegetation_high
6: 0, # Building β†’ wall (requires refinement)
7: 10, # Low Point (noise) β†’ vegetation_low
9: 12, # Water β†’ water
10: 14, # Rail β†’ other
11: 14, # Road Surface β†’ other
17: 13, # Bridge Deck β†’ vehicle
18: 11, # High Noise β†’ vegetation_high
67: 14, # Unknown β†’ other
}

ASPRS β†’ LOD3 Mapping​

ASPRS_TO_LOD3 = {
0: 29, # Never classified β†’ other
1: 29, # Unclassified β†’ other
2: 23, # Ground β†’ ground
3: 24, # Low Vegetation β†’ vegetation_low
4: 24, # Medium Vegetation β†’ vegetation_low
5: 25, # High Vegetation β†’ vegetation_high
6: 0, # Building β†’ wall_plain (requires refinement)
7: 24, # Low Point (noise) β†’ vegetation_low
9: 26, # Water β†’ water
10: 29, # Rail β†’ other
11: 23, # Road Surface β†’ ground
17: 27, # Bridge Deck β†’ vehicle
18: 25, # High Noise β†’ vegetation_high
67: 29, # Unknown β†’ other
}

LOD2 β†’ LOD3 Mapping​

LOD2_TO_LOD3 = {
0: 0, # wall β†’ wall_plain
1: 3, # roof_flat β†’ roof_flat
2: 4, # roof_gable β†’ roof_gable
3: 5, # roof_hip β†’ roof_hip
4: 8, # chimney β†’ chimney
5: 9, # dormer β†’ dormer_gable
6: 16, # balcony β†’ balcony
7: 18, # overhang β†’ overhang
8: 21, # foundation β†’ foundation
9: 23, # ground β†’ ground
10: 24, # vegetation_low β†’ vegetation_low
11: 25, # vegetation_high β†’ vegetation_high
12: 26, # water β†’ water
13: 27, # vehicle β†’ vehicle
14: 29, # other β†’ other
}

🎯 Classification Workflow​

LOD2 Workflow​

LOD3 Workflow​


πŸ“Š Use Cases​

LOD2 Applications​

  1. Solar Potential Analysis

    • Roof type identification
    • Slope calculation
    • Area estimation
  2. Urban Morphology

    • Building type classification
    • Roof shape distribution
    • Urban pattern analysis
  3. 3D City Models

    • CityGML LOD2 generation
    • Simplified visualization
    • Performance-optimized models

LOD3 Applications​

  1. Heritage Documentation

    • Detailed facade capture
    • Architectural element inventory
    • Historical building analysis
  2. Facade Analysis

    • Window-to-wall ratio
    • Architectural style detection
    • Ornament classification
  3. Detailed 3D Modeling

    • CityGML LOD3 generation
    • Textured building models
    • Virtual reality applications

βš™οΈ Processing Modes​

LOD2 Processing​

# Process tiles in LOD2 mode
ign-lidar-hd process \
--config-name lod2_classification \
input_dir=data/tiles/ \
output_dir=output/lod2/ \
classification.mode=lod2

LOD3 Processing​

# Process tiles in LOD3 mode (requires high-density data)
ign-lidar-hd process \
--config-name lod3_classification \
input_dir=data/tiles_hd/ \
output_dir=output/lod3/ \
classification.mode=lod3 \
classification.lod3.min_point_density=20

Adaptive Mode​

# Automatically choose LOD2 or LOD3 based on point density
classification:
mode: adaptive

adaptive:
lod3_density_threshold: 20.0 # pts/mΒ²
lod2_density_threshold: 10.0
fallback_to_asprs: true # Use ASPRS if density < 10

πŸ’» Advanced Python API​

LOD Classification with Refinement​

from ign_lidar.preprocessing.classification_refinement import (
refine_lod2_buildings,
refine_lod3_buildings
)

# Load point cloud
las = laspy.read("tile.laz")
points = np.column_stack([las.x, las.y, las.z])
asprs_classes = las.classification

# Initial conversion
lod2_classes = np.array([ASPRS_TO_LOD2.get(c, 14) for c in asprs_classes])

# Refine with geometric analysis
lod2_refined = refine_lod2_buildings(
points=points,
classes=lod2_classes,
compute_normals=True,
detect_roof_types=True,
detect_chimneys=True,
detect_dormers=True
)

# Further refine to LOD3 if density sufficient
point_density = estimate_point_density(points)
if point_density > 20.0:
lod3_refined = refine_lod3_buildings(
points=points,
classes=lod2_refined,
detect_windows=True,
detect_doors=True,
detect_balconies=True,
detect_cornices=True
)

Export Class Statistics​

from ign_lidar.classes import LOD3_CLASSES

def print_lod3_statistics(classes):
"""Print detailed LOD3 class statistics."""
print("\n=== LOD3 Classification Report ===\n")

# Group by category
categories = {
'Walls': [0, 1, 2],
'Roofs': [3, 4, 5, 6, 7],
'Roof Details': [8, 9, 10, 11, 12],
'Openings': [13, 14, 15],
'Facade': [16, 17, 18, 19, 20],
'Foundation': [21, 22],
'Context': [23, 24, 25, 26, 27, 28, 29]
}

for category, class_ids in categories.items():
print(f"\n{category}:")
for class_id in class_ids:
if class_id in LOD3_CLASSES.values():
class_name = [k for k, v in LOD3_CLASSES.items() if v == class_id][0]
count = np.sum(classes == class_id)
if count > 0:
pct = 100 * count / len(classes)
print(f" {class_name:20s}: {count:8d} pts ({pct:5.2f}%)")

print_lod3_statistics(lod3_refined)

πŸ“š See Also​


πŸ’‘ Best Practices​

LOD2​

  1. Check point density - Requires at least 10 pts/mΒ²
  2. Compute normals accurately - Essential for roof type detection
  3. Validate roof slopes - Verify against architectural standards
  4. Use building masks - Focus refinement on building points

LOD3​

  1. Verify high density - Requires 20+ pts/mΒ²
  2. Enable all refinements - Window, door, balcony detection
  3. Tune thresholds - Adjust for regional architectural styles
  4. Post-process results - Manual verification recommended
  5. Consider computational cost - LOD3 is 5-10x slower than LOD2

General​

  1. Start with LOD2 - Simpler, faster, more robust
  2. Use adaptive mode - Automatically choose based on data quality
  3. Validate outputs - Check with QGIS or CloudCompare
  4. Document parameters - Keep track of thresholds used
  5. Test on samples - Validate before batch processing

Standards: CityGML LOD2/LOD3, ASPRS LAS 1.4
Updated: October 17, 2025 - V5 Configuration