from __future__ import annotations from .evidence import make_evidence from .models import EvidenceItem def summarize_sun_wind(lat: float, lon: float, wind_direction_deg: float | None = None) -> tuple[dict[str, str], list[EvidenceItem]]: hemisphere = "northern" if lat >= 0 else "southern" sun_side = "southern" if lat >= 0 else "northern" wind_text = _wind_text(wind_direction_deg) summary = { "hemisphere": hemisphere, "sun_side": sun_side, "orientation_note": ( f"At this latitude in the {hemisphere} hemisphere, the sun is generally biased toward the {sun_side} side of the sky across much of the year." ), "east_west_note": "Morning exposure is generally from the east; afternoon heat/glare risk is generally stronger from the west.", "wind_note": wind_text, "limitation": "This is a deterministic orientation summary and does not model shadows from surrounding buildings or terrain.", } evidence = [ make_evidence( category="Sun/wind", finding="A deterministic sun/orientation summary was computed from latitude and longitude.", source_name="Local solar/orientation calculation", source_url="", source_type="computed", resolution_or_scope="anchor coordinate", confidence="medium", limitation="Does not model site obstructions, surrounding-building shadows, or microclimate.", design_implication="Use for early massing, shading, and facade-orientation thinking.", verification_needed="Observe actual shade, adjacent heights, glare, and wind during site visit.", output_label="computed", ) ] return summary, evidence def _wind_text(direction: float | None) -> str: if direction is None: return "Wind direction was not available from climate data." return f"Available climate data suggests dominant wind around {round(direction)} degrees ({_bearing_label(direction)}). Treat this as regional/modelled." def _bearing_label(deg: float) -> str: labels = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"] return labels[int((deg + 22.5) // 45) % 8]