import unittest from unittest.mock import patch, MagicMock import os import numpy as np from geodata_pipeline.buildings import export_buildings from geodata_pipeline.config import Config class TestRoofTextures(unittest.TestCase): @patch("geodata_pipeline.buildings.gdal.WarpOptions") @patch("geodata_pipeline.buildings.gdal.Warp") @patch("geodata_pipeline.buildings.gdal.Translate") @patch("geodata_pipeline.buildings.gdal.Open") @patch("geodata_pipeline.buildings._ensure_cityjson_for_tile") @patch("geodata_pipeline.buildings._load_cityjson") @patch("geodata_pipeline.buildings._collect_faces") @patch("geodata_pipeline.buildings._compose_glb") @patch("geodata_pipeline.buildings.ensure_dir") @patch("geodata_pipeline.buildings.os.path.exists") @patch("builtins.open") def test_vrt_roof_texture_extraction(self, mock_open_file, mock_exists, mock_ensure_dir, mock_compose, mock_collect, mock_load_cj, mock_ensure_cj, mock_gdal_open, mock_translate, mock_warp, mock_warp_opts): # Setup mocks mock_exists.return_value = True # Mock manifest: 2km tile (1000, 1000) to (3000, 3000) mock_handle = MagicMock() mock_open_file.return_value.__enter__.return_value = mock_handle mock_handle.__iter__.return_value = [ "tile_id,xmin,ymin,xmax,ymax,global_min,global_max,out_res,tile_key,tile_min,tile_max\n", "tile_2km,1000,1000,3000,3000,0,100,1025,1_1,0,100\n" ] mock_ensure_cj.return_value = "dummy.json" mock_load_cj.return_value = {"CityObjects": {}} mock_collect.return_value = ( [[10.0, 10.0, 5.0]], # vertices [([0, 0, 0], "RoofSurface")] ) cfg = Config.default() cfg.work.ortho_vrt = "work/dop.vrt" cfg.export.ortho_dir = "export/ortho_jpg" cfg.export.manifest_path = "manifest.csv" # Mock GDAL mock_ds = MagicMock() mock_gdal_open.return_value = mock_ds mock_ds.GetGeoTransform.return_value = (0, 1, 0, 5000, 0, -1) mock_ds.RasterXSize = 5000 mock_ds.RasterYSize = 5000 mock_ds.RasterCount = 3 mock_band = MagicMock() mock_ds.GetRasterBand.return_value = mock_band mock_band.ReadAsArray.return_value = np.zeros((10, 10)) # Mock Warp to return a dataset mock_warp.return_value = MagicMock() export_buildings(cfg) # Verify WarpOptions was called with the 2km bounds mock_warp_opts.assert_called() # Find the call that used outputBounds found_correct_bounds = False for call in mock_warp_opts.call_args_list: if call.kwargs.get("outputBounds") == (1000.0, 1000.0, 3000.0, 3000.0): found_correct_bounds = True break self.assertTrue(found_correct_bounds, "WarpOptions not called with expected 2km bounds") if __name__ == "__main__": unittest.main()