feat: improve D-InSAR pairing and distribution

This commit is contained in:
2026-05-09 14:59:20 +08:00
parent 69d15bffcb
commit 5c73e2c1c2
28 changed files with 1480 additions and 86 deletions
@@ -0,0 +1,185 @@
-- Migration: Raw source pairing readiness and center-distance metrics
-- Version: 9.0
-- Date: 2026-05-09
-- Purpose: Pair D-InSAR candidates from raw complex source products without requiring prebuilt SLC/envi_import folders.
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS satellite_family VARCHAR NULL;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS source_product_token VARCHAR NULL;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS image_data_type VARCHAR NULL;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS image_data_format VARCHAR NULL;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS product_variant VARCHAR NULL;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS look_direction VARCHAR NULL;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS geocoded_flag BOOLEAN NULL;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS insar_source_ready BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE IF EXISTS radar_data
ADD COLUMN IF NOT EXISTS insar_source_reason TEXT NULL;
ALTER TABLE IF EXISTS pairing_metric_cache
ADD COLUMN IF NOT EXISTS scene_center_distance_meters DOUBLE PRECISION NULL;
ALTER TABLE IF EXISTS pairing_metric_cache
ADD COLUMN IF NOT EXISTS same_satellite_family BOOLEAN NOT NULL DEFAULT TRUE;
ALTER TABLE IF EXISTS pairing_metric_cache
ADD COLUMN IF NOT EXISTS same_look_direction BOOLEAN NOT NULL DEFAULT TRUE;
ALTER TABLE IF EXISTS pairing_metric_cache
ADD COLUMN IF NOT EXISTS master_satellite_family VARCHAR NULL;
ALTER TABLE IF EXISTS pairing_metric_cache
ADD COLUMN IF NOT EXISTS slave_satellite_family VARCHAR NULL;
ALTER TABLE IF EXISTS pairing_metric_cache
ADD COLUMN IF NOT EXISTS master_look_direction VARCHAR NULL;
ALTER TABLE IF EXISTS pairing_metric_cache
ADD COLUMN IF NOT EXISTS slave_look_direction VARCHAR NULL;
ALTER TABLE IF EXISTS dinsar_task_items
ADD COLUMN IF NOT EXISTS scene_center_distance_meters DOUBLE PRECISION NULL;
ALTER TABLE IF EXISTS dinsar_product_profiles
ADD COLUMN IF NOT EXISTS scene_center_distance_meters DOUBLE PRECISION NULL;
CREATE INDEX IF NOT EXISTS idx_radar_data_satellite_family
ON radar_data (satellite_family);
CREATE INDEX IF NOT EXISTS idx_radar_data_look_direction
ON radar_data (look_direction);
CREATE INDEX IF NOT EXISTS idx_radar_data_insar_source_ready
ON radar_data (insar_source_ready);
CREATE INDEX IF NOT EXISTS idx_pairing_metric_cache_center_distance
ON pairing_metric_cache (scene_center_distance_meters);
CREATE INDEX IF NOT EXISTS idx_pairing_metric_cache_same_family
ON pairing_metric_cache (same_satellite_family);
UPDATE radar_data
SET
satellite_family = COALESCE(
NULLIF(satellite_family, ''),
CASE
WHEN upper(replace(replace(replace(COALESCE(satellite, ''), '-', ''), '_', ''), ' ', '')) IN
('LT1', 'LT1A', 'LT1B', 'LUTAN1', 'LUTAN1A', 'LUTAN1B')
THEN 'LT1'
WHEN upper(replace(replace(replace(COALESCE(satellite, ''), '-', ''), '_', ''), ' ', '')) IN
('S1', 'S1A', 'S1B', 'SENTINEL1', 'SENTINEL1A', 'SENTINEL1B')
THEN 'S1'
WHEN NULLIF(satellite, '') IS NOT NULL
THEN upper(satellite)
ELSE NULL
END
),
source_product_token = COALESCE(
NULLIF(source_product_token, ''),
CASE
WHEN split_part(regexp_replace(COALESCE(file_path, ''), '^.*[\\/]', ''), '_', 1) LIKE 'LT1%%'
THEN NULLIF(split_part(regexp_replace(COALESCE(file_path, ''), '^.*[\\/]', ''), '_', 9), '')
WHEN split_part(regexp_replace(COALESCE(file_path, ''), '^.*[\\/]', ''), '_', 1) LIKE 'S1%%'
THEN NULLIF(split_part(regexp_replace(COALESCE(file_path, ''), '^.*[\\/]', ''), '_', 3), '')
ELSE NULL
END
),
image_data_type = COALESCE(NULLIF(image_data_type, ''), NULLIF(product_type, ''))
WHERE satellite_family IS NULL
OR satellite_family = ''
OR source_product_token IS NULL
OR source_product_token = ''
OR image_data_type IS NULL
OR image_data_type = '';
UPDATE radar_data
SET
insar_source_ready = (
geom IS NOT NULL
AND imaging_date ~ '^[0-9]{8}$'
AND NULLIF(orbit_direction, '') IS NOT NULL
AND NULLIF(imaging_mode, '') IS NOT NULL
AND NULLIF(polarization, '') IS NOT NULL
AND NULLIF(satellite_family, '') IS NOT NULL
AND geocoded_flag IS DISTINCT FROM TRUE
AND (
upper(COALESCE(NULLIF(image_data_type, ''), NULLIF(product_type, ''), '')) = 'COMPLEX'
OR upper(COALESCE(NULLIF(source_product_token, ''), '')) IN ('SLC', 'SSC')
OR upper(COALESCE(NULLIF(product_variant, ''), '')) IN ('SLC', 'SSC')
)
),
insar_source_reason = CASE
WHEN (
geom IS NOT NULL
AND imaging_date ~ '^[0-9]{8}$'
AND NULLIF(orbit_direction, '') IS NOT NULL
AND NULLIF(imaging_mode, '') IS NOT NULL
AND NULLIF(polarization, '') IS NOT NULL
AND NULLIF(satellite_family, '') IS NOT NULL
AND geocoded_flag IS DISTINCT FROM TRUE
AND (
upper(COALESCE(NULLIF(image_data_type, ''), NULLIF(product_type, ''), '')) = 'COMPLEX'
OR upper(COALESCE(NULLIF(source_product_token, ''), '')) IN ('SLC', 'SSC')
OR upper(COALESCE(NULLIF(product_variant, ''), '')) IN ('SLC', 'SSC')
)
)
THEN NULL
ELSE concat_ws(
';',
CASE WHEN geom IS NULL THEN 'missing_footprint' END,
CASE WHEN imaging_date IS NULL OR imaging_date !~ '^[0-9]{8}$' THEN 'missing_date' END,
CASE WHEN NULLIF(orbit_direction, '') IS NULL THEN 'missing_orbit_direction' END,
CASE WHEN NULLIF(imaging_mode, '') IS NULL THEN 'missing_imaging_mode' END,
CASE WHEN NULLIF(polarization, '') IS NULL THEN 'missing_polarization' END,
CASE WHEN NULLIF(satellite_family, '') IS NULL THEN 'missing_satellite_family' END,
CASE WHEN geocoded_flag IS TRUE THEN 'geocoded_product' END,
CASE WHEN NOT (
upper(COALESCE(NULLIF(image_data_type, ''), NULLIF(product_type, ''), '')) = 'COMPLEX'
OR upper(COALESCE(NULLIF(source_product_token, ''), '')) IN ('SLC', 'SSC')
OR upper(COALESCE(NULLIF(product_variant, ''), '')) IN ('SLC', 'SSC')
) THEN 'not_complex_source' END
)
END;
UPDATE pairing_metric_cache pmc
SET
scene_center_distance_meters = COALESCE(pmc.scene_center_distance_meters, pmc.spatial_baseline_meters),
master_satellite_family = COALESCE(pmc.master_satellite_family, m.satellite_family),
slave_satellite_family = COALESCE(pmc.slave_satellite_family, s.satellite_family),
master_look_direction = COALESCE(pmc.master_look_direction, m.look_direction),
slave_look_direction = COALESCE(pmc.slave_look_direction, s.look_direction),
same_satellite_family = (
NULLIF(COALESCE(m.satellite_family, m.satellite), '') IS NOT NULL
AND NULLIF(COALESCE(s.satellite_family, s.satellite), '') IS NOT NULL
AND COALESCE(m.satellite_family, m.satellite) = COALESCE(s.satellite_family, s.satellite)
),
same_look_direction = (
NULLIF(m.look_direction, '') IS NULL
OR NULLIF(s.look_direction, '') IS NULL
OR m.look_direction = s.look_direction
)
FROM radar_data m, radar_data s
WHERE pmc.master_scene_ref_id = m.id
AND pmc.slave_scene_ref_id = s.id;
UPDATE pairing_cache_state
SET
metric_version = '2026.05.raw.v1',
status = CASE WHEN status = 'REBUILDING' THEN status ELSE 'DIRTY' END,
last_error = NULL,
updated_at = NOW()
WHERE metric_version IS DISTINCT FROM '2026.05.raw.v1';