feat: add map-driven orthophoto analysis
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-15 02:01:03 +02:00
parent 845c4696e7
commit daccd3869a
29 changed files with 1300 additions and 26 deletions
+86
View File
@@ -410,6 +410,92 @@ class DatasetService:
return DatasetService._to_response(dataset)
@staticmethod
def import_raster_bytes(
db: Session,
*,
project_id: UUID,
filename: str,
content: bytes,
source: str,
source_name: str,
source_metadata: dict[str, Any],
provenance_metadata: dict[str, Any],
area_id: UUID | None = None,
source_version: str | None = None,
content_type: str = "image/tiff",
) -> DatasetCreateResponse:
if not db.get(Project, project_id):
raise AppError(code="PROJECT_NOT_FOUND", message="Project not found", status_code=404)
if area_id is not None:
area = db.get(Area, area_id)
if not area:
raise AppError(code="AREA_NOT_FOUND", message="Area not found", status_code=404)
if area.project_id != project_id:
raise AppError(code="INVALID_DATASET_SCOPE", message="Area does not belong to this project", status_code=400)
if not content:
raise AppError(code="INVALID_UPLOAD", message="Raster artifact is empty", status_code=400)
safe_filename = DatasetService._validate_upload_filename(filename)
if DatasetService._extension_for_path(safe_filename) not in DatasetService.RASTER_EXTENSIONS:
raise AppError(code="INVALID_UPLOAD", message="Raster artifacts require a GeoTIFF filename", status_code=415)
dataset_id = uuid.uuid4()
storage_info = StorageService.persist_dataset_file(
project_id=str(project_id),
dataset_id=str(dataset_id),
dataset_type="raster",
original_filename=safe_filename,
content=content,
content_type=content_type,
)
try:
metadata = extract_raster_metadata(storage_info["storage_path"])
dataset = Dataset(
id=dataset_id,
project_id=project_id,
area_id=area_id,
name=safe_filename,
dataset_type="raster",
source=source,
dataset_role="source",
source_name=source_name,
source_metadata=source_metadata,
provenance_metadata=provenance_metadata,
imported_at=datetime.now(timezone.utc),
source_version=source_version,
storage_path=storage_info["storage_path"],
original_filename=storage_info["original_filename"],
stored_filename=storage_info["stored_filename"],
content_type=storage_info["content_type"],
size_bytes=storage_info["size_bytes"],
checksum_sha256=storage_info["checksum_sha256"],
crs=metadata.get("crs"),
bounds_json=DatasetService._extract_raster_bounds_json(metadata),
resolution_json=DatasetService._extract_raster_resolution_json(metadata),
bands_json=DatasetService._extract_raster_bands_json(metadata),
metadata_json=metadata,
status="ready",
)
db.add(dataset)
db.add(
DatasetVersion(
dataset_id=dataset.id,
version=1,
storage_path=dataset.storage_path,
source_version=dataset.source_version,
checksum_sha256=dataset.checksum_sha256,
source_metadata=dataset.source_metadata,
provenance_metadata=dataset.provenance_metadata,
)
)
db.commit()
db.refresh(dataset)
return DatasetService._to_response(dataset)
except Exception:
db.rollback()
StorageService.remove_dataset_file(storage_info["storage_path"])
raise
@staticmethod
def import_partitioned_vector_artifact(
db: Session,