=== versions === python 3.12.0 | pvlib 0.16.1 | rasterio 1.5.2 | duckdb 2.0.0 | geopandas 1.2.0 | numpy 2.5.4 | pandas 3.0.6 | scipy 1.18.1 === Step 1: Environment Agency 1 m LiDAR DSM and DTM === grid 2000 x 2000 cells of 1 m | no data: DSM 0.00%, DTM 0.00% DTM 37.5..61.8 m | DSM 37.5..82.7 m | cells over 2.5 m above ground: 31.4% === Step 2: Overture Maps building footprints with DuckDB === AOI centre 53.4435 N, 2.1927 W | query bbox -2.2012, 53.4389, -2.1842, 53.4481 Overture release 2026-10-21.0: 3,274 buildings in the query box buildings with a centroid in the AOI: 2,148 | sources: OpenStreetMap 1,903, Microsoft ML Buildings 245 footprint area: median 56 m2, total 18.8 ha (24% of the AOI) footprint cells over 2.5 m in the nDSM: 92.7% | roof cells after a 1-cell inward buffer: 133,662 === Step 3: roof slope and aspect (Horn's method) === roof cells: flat (<10 deg) 16.3% | pitched 10-60 deg 74.7% | steeper 9.0% pitched roof slope: median 26 deg, interquartile 19-34 deg pitched roof cells by the way they face: N 18%, NE 10%, E 16%, SE 9%, S 17%, SW 9%, W 14%, NW 8% === Step 4: horizon angles in 72 directions by ray marching over the DSM === 72 directions x 104 steps (2-300 m) for 133,662 roof cells in 8.0 s relative sky view: median 1.00, 10th percentile 0.95 === Step 5: PVGIS typical meteorological year and a sun map === TMY 8,760 hours | annual GHI 918 kWh/m2, DNI 740, DHI 572 | diffuse share of GHI 62% 2,933 sunlit hours grouped into 463 sky cells (5 deg azimuth x 2 deg elevation) | beam on a horizontal plane 347 kWh/m2 === Step 6: check on an unshaded 35 deg south-facing plane === sun-map model (this script) : 1026 kWh/m2/yr (beam 489, diffuse 520, reflected 17) pvlib hourly, isotropic sky : 1026 kWh/m2/yr pvlib hourly, Perez sky : 1089 kWh/m2/yr PVGIS SARAH 2014-2023 mean : 1109 kWh/m2/yr pvlib Ineichen clear sky (no cloud): 1929 kWh/m2/yr specific yield: ours 820 kWh/kWp (PR 0.8) | PVGIS PV model, 14% system loss 882 kWh/kWp === Step 7: annual irradiation on every roof cell, with shading === 463 sky cells x 133,662 roof cells in 0.2 s annual irradiation on roof cells: median 871 kWh/m2, 90th percentile 994, max 1026 beam lost to shading from neighbours, trees and chimneys: 2.8% of the unshaded beam median kWh/m2/yr on pitched roofs by aspect: N 711, NE 759, E 851, SE 962, S 1000, SW 943, W 870, NW 738 | flat roofs 908 === Step 8: kWh per year per building === assumptions: efficiency 20%, performance ratio 0.8, coverage 70%, usable if slope <= 60 deg and >= 800 kWh/m2/yr usable share of roof area: 57% AOI total: 13.8 MWp, 10.1 GWh/yr = 3,748 typical households (2,700 kWh each) house-sized footprints (30-120 m2): 1,774 | median 3.9 kWp, 2,922 kWh/yr | 58% could cover 2,700 kWh/yr | 1% have no usable roof top 10 roofs by annual output: rank id type footprint_m2 usable_m2 kwp kwh_yr kwh_kwp mean_irr 1 37d7b994 school 2763 1779 249.0 179598 721 902 2 0ca0beb5 school 2798 1621 226.9 164641 726 907 3 06f69560 - 1978 1537 215.2 154820 719 899 4 58398829 - 1402 1081 151.4 111407 736 920 5 923b7ea9 commercial 1347 978 137.0 100910 737 921 6 080a529b religious 1479 871 121.9 86348 708 885 7 e21169e8 retail 1234 752 105.3 76383 725 907 8 9bc185f7 school 806 673 94.2 68492 727 909 9 917b5410 medical 782 590 82.5 59317 719 898 10 fef13b60 civic 853 560 78.4 56135 716 895 wrote output\roof_ranking.csv (2,148 buildings) === figures === 2026-12-21 12:10 UTC: sun elevation 13.2 deg, azimuth 181 deg, 49% of the zoom window in shadow 2026-03-20 12:10 UTC: sun elevation 36.5 deg, azimuth 178 deg, 18% of the zoom window in shadow 2026-06-21 12:10 UTC: sun elevation 60.0 deg, azimuth 180 deg, 6% of the zoom window in shadow best unshaded orientation on the grid: slope 30 deg, aspect 180 deg, 1024 kWh/m2/yr | flat 919 | vertical south wall 746 figures written to C:\Users\Sean.Blaney\source\tgis-b5-3\tutorial-code\rooftop-solar-potential-lidar-python\output