Fixed the issue where 2km building tiles had incorrect roof textures because they relied on 1km texture files. Now, textures are dynamically extracted from the global Ortho VRT using the exact building tile bounds, ensuring perfect alignment and full coverage.
72 lines
2.9 KiB
Python
72 lines
2.9 KiB
Python
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()
|