π οΈ Troubleshooting & Tips¶
π§ Master Problem-Solving Guide
Overcome common challenges and optimize your building height extraction workflow
π¨ Common Issues and Solutions¶
ποΈ Building Visualization Problems¶
#### β οΈ **Buildings appear stretched or distorted in 2.5D view**
**π Verify Height Units:**
**βοΈ Adjust Vertical Scale:**
- In 2.5D symbology, set height scale factor to 0.3048 if data is in feet
- For dramatic effect, use scale factor 2-3x
- For realistic view, use scale factor 1.0x
π― Root Causes
- Coordinate System Issues: Data in geographic (lat/lon) instead of projected coordinates
- Height Unit Mismatch: Heights in feet instead of meters
- Scale Factor Problems: Vertical exaggeration set incorrectly
- CRS Inconsistency: Layers using different coordinate reference systems
β Solutions
**πΊοΈ Fix Coordinate System:**-- In QGIS, reproject to local UTM zone
Project β Properties β CRS β Search for "UTM Zone [XX]N"
-- Example for Ghana: EPSG:32630 (UTM Zone 30N)
# Check height statistics in Python console
layer = iface.activeLayer()
heights = [f['height'] for f in layer.getFeatures() if f['height'] is not None]
print(f"Min height: {min(heights):.2f}")
print(f"Max height: {max(heights):.2f}")
print(f"Average height: {sum(heights)/len(heights):.2f}")
# Typical residential buildings: 3-15m
# If values are 10-50, might be in feet
π Data Quality Issues¶
#### β οΈ **Missing or NULL height values**
**π§ Method 2: Conditional Defaults**
**π§ Method 3: Spatial Interpolation**
π Diagnosis Steps
1. **π Check Attribute Table:** 2. **π― Verify Building Presence:** 3. **π Statistical Analysis:**π οΈ Fix Strategies
**π§ Method 1: Default Value Assignment**-- In Field Calculator, create new field 'height_clean'
COALESCE("height", 5) -- Use 5m default for NULL values
π Earth Engine and Download Issues¶
#### β οΈ **Google Earth Engine timeout or memory errors**
**π Process Smaller Areas:**
**β‘ Use Pyramid Policy:**
π« Common Error Messages
User memory limit exceeded
Computation timed out
Too many concurrent aggregations
Image.reduceRegions: Tile error
π‘ Optimization Solutions
**π― Reduce Processing Scale:**// Instead of scale: 4, try larger values
Export.image.toDrive({
image: buildingHeights.clip(geometry),
scale: 8, // or 16 for testing
maxPixels: 1e9, // Increase pixel limit
tileScale: 16 // Reduce memory per tile
});
// Split large areas into smaller chunks
var bounds = geometry.bounds();
var xSize = bounds.coordinates().get(0).get(2).get(0)
.subtract(bounds.coordinates().get(0).get(0).get(0));
var ySize = bounds.coordinates().get(0).get(2).get(1)
.subtract(bounds.coordinates().get(0).get(0).get(1));
// Create grid of smaller areas
var gridSize = 0.01; // Degrees
// Process each grid cell separately
π Python Download and Processing Issues¶
#### β οΈ **gsutil authentication and download problems**
**Memory Issues with Large Files:**
π Authentication Issues
**Error:** `AccessDeniedException: 403 Forbidden` **Solutions:** **Error:** `gsutil: command not found` **Solutions:**π¦ Python Package Issues
**Error:** `ModuleNotFoundError: No module named 'rasterio'` **Solutions:**# Create isolated environment
python -m venv building_env
source building_env/bin/activate # Linux/Mac
# OR
building_env\Scripts\activate # Windows
# Install with specific versions
pip install rasterio==1.3.8 geopandas==0.13.2
pip install google-cloud-storage matplotlib
# Fix GDAL issues (common on Windows)
pip install GDAL --find-links https://www.lfd.uci.edu/~gohlke/pythonlibs/
# Process in chunks for large rasters
import rasterio
from rasterio.windows import Window
def process_large_raster_chunked(filepath, chunk_size=1000):
with rasterio.open(filepath) as src:
height, width = src.height, src.width
for row in range(0, height, chunk_size):
for col in range(0, width, chunk_size):
window = Window(col, row,
min(chunk_size, width - col),
min(chunk_size, height - row))
chunk = src.read(window=window)
# Process chunk here
yield chunk
π Performance Optimization¶
β‘ QGIS Performance Tuning¶
π₯οΈ System Settings
- Memory: Settings β Options β System β Memory: Set to 75% of RAM
- CPU: Enable multi-threading in Processing settings
- Graphics: Enable OpenGL rendering in Advanced settings
- Cache: Increase tile cache size to 100-500MB
π Layer Optimization
- Indexes: Create spatial indexes for vector layers
- Pyramids: Build overviews for large rasters
- Simplification: Use scale-dependent rendering
- Formats: Use GeoPackage instead of Shapefile
ποΈ Data Management Best Practices¶
#### π **File Organization**
#### πΎ **Storage Optimization**
π building_heights_project/
βββ π data/
β βββ π’ raw/ # Original downloads
β βββ π processed/ # Cleaned data
β βββ π― analysis/ # Analysis results
βββ πΊοΈ qgis_projects/ # QGIS project files
βββ π outputs/ # Final maps and exports
β βββ πΌοΈ images/ # PNG, JPG exports
β βββ π documents/ # PDF reports
β βββ π web/ # Web exports
βββ π documentation/ # Metadata and notes
π Temporal Data Inconsistencies¶
β° Handling Multi-Year Variations¶
#### π **Year Selection Strategy**
1. **π― Data Quality Assessment:**
2. **π Multi-Year Averaging:**
# Analyze data quality across years
years = [2019, 2020, 2021, 2022, 2023]
quality_scores = {}
for year in years:
# Load data for each year
valid_buildings = count_valid_heights(year)
cloud_coverage = get_cloud_coverage(year)
# Calculate quality score
quality_scores[year] = valid_buildings * (1 - cloud_coverage)
best_year = max(quality_scores, key=quality_scores.get)
print(f"Best data quality: {best_year}")
-- Create averaged heights across multiple years
SELECT
building_id,
AVG(height) as avg_height,
STDDEV(height) as height_variability,
COUNT(*) as year_count
FROM building_temporal_data
WHERE height IS NOT NULL AND building_presence > 0.5
GROUP BY building_id
HAVING COUNT(*) >= 3 -- At least 3 years of data
π Spatial Misalignment Fixes¶
#### π§ **Building Matching Across Years**
# Python script for spatial matching
import geopandas as gpd
from shapely.geometry import Point, Polygon
def match_buildings_across_years(buildings_2019, buildings_2023, tolerance=5):
"""
π― Match buildings across different years using spatial proximity
"""
matched_pairs = []
for idx_2023, building_2023 in buildings_2023.iterrows():
centroid_2023 = building_2023.geometry.centroid
# Find nearby buildings from 2019
distances = buildings_2019.geometry.centroid.distance(centroid_2023)
closest_idx = distances.idxmin()
closest_distance = distances.min()
if closest_distance < tolerance: # Within tolerance meters
matched_pairs.append({
'id_2019': closest_idx,
'id_2023': idx_2023,
'distance': closest_distance,
'height_2019': buildings_2019.loc[closest_idx, 'height'],
'height_2023': building_2023['height']
})
return pd.DataFrame(matched_pairs)
π Expert Tips and Tricks¶
π‘ Advanced Workflow Optimizations¶
β‘ Speed Hacks
- π― Batch Processing: Process multiple countries simultaneously
- π Automation: Use QGIS Model Builder for repeated tasks
- πΎ Caching: Save intermediate results to avoid recomputation
- βοΈ Parallel Processing: Use multiprocessing for Python scripts
π¨ Quality Improvements
- π Multi-Source Validation: Compare with OpenStreetMap data
- π Statistical Filtering: Remove outliers using IQR method
- π Local Knowledge: Validate against known landmarks
- π Trend Analysis: Use temporal patterns for validation
π οΈ Tool Integration
- πΊοΈ QGIS + PostGIS: For large-scale database operations
- π Python + R: Combine processing with statistical analysis
- π Web Integration: Create online dashboards with Leaflet
- π± Mobile Sync: Use QField for field validation
π Debugging Checklist¶
#### β
**Pre-Processing Checklist**
- [ ] **π CRS Consistency:** All layers use same coordinate system
- [ ] **π Data Validity:** No NULL or negative height values
- [ ] **π Unit Verification:** Heights in meters, not feet
- [ ] **π― Quality Filter:** Building presence > 0.5
- [ ] **π Geometry Validity:** No invalid or self-intersecting polygons
#### β
**Processing Checklist**
- [ ] **πΎ Sufficient Memory:** At least 8GB RAM for large areas
- [ ] **β° Timeout Settings:** Increased for large exports
- [ ] **π§ Scale Appropriateness:** Balance between detail and performance
- [ ] **π Output Validation:** Sample outputs match expectations
- [ ] **ποΈ Backup Strategy:** Save intermediate results
#### β
**Post-Processing Checklist**
- [ ] **π¨ Visualization Quality:** Colors and styles appropriate
- [ ] **π Statistical Validation:** Heights within expected ranges
- [ ] **πΊοΈ Spatial Accuracy:** Buildings align with satellite imagery
- [ ] **π± Export Compatibility:** Files work in target applications
- [ ] **π Documentation:** Methods and parameters recorded
π Troubleshooting Master!
You're now equipped to solve any building height extraction challenge!