- HDF5 format v3 (
voxcity_results.v3) is required by the loader. Files written by VoxCity 1.x no longer load; convert them once withvoxcity.io.migrate_h5(src, dst)orpython -m voxcity.migrate FILE .... v3 files are self-describing: root/group/datasetaxesattributes,rotation_angle(derived from geometry at save time), and a structuredrectangle_verticesdataset. - Saving now errors if
extras['rotation_angle']disagrees with the angle derived fromrectangle_verticesby more than 0.1 degrees.
voxcity.direction_to_axis_vector(azimuth_deg, elevation_deg, rotation_angle_deg)— the single public azimuth-to-axis-vector mapping (compass azimuth, component 0 = north). Broadcasts over arrays.voxcity.check_axes(file_or_attrs)— assert a file declares thenorth,east,upcontract.voxcity.GridProjector.from_city(city)/.from_h5(path)— lon/lat <-> cell without hand-assembling aGridGeom.VoxCity.to_xarray()— zero-copy named-dimension view (dims("north", "east", "up"), cell-centre metre coordinates).python -m voxcity.migrate— batch converter with provenance attrs (migrated_from,geometry_source).- Empirical orientation guard test (NE-corner building -> high-i/high-j),
the permanent version of the check that caught the
voxcity_vwindaxis-swap incident.
- Solar simulators (
radiation.py,sky.py,common/geometry.py) build direction vectors viadirection_to_axis_vector. Outputs are bit-identical, except the SVF ray fan may differ by <=1 ulp (azimuth generation moved from radians to degrees).