feat: improve D-InSAR pairing and distribution
This commit is contained in:
@@ -33,8 +33,17 @@ class RadarDataORM(Base):
|
||||
scene_center_lat = Column(Float, nullable=True)
|
||||
acquisition_time_utc = Column(String, nullable=True)
|
||||
product_type = Column(String, nullable=True)
|
||||
source_product_token = Column(String, nullable=True)
|
||||
image_data_type = Column(String, nullable=True)
|
||||
image_data_format = Column(String, nullable=True)
|
||||
product_variant = Column(String, nullable=True)
|
||||
product_level = Column(String, nullable=True)
|
||||
product_unique_id = Column(String, nullable=True)
|
||||
satellite_family = Column(String, index=True, nullable=True)
|
||||
look_direction = Column(String, index=True, nullable=True)
|
||||
geocoded_flag = Column(Boolean, nullable=True)
|
||||
insar_source_ready = Column(Boolean, nullable=False, default=False, server_default="false")
|
||||
insar_source_reason = Column(Text, nullable=True)
|
||||
file_path = Column(String, unique=True)
|
||||
has_orbit_data = Column(Boolean)
|
||||
orbit_file_path = Column(String, nullable=True)
|
||||
@@ -179,6 +188,7 @@ class DinsarProductProfileORM(Base):
|
||||
orbit_direction = Column(String, index=True, nullable=True)
|
||||
time_baseline_days = Column(Integer, index=True, nullable=True)
|
||||
spatial_baseline_meters = Column(Float, index=True, nullable=True)
|
||||
scene_center_distance_meters = Column(Float, index=True, nullable=True)
|
||||
|
||||
grid_size_m = Column(Float, nullable=True)
|
||||
radar_wavelength = Column(Float, nullable=True)
|
||||
@@ -287,7 +297,7 @@ class PairingCacheStateORM(Base):
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
cache_scope = Column(String(32), unique=True, index=True, nullable=False, default="global")
|
||||
metric_version = Column(String(32), nullable=False, default="2026.04.v1")
|
||||
metric_version = Column(String(32), nullable=False, default="2026.05.raw.v1")
|
||||
status = Column(String(16), index=True, nullable=False, default="DIRTY")
|
||||
scene_count = Column(Integer, nullable=False, default=0)
|
||||
pair_count = Column(Integer, nullable=False, default=0)
|
||||
@@ -338,23 +348,30 @@ class PairingMetricCacheORM(Base):
|
||||
master_scene_uid = Column(String, index=True, nullable=False)
|
||||
slave_scene_uid = Column(String, index=True, nullable=False)
|
||||
pair_uid = Column(String, index=True, nullable=False)
|
||||
metric_version = Column(String(32), index=True, nullable=False, default="2026.04.v1")
|
||||
metric_version = Column(String(32), index=True, nullable=False, default="2026.05.raw.v1")
|
||||
orientation_rule_version = Column(String(32), nullable=False, default="date_then_scene_uid_v1")
|
||||
time_baseline_days = Column(Integer, index=True, nullable=True)
|
||||
spatial_baseline_meters = Column(Float, index=True, nullable=True)
|
||||
scene_center_distance_meters = Column(Float, index=True, nullable=True)
|
||||
scene_overlap_ratio = Column(Float, index=True, nullable=True)
|
||||
orbit_direction = Column(String, index=True, nullable=True)
|
||||
same_satellite = Column(Boolean, nullable=False, default=True)
|
||||
same_satellite_family = Column(Boolean, nullable=False, default=True, server_default="true")
|
||||
same_look_direction = Column(Boolean, nullable=False, default=True, server_default="true")
|
||||
same_imaging_mode = Column(Boolean, nullable=False, default=True)
|
||||
same_polarization = Column(Boolean, nullable=False, default=True)
|
||||
master_imaging_date = Column(String(8), index=True, nullable=True)
|
||||
slave_imaging_date = Column(String(8), index=True, nullable=True)
|
||||
master_satellite = Column(String, index=True, nullable=True)
|
||||
slave_satellite = Column(String, index=True, nullable=True)
|
||||
master_satellite_family = Column(String, index=True, nullable=True)
|
||||
slave_satellite_family = Column(String, index=True, nullable=True)
|
||||
master_imaging_mode = Column(String, nullable=True)
|
||||
slave_imaging_mode = Column(String, nullable=True)
|
||||
master_polarization = Column(String, nullable=True)
|
||||
slave_polarization = Column(String, nullable=True)
|
||||
master_look_direction = Column(String, nullable=True)
|
||||
slave_look_direction = Column(String, nullable=True)
|
||||
master_file_path = Column(String, nullable=True)
|
||||
slave_file_path = Column(String, nullable=True)
|
||||
status = Column(String(16), index=True, nullable=False, default="READY")
|
||||
@@ -927,6 +944,7 @@ class DinsarTaskItemORM(Base):
|
||||
slave_polarization = Column(String, nullable=True)
|
||||
time_baseline_days = Column(Integer, nullable=True)
|
||||
spatial_baseline_meters = Column(Float, nullable=True)
|
||||
scene_center_distance_meters = Column(Float, nullable=True)
|
||||
|
||||
status = Column(String, index=True, nullable=False, default="PENDING")
|
||||
remark = Column(Text, nullable=True)
|
||||
|
||||
@@ -5,7 +5,7 @@ Pydantic Schema 定义。
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, computed_field, field_validator
|
||||
from pydantic import BaseModel, ConfigDict, Field, computed_field, field_validator, model_validator
|
||||
|
||||
from ..config import read_int_env
|
||||
|
||||
@@ -178,8 +178,17 @@ class RadarData(BaseModel):
|
||||
scene_center_lat: Optional[float] = None
|
||||
acquisition_time_utc: Optional[str] = None
|
||||
product_type: Optional[str] = None
|
||||
source_product_token: Optional[str] = None
|
||||
image_data_type: Optional[str] = None
|
||||
image_data_format: Optional[str] = None
|
||||
product_variant: Optional[str] = None
|
||||
product_level: Optional[str] = None
|
||||
product_unique_id: Optional[str] = None
|
||||
satellite_family: Optional[str] = None
|
||||
look_direction: Optional[str] = None
|
||||
geocoded_flag: Optional[bool] = None
|
||||
insar_source_ready: bool = False
|
||||
insar_source_reason: Optional[str] = None
|
||||
file_path: str
|
||||
has_orbit_data: bool
|
||||
orbit_file_path: Optional[str] = None
|
||||
@@ -242,6 +251,9 @@ class PairingRequest(BaseModel):
|
||||
require_same_imaging_mode: bool = True
|
||||
require_same_polarization: bool = True
|
||||
aoi_overlap_threshold: Optional[float] = Field(default=None, ge=0.0, le=1.0)
|
||||
max_temporal_baseline_days: Optional[int] = Field(default=None, ge=1, le=3650)
|
||||
pair_footprint_overlap_min_ratio: Optional[float] = Field(default=None, ge=0.0, le=1.0)
|
||||
footprint_center_distance_max_meters: Optional[int] = Field(default=None, ge=0, le=100000)
|
||||
|
||||
# === 双池日期(新增) ===
|
||||
master_date_from: Optional[str] = Field(default=None, pattern=r'^\d{8}$|^$')
|
||||
@@ -261,6 +273,20 @@ class PairingRequest(BaseModel):
|
||||
# === 向后兼容(保留) ===
|
||||
start_date: Optional[str] = Field(default=None, pattern=r'^\d{8}$|^$')
|
||||
|
||||
@model_validator(mode='before')
|
||||
@classmethod
|
||||
def _apply_aliases(cls, data):
|
||||
if not isinstance(data, dict):
|
||||
return data
|
||||
normalized = dict(data)
|
||||
if normalized.get('max_temporal_baseline_days') not in (None, ''):
|
||||
normalized['time_baseline_max'] = normalized['max_temporal_baseline_days']
|
||||
if normalized.get('pair_footprint_overlap_min_ratio') not in (None, ''):
|
||||
normalized['overlap_threshold'] = normalized['pair_footprint_overlap_min_ratio']
|
||||
if normalized.get('footprint_center_distance_max_meters') not in (None, ''):
|
||||
normalized['spatial_baseline_max_meters'] = normalized['footprint_center_distance_max_meters']
|
||||
return normalized
|
||||
|
||||
@field_validator(
|
||||
'master_date_from',
|
||||
'master_date_to',
|
||||
@@ -336,6 +362,7 @@ class RadarPair(BaseModel):
|
||||
selection_reason: Optional[str] = None
|
||||
time_baseline_days: int
|
||||
spatial_baseline_meters: float
|
||||
scene_center_distance_meters: Optional[float] = None
|
||||
|
||||
|
||||
class PairingResponse(BaseModel):
|
||||
@@ -413,6 +440,7 @@ class TimeseriesStackPlanEdge(BaseModel):
|
||||
slave_imaging_date: Optional[str] = None
|
||||
temporal_baseline_days: Optional[int] = None
|
||||
spatial_baseline_meters: Optional[float] = None
|
||||
scene_center_distance_meters: Optional[float] = None
|
||||
perpendicular_baseline_meters: Optional[float] = None
|
||||
scene_overlap_ratio: Optional[float] = None
|
||||
pair_aoi_overlap_ratio: Optional[float] = None
|
||||
@@ -518,6 +546,7 @@ class DinsarTaskItem(BaseModel):
|
||||
slave_polarization: Optional[str] = None
|
||||
time_baseline_days: Optional[int] = None
|
||||
spatial_baseline_meters: Optional[float] = None
|
||||
scene_center_distance_meters: Optional[float] = None
|
||||
status: str
|
||||
remark: Optional[str] = None
|
||||
created_at: datetime
|
||||
|
||||
Reference in New Issue
Block a user