MCDR 2026 – Deliverables QC Checker¶
Overview¶
An automated quality-control tool that validates a complete MCDR 2026 drone-survey deliverables folder against a multi-section QC checklist — covering raster metadata, shapefile attributes, UTM consistency, RMSE reports, drone logs, GCP counts, and annexure cross-checks. Built to replace a manual review process that was slow, error-prone, and generated unnecessary back-and-forth with the survey team before regulatory submission.
- Study Area: Mine survey deliverables (MCDR 2026 specification)
Methods & Tools¶
Data Sources¶
- Drone-survey deliverables folder (Orthomosaic, DSM/DTM, GCP shapefiles, RMSE report, drone log, annexure)
- MCDR 2026 QC checklist specification
Processing Steps¶
- Auto-install any missing Python dependencies at startup
- Accept a deliverables folder path and mine name as inputs
- Run 60–80+ checks sequentially across 10 QC sections
- Stream live results to the terminal with colour-coded PASS / FAIL / WARN / INFO statuses
- Auto-rename any files with incorrect naming conventions
- Cross-check GCP counts, RMSE values, and annexure figures for consistency
- Write a formatted Word document report with a full results table and a FAIL-only summary
Tools Used¶
| Tool | Purpose |
|---|---|
rasterio |
Read orthomosaic and DEM (DSM/DTM) raster metadata |
geopandas |
Parse and validate GCP and map shapefiles |
pandas |
Read Excel GCP tables with auto header detection |
pdfplumber |
Extract values from RMSE PDF reports |
python-docx |
Generate the Word QC report with colour-coded rows |
rich |
Live terminal progress panel with section tracker |
colorama |
Coloured terminal output for the full results log |
openpyxl |
Read .xlsx GCP and annexure files |
Setup¶
# All dependencies are auto-installed at startup — no manual pip install needed.
# Run the script directly:
#
# python mcdr_qc_checker.py
#
# You will be prompted for:
# 1. Path to the MCDR deliverables folder
# 2. Mine name (used to validate expected file names)
import rasterio
import geopandas as gpd
import pandas as pd
import pdfplumber
from docx import Document
from rich.console import Console
Data¶
The script validates a deliverables folder with the following expected structure:
/
├── 1_Orthomosaic/
│ └── 1__Orthomosaic_MCDR2026.tif
├── 2_DEM/
│ ├── 2a__DSM_MCDR2026.tif
│ └── 2b__DTM_MCDR2026.tif
├── 3_GCPs/
│ ├── GCPs/ (shapefiles + Excel)
│ └── Permanent GCPs/
├── 4_RMSE_Report/ (.pdf)
├── 5_MapShapefiles/ (.shp + sidecars)
├── 6_LBP/
├── 7_DroneLogReport/
└── 8_Annexure/
QC specification constants¶
EXPECTED_ALTITUDE_M = 120 # drone flight altitude
EXPECTED_GSD_CM = 3.5 # ground sampling distance
EXPECTED_FRONT_OVERLAP = 80 # % front overlap
EXPECTED_SIDE_OVERLAP = 70 # % side overlap
EXPECTED_ORTHO_RES_CM = 3.5 # orthomosaic resolution
EXPECTED_DEM_RES_CM = 15 # DSM / DTM resolution
MIN_GCPS_PER_100HA = 5 # minimum GCP density
SURVEY_CUTOFF_DATE = 2026-03-31 # survey must post-date this
Analysis¶
QC Sections¶
The script runs checks across 10 sections in sequence:
_SECTIONS = [
"1. Orthomosaic",
"2. DEM (DSM/DTM)",
"3. GCPs",
"4. RMSE Report",
"5. Map Shapefiles",
"6. Lease Boundary Pillars",
"7. Drone Log Report",
"8. Annexure",
"GCP Screenshots",
"UTM Consistency",
]
Raster Validation (Orthomosaic & DEM)¶
For each raster file the script checks:
- File naming matches the expected convention (
{section}_{MineName}_{type}_MCDR2026.tif) - Data type:
uint8for orthomosaic,float32for DSM/DTM - Band count: 4 bands (RGBI) for orthomosaic, 1 band for elevation rasters
- Pixel resolution ≤ specification threshold
- CRS is a valid UTM zone (EPSG 32601–32660 or 32701–32760)
- DTM minimum elevation ≤ DSM minimum elevation (sanity check)
def check_raster_common(report, section, path, meta,
expected_dtype, expected_bands, max_res_cm):
# dtype, band count, resolution, UTM CRS checks
...
GCP Validation¶
GCP_REQUIRED_FIELDS = [
"Name", "Lat", "Long", "Easting", "Northing",
"DMS_Lat", "DMS_Long", "Elevation", "Remarks"
]
# Minimum GCP density enforced relative to mine lease area
min_gcps = math.ceil(MIN_GCPS_PER_100HA * mlb_area_ha / 100)
If column names in the shapefile or Excel file don't exactly match the required fields, the script pauses the live display and prompts the user to approve or reject the discrepancy — preserving human judgement without halting the full run.
UTM Consistency¶
After all sections complete, the script cross-checks every spatial file's UTM zone against each other and flags any mismatch:
def check_overall_utm(report: QCReport) -> None:
zones = set(report.utm_zones_seen.values())
if len(zones) == 1:
report.add("UTM Consistency", "All files same zone", "PASS", ...)
else:
report.add("UTM Consistency", "Zone mismatch", "FAIL", ...)
Auto-Rename¶
Files with incorrect names are automatically renamed (including all shapefile sidecars: .shp, .dbf, .shx, .prj, etc.) and logged in the Word report's auto-rename table.
Output¶
Terminal (live panel + full log)¶
The rich live panel streams check results in real time while the script runs, showing a section progress bar, running PASS/FAIL/WARN/INFO counters, and a scrolling results log. After the live panel closes, the full results log is reprinted with colour coding.
Word Report¶
A .docx report is saved to the deliverables root folder, named:
MCDR_QC_Report__.docx
It includes:
- Executive summary (total PASS / FAIL / WARN / INFO counts)
- FAIL-only summary table (red text)
- Auto-renamed files log
- GCP elevations table (DSM and DTM values per GCP)
- One detailed section table per QC section, with colour-coded rows
Key Findings¶
- Replaced a manual checklist process — what previously required careful human review of 60–80+ individual items is now validated automatically in seconds
- Catches naming errors, CRS mismatches, resolution violations, and cross-document inconsistencies that were routinely missed in manual review
- The interactive column-approval prompt preserves human judgement for edge cases without stopping the full QC run
- Auto-renaming of incorrectly named files (including all shapefile sidecars) eliminates a common source of rework before submission