""" Venus (GJ0c) terrain builder. Data source: - Elevation: Magellan radar altimetry from USGS Astrogeology Global topography at ~4.6 km/px, PDS format. Venus properties: - Surface: volcanic, extremely hot (~735K), dense CO2 atmosphere - No liquid water, thick clouds - Min elevation: ~-2000 m (lowlands) - Max elevation: ~11000 m (Maxwell Montes on Ishtar Terra) - planet_class: "volcanic", atmosphere: "toxic" """ import numpy as np from pathlib import Path from sol_data.download import ensure_cached from sol_data.shared import ( GRID_W, GRID_H, load_tiff_as_array, load_raw_binary, resample_to_grid, normalize_01, compute_hillshade, assemble_terrain, temperature_grid_analytical, ) # Magellan topography — USGS GeoTIFF (reliable, PIL-loadable) MAGELLAN_TIFF_URL = "https://planetarymaps.usgs.gov/mosaic/Venus_Magellan_Topography_Global_4641m_v02.tif" MAGELLAN_TIFF_FILE = "Venus_Magellan_Topography_Global_4641m_v02.tif" # PDS fallback (raw binary, dimensions may vary) MAGELLAN_PDS_URL = "https://pds-geosciences.wustl.edu/mgn/mgn-v-rdrs-5-dim-v1/mg_3002/gedr/gtdr/gtdr_shtplt.img" MAGELLAN_PDS_FILE = "venus_magellan_gtdr.img" VENUS_MIN_ELEV_M = -2000.0 VENUS_MAX_ELEV_M = 11000.0 VENUS_SURFACE_TEMP_K = 735.0 # nearly uniform due to dense atmosphere def _load_magellan() -> np.ndarray: """Load Magellan topography data.""" # Try USGS GeoTIFF first (reliable, well-defined format) try: path = ensure_cached(MAGELLAN_TIFF_URL, MAGELLAN_TIFF_FILE) print(f" loading Magellan GeoTIFF: {path}") arr = load_tiff_as_array(str(path)) # Handle nodata arr[arr < -20000] = 0.0 arr[arr > 20000] = 0.0 print(f" Magellan shape: {arr.shape}, " f"range: [{arr.min():.0f}, {arr.max():.0f}] m") return arr except Exception as e: print(f" GeoTIFF failed ({e}), trying PDS binary...") # PDS fallback — try common dimension/format combinations try: path = ensure_cached(MAGELLAN_PDS_URL, MAGELLAN_PDS_FILE) print(f" loading Magellan PDS: {path}") for w, h in [(4096, 2048), (2048, 1024), (8192, 4096)]: try: arr = load_raw_binary(str(path), w, h, dtype=">i2", offset=0) arr[arr > 20000] = 0.0 arr[arr < -20000] = 0.0 print(f" Magellan PDS: {w}x{h}, range: [{arr.min():.0f}, {arr.max():.0f}]") return arr except ValueError: continue except Exception as e3: print(f" PDS also failed ({e3})") # All sources failed — fall through to procedural generation print(" WARNING: all Magellan sources failed, using procedural") return None def build_terrain(body_def: dict) -> dict: """Build Venus terrain dict from Magellan data.""" import sys sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from planet_simulation import compute_biome print(" Venus: loading Magellan data...") # ── 1. Elevation ──────────────────────────────────────────────────── raw = _load_magellan() if raw is None: # Fall back to procedural simulation import sys sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from planet_simulation import simulate return simulate(body_def) from sol_data.shared import greenwich_to_dateline shifted = greenwich_to_dateline(raw) elevation_m = resample_to_grid(shifted, GRID_H, GRID_W, order=1) elevation = normalize_01(elevation_m, VENUS_MIN_ELEV_M, VENUS_MAX_ELEV_M) sea_level = 0.0 surface_water = np.zeros((GRID_H, GRID_W), dtype=bool) # ── 2. Temperature ────────────────────────────────────────────────── # Venus has nearly uniform surface temperature due to dense atmosphere temperature_K = temperature_grid_analytical( base_T_K=VENUS_SURFACE_TEMP_K, elevation=elevation, lapse_rate_K_per_unit=50.0, # slight cooling at altitude lat_gradient_K=5.0, # almost no lat variation (thick atmo) ) # ── 3. Moisture ───────────────────────────────────────────────────── moisture = np.zeros((GRID_H, GRID_W), dtype=np.float32) # ── 4. Biome ──────────────────────────────────────────────────────── biome = compute_biome(body_def, elevation, sea_level, surface_water, temperature_K, moisture) # ── 5. Hillshade ──────────────────────────────────────────────────── hillshade = compute_hillshade(elevation) return assemble_terrain( elevation=elevation, temperature_K=temperature_K, moisture=moisture, biome=biome, surface_water=surface_water, hillshade=hillshade, rivers=[], sea_level=sea_level, )