voxcity.exporter ================ .. py:module:: voxcity.exporter Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/voxcity/exporter/cityles/index /autoapi/voxcity/exporter/envimet/index /autoapi/voxcity/exporter/magicavoxel/index /autoapi/voxcity/exporter/netcdf/index /autoapi/voxcity/exporter/obj/index Classes ------- .. toctree:: :hidden: /autoapi/voxcity/exporter/EnvimetExporter /autoapi/voxcity/exporter/MagicaVoxelExporter /autoapi/voxcity/exporter/OBJExporter /autoapi/voxcity/exporter/CityLesExporter /autoapi/voxcity/exporter/NetCDFExporter /autoapi/voxcity/exporter/Exporter .. autoapisummary:: voxcity.exporter.EnvimetExporter voxcity.exporter.MagicaVoxelExporter voxcity.exporter.OBJExporter voxcity.exporter.CityLesExporter voxcity.exporter.NetCDFExporter voxcity.exporter.Exporter Functions --------- .. autoapisummary:: voxcity.exporter.export_inx voxcity.exporter.generate_edb_file voxcity.exporter.generate_lad_profile voxcity.exporter.export_magicavoxel_vox voxcity.exporter.export_large_voxel_model voxcity.exporter.export_obj voxcity.exporter.grid_to_obj voxcity.exporter.export_netcdf_to_obj voxcity.exporter.convert_colormap_indices voxcity.exporter.mesh_faces voxcity.exporter.create_face_vertices voxcity.exporter.export_cityles voxcity.exporter.voxel_to_xarray_dataset voxcity.exporter.save_voxel_netcdf Package Contents ---------------- .. py:function:: export_inx(city: voxcity.models.VoxCity, output_directory: str, file_basename: str = 'voxcity', land_cover_source: str | None = None, **kwargs) Export model data to ENVI-met INX file format. This is the main function for exporting voxel city data to ENVI-met format. It coordinates the entire export process from grid preparation to file saving. :param city: VoxCity instance to export :type city: VoxCity :param output_directory: Directory to save output :type output_directory: str :param file_basename: Base filename (without extension) :type file_basename: str :param land_cover_source: Optional override for land cover source; defaults to city.extras :type land_cover_source: str | None :param \*\*kwargs: Additional keyword arguments: - envimet_mapping (dict): Custom mapping from land cover class indices (1-based) to ENVI-met IDs. Each value is a dict with optional 'veg' (simple plant ID) and/or 'mat' (soil profile ID) keys. Tree vegetation (key 5 'veg') is ignored. Example: ``{2: {'veg': '0200H1'}, 12: {'mat': '0200AR'}}`` - rooftop_vegetation (bool): If True, keep 1D vegetation (grass, shrubs) on building cells (e.g. green roofs). Default False (remove them). - Other kwargs are passed to create_xml_content(). .. rubric:: Notes - Creates output directory if it doesn't exist - Handles grid preparation and transformation - Generates complete INX file with all required data - Uses standardized file naming convention .. py:function:: generate_edb_file(**kwargs) Generate ENVI-met database file for 3D plants. Creates a plant database file (EDB) containing definitions for trees of different heights with customizable leaf area density profiles. :param \*\*kwargs: Keyword arguments: - lad (float): Leaf area density in m²/m³ (default 1.0) - trunk_height_ratio (float): Ratio of trunk height to total height (default 11.76/19.98) - output_dir (str): Directory to save the EDB file (default: current directory) .. rubric:: Notes - Generates plants for heights from 1-50m - Uses standardized plant IDs in format 'HxxW01' - Includes physical properties like wood density - Sets seasonal variation profiles - Creates complete ENVI-met plant database format .. py:function:: generate_lad_profile(height, trunk_height_ratio, lad='1.00000') Generate leaf area density profile for a plant. Creates a vertical profile of leaf area density (LAD) values for ENVI-met plant definitions, accounting for trunk space and crown distribution. :param height: Total height of plant in meters :type height: int :param trunk_height_ratio: Ratio of trunk height to total height :type trunk_height_ratio: float :param lad: Leaf area density value as string (default '1.00000') :type lad: str :returns: LAD profile data formatted for ENVI-met EDB file :rtype: str .. rubric:: Notes - LAD values start above trunk height - Uses 5-space indentation for ENVI-met format - Profile follows format: "z-level,x,y,LAD" .. py:function:: export_magicavoxel_vox(array, output_dir, base_filename='chunk', voxel_color_map=None) Export a voxel model to MagicaVoxel .vox format. This is the main entry point for voxel model export. It handles: 1. Color map management (using default if none provided) 2. Color index optimization 3. Large model splitting and export 4. Progress reporting :param array: 3D array containing voxel data or a VoxCity instance. When a VoxCity is provided, its voxel classes are exported. :type array: numpy.ndarray | VoxCity :param output_dir: Directory to save the .vox files. Will be created if it doesn't exist. :type output_dir: str :param base_filename: Base name for the output files. Defaults to 'chunk'. Used when model is split into multiple files. :type base_filename: str, optional :param voxel_color_map: Dictionary mapping indices to RGB color values. If None, uses default color map from visualizer. Each value should be a list of [R,G,B] values (0-255). :type voxel_color_map: dict, optional .. note:: - Large models are automatically split into multiple files - Color mapping is optimized and made sequential - Progress information is printed to stdout .. py:function:: export_large_voxel_model(array, color_map, output_prefix, max_size=255, base_filename='chunk') Export a large voxel model by splitting it into multiple .vox files. This function handles models of any size by: 1. Creating the output directory if needed 2. Splitting the model into manageable chunks 3. Saving each chunk as a separate .vox file 4. Maintaining consistent color mapping across all chunks :param array: 3D array containing voxel data. Can be any size, will be split into chunks if needed. :type array: numpy.ndarray :param color_map: Dictionary mapping indices to RGB color values. Each value should be a list of [R,G,B] values (0-255). :type color_map: dict :param output_prefix: Directory to save the .vox files. Will be created if it doesn't exist. :type output_prefix: str :param max_size: Maximum size allowed for each dimension. Defaults to 255 (MagicaVoxel's limit is 256). :type max_size: int, optional :param base_filename: Base name for the output files. Defaults to 'chunk'. Final filenames will be {base_filename}_{i}_{j}_{k}.vox :type base_filename: str, optional :returns: (value_mapping, palette) - value_mapping: dict mapping original indices to MagicaVoxel indices - palette: numpy.ndarray of shape (256,4) containing RGBA values :rtype: tuple .. rubric:: Example >>> array = np.ones((500,500,500)) >>> color_map = {1: [255,0,0]} >>> export_large_voxel_model(array, color_map, "output/model") # Creates files like: output/model/chunk_0_0_0.vox, chunk_0_0_1.vox, etc. .. py:function:: export_obj(array, output_dir, file_name, voxel_size=None, voxel_color_map=None) Export a voxel array to OBJ format with materials and proper face orientations. This function converts a 3D voxel array into a complete OBJ file with materials, performing mesh optimization and ensuring proper face orientations. It generates both OBJ and MTL files with all necessary components for rendering. :param array: 3D numpy array of voxel values or a VoxCity instance. Non-zero values indicate voxel presence and material type. :type array: ndarray | VoxCity :param output_dir: Directory to save the OBJ and MTL files. Will be created if it doesn't exist. :type output_dir: str :param file_name: Base name for the output files. Will be used for both .obj and .mtl files. :type file_name: str :param voxel_size: Size of each voxel in meters. If a VoxCity is provided, this is inferred from the object and this parameter is ignored. :type voxel_size: float | None :param voxel_color_map: Dictionary mapping voxel values to RGB colors. If None, uses default color map. Colors should be RGB lists (0-255). :type voxel_color_map: dict, optional .. rubric:: Notes - Generates optimized mesh using greedy meshing - Creates complete OBJ file with vertices, normals, and faces - Generates MTL file with material definitions - Handles proper face orientation and winding order - Supports color mapping for visualization - Uses consistent coordinate system throughout File Format Details: OBJ file contains: - Vertex coordinates (v) - Normal vectors (vn) - Material references (usemtl) - Face definitions (f) MTL file contains: - Material names and colors - Ambient, diffuse, and specular properties - Transparency settings - Illumination model definitions .. py:function:: grid_to_obj(value_array_ori, dem_array_ori, output_dir, file_name, cell_size, offset, colormap_name='viridis', num_colors=256, alpha=1.0, vmin=None, vmax=None) Converts a 2D array of values and a corresponding DEM array to an OBJ file with specified colormap, transparency, and value range. This function creates a 3D visualization of 2D grid data by using elevation data and color mapping. It's particularly useful for visualizing terrain data, analysis results, or any 2D data that should be displayed with elevation. :param value_array_ori: 2D array of values to visualize. These values will be mapped to colors using the specified colormap. :type value_array_ori: ndarray :param dem_array_ori: 2D array of DEM values corresponding to value_array. Provides elevation data for the 3D visualization. :type dem_array_ori: ndarray :param output_dir: Directory to save the OBJ and MTL files. Will be created if it doesn't exist. :type output_dir: str :param file_name: Base name for the output files. Used for both .obj and .mtl files. :type file_name: str :param cell_size: Size of each cell in the grid (e.g., in meters). Used to scale the model to real-world units. :type cell_size: float :param offset: Elevation offset added after quantization. Useful for adjusting the base height of the model. :type offset: float :param colormap_name: Name of the Matplotlib colormap to use. Defaults to 'viridis'. Must be a valid Matplotlib colormap name. :type colormap_name: str, optional :param num_colors: Number of discrete colors to use from the colormap. Defaults to 256. Higher values give smoother color transitions. :type num_colors: int, optional :param alpha: Transparency value between 0.0 (transparent) and 1.0 (opaque). Defaults to 1.0 (fully opaque). :type alpha: float, optional :param vmin: Minimum value for colormap normalization. If None, uses data minimum. Used to control color mapping range. :type vmin: float, optional :param vmax: Maximum value for colormap normalization. If None, uses data maximum. Used to control color mapping range. :type vmax: float, optional .. rubric:: Notes - Automatically handles NaN values in input arrays - Creates triangulated mesh for proper rendering - Supports transparency and color mapping - Generates complete OBJ and MTL files - Maintains consistent coordinate system - Optimizes mesh generation for large grids :raises ValueError: If vmin equals vmax or if colormap_name is invalid .. py:function:: export_netcdf_to_obj(voxcity_nc, scalar_nc, lonlat_txt, output_dir, vox_base_filename='voxcity_objects', tm_base_filename='tm_isosurfaces', scalar_var='tm', scalar_building_value=-999.99, scalar_building_tol=0.0001, stride_vox=(1, 1, 1), stride_scalar=(1, 1, 1), contour_levels=24, cmap_name='magma', vmin=None, vmax=None, iso_vmin=None, iso_vmax=None, greedy_vox=True, vox_voxel_size=None, scalar_spacing=None, opacity_points=None, max_opacity=0.1, classes_to_show=None, voxel_color_scheme='default', max_faces_warn=1000000, export_vox_base=True) Export two OBJ/MTL files using the same local meter frame: - VoxCity voxels: opaque, per-class color, fixed face winding and normals - Scalar iso-surfaces: colormap colors with variable transparency The two outputs share the same XY origin and axes (X east, Y north, Z up), anchored at the minimum lon/lat of the VoxCity bounding rectangle. :param voxcity_nc: Path to VoxCity NetCDF (must include variable 'voxels' and coords 'x','y','z'). :type voxcity_nc: str :param scalar_nc: Path to scalar NetCDF containing variable specified by scalar_var. :type scalar_nc: str :param lonlat_txt: Text file with columns: i j lon lat (1-based indices) describing the scalar grid georef. :type lonlat_txt: str :param output_dir: Directory to write results. :type output_dir: str :param vox_base_filename: Base filename for VoxCity OBJ/MTL. :type vox_base_filename: str :param tm_base_filename: Base filename for scalar iso-surfaces OBJ/MTL. :type tm_base_filename: str :param scalar_var: Name of scalar variable in scalar_nc. :type scalar_var: str :param scalar_building_value: Value used in scalar field to mark buildings (to be masked). :type scalar_building_value: float :param scalar_building_tol: Tolerance for building masking (isclose). :type scalar_building_tol: float :param stride_vox: Downsampling strides for VoxCity (z,y,x) in voxels. :type stride_vox: tuple[int,int,int] :param stride_scalar: Downsampling strides for scalar (k,j,i). :type stride_scalar: tuple[int,int,int] :param contour_levels: Number of iso-surface levels between vmin and vmax. :type contour_levels: int :param cmap_name: Matplotlib colormap name for iso-surfaces. :type cmap_name: str :param vmin: Minimum scalar value for color mapping and iso range. If None, inferred. :type vmin: float|None :param vmax: Maximum scalar value for color mapping and iso range. If None, inferred. :type vmax: float|None :param iso_vmin: Minimum scalar value to generate iso-surface levels. If None, uses vmin. :type iso_vmin: float|None :param iso_vmax: Maximum scalar value to generate iso-surface levels. If None, uses vmax. :type iso_vmax: float|None :param greedy_vox: If True, use greedy meshing for VoxCity faces to reduce triangles. :type greedy_vox: bool :param vox_voxel_size: If provided, overrides VoxCity voxel spacing for X,Y,Z respectively in meters. A single float applies to all axes. :type vox_voxel_size: float|tuple[float,float,float]|None :param scalar_spacing: If provided, overrides scalar grid spacing (dx,dy,dz) used for iso-surface generation. Values are in meters. :type scalar_spacing: tuple[float,float,float]|None :param opacity_points: Transfer function control points (value, alpha in [0..1]). :type opacity_points: list[tuple[float,float]]|None :param max_opacity: Global max opacity multiplier for iso-surfaces (0..1). :type max_opacity: float :param classes_to_show: Optional subset of voxel classes to export; None -> all present (except 0). :type classes_to_show: set[int]|None :param voxel_color_scheme: Color scheme name passed to get_voxel_color_map. :type voxel_color_scheme: str :param max_faces_warn: Warn if a single class exceeds this many faces. :type max_faces_warn: int :param export_vox_base: If False, skip exporting VoxCity OBJ/MTL; VoxCity input is still used to define the shared coordinate system for scalar OBJ. :type export_vox_base: bool :returns: Paths of written files: keys 'vox_obj','vox_mtl','tm_obj','tm_mtl' (values may be None). :rtype: dict .. py:function:: convert_colormap_indices(original_map) Convert a color map with arbitrary indices to sequential indices starting from 0. This function takes a color map with arbitrary integer keys and creates a new map with sequential indices starting from 0, maintaining the original color values. This is useful for ensuring consistent material indexing in OBJ files. :param original_map: Dictionary with integer keys and RGB color value lists. Each value should be a list of 3 integers (0-255) representing RGB colors. :type original_map: dict :returns: New color map with sequential indices starting from 0. The values maintain their original RGB color assignments. :rtype: dict .. rubric:: Example >>> original = {5: [255, 0, 0], 10: [0, 255, 0], 15: [0, 0, 255]} >>> new_map = convert_colormap_indices(original) >>> _logger.info(new_map) {0: [255, 0, 0], 1: [0, 255, 0], 2: [0, 0, 255]} .. py:function:: mesh_faces(mask, layer_index, axis, positive_direction, normal_idx, voxel_size_m, vertex_dict, vertex_list, faces_per_material, voxel_value_to_material) Performs greedy meshing on a 2D mask layer and adds optimized faces to the mesh. This function implements a greedy meshing algorithm to combine adjacent voxels into larger faces, reducing the total number of faces in the final mesh while maintaining visual accuracy. It processes each layer of voxels and generates optimized faces with proper materials and orientations. :param mask: 2D boolean array indicating voxel presence. Non-zero values indicate voxel presence, zero indicates empty space. :type mask: ndarray :param layer_index: Index of current layer being processed. Used to position faces in 3D space. :type layer_index: int :param axis: Axis perpendicular to faces being generated ('x', 'y', or 'z'). Determines how coordinates are generated for the faces. :type axis: str :param positive_direction: Whether faces point in positive axis direction. Affects face normal orientation. :type positive_direction: bool :param normal_idx: Index of normal vector to use for faces. References pre-defined normal vectors in the OBJ file. :type normal_idx: int :param voxel_size_m: Size of each voxel in meters. Used to scale coordinates to real-world units. :type voxel_size_m: float :param vertex_dict: Dictionary mapping vertex coordinates to indices. Used to avoid duplicate vertices in the mesh. :type vertex_dict: dict :param vertex_list: List of unique vertex coordinates. Stores all vertices used in the mesh. :type vertex_list: list :param faces_per_material: Dictionary collecting faces by material. Keys are material names, values are lists of face definitions. :type faces_per_material: dict :param voxel_value_to_material: Mapping from voxel values to material names. Used to assign materials to faces based on voxel values. :type voxel_value_to_material: dict .. rubric:: Notes - Uses greedy meshing to combine adjacent same-value voxels - Handles coordinate system conversion for proper orientation - Maintains consistent face winding order for rendering - Optimizes mesh by reusing vertices and combining faces - Supports different coordinate systems for each axis .. py:function:: create_face_vertices(coords, positive_direction, axis) Helper function to create properly oriented face vertices for OBJ export. This function handles the creation of face vertices with correct winding order based on the face direction and axis. It accounts for OpenGL coordinate system conventions and ensures proper face orientation for rendering. :param coords: List of 4 vertex coordinates defining the face corners. Each coordinate should be a tuple of (x, y, z) values. :type coords: list :param positive_direction: Whether face points in positive axis direction. True = face normal points in positive direction along the axis False = face normal points in negative direction along the axis :type positive_direction: bool :param axis: Axis the face is perpendicular to ('x', 'y', or 'z'). This determines how vertices are ordered for proper face orientation. :type axis: str :returns: Ordered vertex coordinates for the face, arranged to create proper face orientation and winding order for rendering. :rtype: list .. rubric:: Notes - Y-axis faces need special handling due to OpenGL coordinate system - Winding order determines which side of the face is visible - Consistent winding order is maintained for X and Z faces .. py:function:: export_cityles(city: voxcity.models.VoxCity, output_directory: str = 'output/cityles', building_material: str = 'default', tree_type: str = 'default', trunk_height_ratio: float = _TRUNK_RATIO_SENTINEL, canopy_bottom_height_grid=None, under_tree_class_name: str = 'Bareland', under_tree_cityles_code=None, land_cover_source: str | None = None, **kwargs) Export VoxCity data to CityLES format Parameters: ----------- city : VoxCity A VoxCity model instance. output_directory : str Output directory path. building_material : str Building material type for mapping. tree_type : str Tree type for mapping. trunk_height_ratio : float, optional Ratio of trunk height to total canopy height. When explicitly provided, the canopy bottom height grid is *always* recomputed as ``canopy_top * trunk_height_ratio``, even when the VoxCity object already contains a per-cell canopy bottom grid. When omitted the existing ``city.tree_canopy.bottom`` is used if available, otherwise a default ratio of 0.3 is applied. canopy_bottom_height_grid : numpy.ndarray, optional Explicit canopy bottom height grid. Ignored when *trunk_height_ratio* is explicitly provided. under_tree_class_name : str Ground land-cover class to assign under tree canopy. under_tree_cityles_code : int, optional Override CityLES code for under-tree class. land_cover_source : str, optional Source of land cover data. Auto-detected from VoxCity extras when omitted. **kwargs : dict Additional parameters (for compatibility). Returns: -------- str : Path to output directory .. py:function:: voxel_to_xarray_dataset(voxcity_grid: numpy.ndarray, voxel_size_m: float, rectangle_vertices: Optional[Sequence[Tuple[float, float]]] = None, extra_attrs: Optional[Mapping[str, Any]] = None) -> xarray.Dataset Create an xarray Dataset from a VoxCity voxel grid. :param voxcity_grid: 3D numpy array with shape (rows, cols, levels) as returned by `get_voxcity` (first element of the returned tuple). :param voxel_size_m: Voxel size (mesh size) in meters. :param rectangle_vertices: Optional polygon vertices defining the area of interest in longitude/latitude pairs, typically the same list passed to `get_voxcity`. :param extra_attrs: Optional mapping of additional global attributes to store in the dataset. :returns: Dataset containing one DataArray named "voxels" with dims (y, x, z) and coordinate variables in meters from origin. :rtype: xr.Dataset .. py:function:: save_voxel_netcdf(voxcity_grid: numpy.ndarray, output_path: str | pathlib.Path, voxel_size_m: float, rectangle_vertices: Optional[Sequence[Tuple[float, float]]] = None, extra_attrs: Optional[Mapping[str, Any]] = None, engine: Optional[str] = None) -> str Save a VoxCity voxel grid to a NetCDF file. :param voxcity_grid: 3D numpy array (rows, cols, levels) of voxel values. :param output_path: Path to the NetCDF file to be written. Parent directories will be created as needed. :param voxel_size_m: Voxel size in meters. :param rectangle_vertices: Optional list of (lon, lat) pairs defining the area of interest. Stored as dataset metadata only. :param extra_attrs: Optional additional global attributes to embed in the dataset. :param engine: Optional xarray engine, e.g., "netcdf4" or "h5netcdf". If not provided, xarray will choose a default; on failure we retry alternate engines. :returns: The string path to the written NetCDF file. :rtype: str