Shadow Study
Shadow Analysis
Solar shadow simulation with hour-by-hour sun path, neighbor impact and right-to-light compliance.
@if(session('success'))
{{ session('success') }}
@endif
@if($analyses->count())
@foreach($analyses as $analysis)
{{ \Carbon\Carbon::parse($analysis->analysis_date)->format('M j, Y') }} — {{ $analysis->building_height_m }}m building
Lat {{ number_format($analysis->latitude, 4) }}, Lng {{ number_format($analysis->longitude, 4) }}
{{ ($analysis->right_to_light_compliance ?? false) ? 'Compliant' : 'Non-compliant' }}
{{-- Daylight hours --}}
@if($analysis->daylight_hours)
@php
$dh = $analysis->daylight_hours;
// Use stored exact times; fall back to deriving from hourly entries
if (!empty($dh['sunrise']) && !empty($dh['sunset'])) {
$sunrise = $dh['sunrise'];
$sunset = $dh['sunset'];
} else {
$sunlit = collect($analysis->hourly_shadows ?? [])->filter(fn($s) => ($s['sun_altitude'] ?? 0) > 0);
$sunrise = $sunlit->keys()->first() ?? '—';
$sunset = $sunlit->keys()->last() ?? '—';
}
$totalHrs = $dh['total_hours'] ?? '—';
// Format duration as Xh Ym
if (is_numeric($totalHrs)) {
$hrs = (int)$totalHrs;
$mins = (int)round(($totalHrs - $hrs) * 60);
$durationStr = $hrs . 'h ' . $mins . 'm';
} else {
$durationStr = $totalHrs . 'h';
}
@endphp
Daylight Period
Duration
{{ $durationStr }}
@endif
{{-- Hourly shadows table --}}
@if($analysis->hourly_shadows && is_array($analysis->hourly_shadows))
Hourly Shadow Lengths
@foreach($analysis->hourly_shadows as $timeKey => $hs)
{{ $timeKey }}
{{ number_format($hs['shadow_length'] ?? 0, 1) }}m
{{ isset($hs['shadow_direction']) ? round($hs['shadow_direction']) . '°' : '' }}
@endforeach
@endif
{{-- Max shadow --}}
Max Shadow Length
{{ number_format($analysis->max_shadow_length_m ?? 0, 1) }}m
@endforeach
@else
No Shadow Analysis Yet
Set building height and date to simulate solar shadows.
@endif